<?php

namespace App\Http\Controllers\Coach;

use App\Http\Controllers\Controller;
use App\Models\CoachPaymentMethod;
use App\Notifications\PaymentMethodVerification;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Validation\Rule;
use Inertia\Inertia;
use Inertia\Response;

class PaymentMethodController extends Controller
{
    /**
     * Display a listing of payment methods.
     */
    public function index(Request $request): Response
    {
        $user = $request->user();

        $paymentMethods = $user->paymentMethods()
            ->ordered()
            ->get()
            ->map(fn($method) => array_merge($method->toArray(), [
                'display_name' => $method->display_name,
                'type_label' => $method->type_label,
                'masked_account' => $method->masked_account_number,
                'bank_logo_url' => $method->bank_logo ? asset('storage/' . $method->bank_logo) : null,
            ]));

        return Inertia::render('Coach/PaymentMethods/Index', [
            'paymentMethods' => $paymentMethods,
            'dominicanBanks' => CoachPaymentMethod::getDominicanBankNames(),
            'dominicanBanksData' => CoachPaymentMethod::DOMINICAN_BANKS,
            'accountTypes' => CoachPaymentMethod::ACCOUNT_TYPES,
            'documentTypes' => CoachPaymentMethod::DOCUMENT_TYPES,
        ]);
    }

    /**
     * Store a new PayPal payment method.
     */
    public function storePaypal(Request $request): JsonResponse|RedirectResponse
    {
        $validated = $request->validate([
            'paypal_mode' => 'required|in:email,paypalme,api',
            'paypal_email' => 'required_if:paypal_mode,email|nullable|email|max:255',
            'paypal_me_link' => 'required_if:paypal_mode,paypalme|nullable|string|max:255',
            'paypal_client_id' => 'required_if:paypal_mode,api|nullable|string|max:255',
            'paypal_secret' => 'required_if:paypal_mode,api|nullable|string|max:255',
            'paypal_sandbox' => 'boolean',
            'name' => 'nullable|string|max:100',
        ]);

        $user = $request->user();

        // Check if already has PayPal
        $existingPaypal = $user->paymentMethods()
            ->ofType(CoachPaymentMethod::TYPE_PAYPAL)
            ->first();

        $data = [
            'paypal_email' => $validated['paypal_email'] ?? null,
            'paypal_me_link' => $validated['paypal_me_link'] ?? null,
            'paypal_client_id' => $validated['paypal_client_id'] ?? null,
            'paypal_secret' => $validated['paypal_secret'] ?? null,
            'paypal_sandbox' => $validated['paypal_sandbox'] ?? false,
            'name' => $validated['name'] ?? null,
            'is_verified' => false,
            'metadata' => ['paypal_mode' => $validated['paypal_mode']],
        ];

        if ($existingPaypal) {
            $existingPaypal->update($data);
            $method = $existingPaypal;
        } else {
            $method = $user->paymentMethods()->create(array_merge($data, [
                'type' => CoachPaymentMethod::TYPE_PAYPAL,
                'is_active' => true,
                'priority' => 0,
            ]));
        }

        // Send verification email (optional)
        // $this->sendVerificationEmail($method);

        if ($request->expectsJson()) {
            return response()->json([
                'success' => true,
                'paymentMethod' => array_merge($method->fresh()->toArray(), [
                    'display_name' => $method->display_name,
                    'type_label' => $method->type_label,
                ]),
                'message' => 'PayPal configurado exitosamente',
            ]);
        }

        return back()->with('success', 'PayPal configurado exitosamente');
    }

    /**
     * Store a new Dominican bank account.
     */
    public function storeDominicanBank(Request $request): JsonResponse|RedirectResponse
    {
        $validated = $request->validate([
            'bank_name' => ['required', 'string', Rule::in(array_keys(CoachPaymentMethod::DOMINICAN_BANKS))],
            'bank_account_number' => 'required|string|max:30',
            'bank_account_type' => ['required', Rule::in(array_keys(CoachPaymentMethod::ACCOUNT_TYPES))],
            'bank_holder_name' => 'required|string|max:255',
            'bank_holder_document' => 'nullable|string|max:20',
            'bank_holder_document_type' => ['nullable', Rule::in(array_keys(CoachPaymentMethod::DOCUMENT_TYPES))],
            'bank_logo' => 'nullable|image|max:2048',
            'name' => 'nullable|string|max:100',
        ]);

        // Validate cedula format if type is cedula and document is provided
        if (!empty($validated['bank_holder_document_type']) && $validated['bank_holder_document_type'] === 'cedula' && !empty($validated['bank_holder_document'])) {
            $cedula = preg_replace('/[^0-9]/', '', $validated['bank_holder_document']);
            if (!CoachPaymentMethod::validateDominicanCedula($cedula)) {
                return $request->expectsJson()
                    ? response()->json(['errors' => ['bank_holder_document' => ['La cédula no es válida']]], 422)
                    : back()->withErrors(['bank_holder_document' => 'La cédula no es válida']);
            }
            $validated['bank_holder_document'] = CoachPaymentMethod::formatDominicanCedula($cedula);
        }

        $user = $request->user();

        // Clean account number (remove spaces/dashes)
        $validated['bank_account_number'] = preg_replace('/[^0-9]/', '', $validated['bank_account_number']);

        // Handle bank logo upload
        $bankLogoPath = null;
        if ($request->hasFile('bank_logo')) {
            $bankLogoPath = $request->file('bank_logo')->store('bank-logos/' . $user->id, 'public');
        }

        $method = $user->paymentMethods()->create([
            'type' => CoachPaymentMethod::TYPE_BANK_DOMINICAN,
            'bank_name' => $validated['bank_name'],
            'bank_logo' => $bankLogoPath,
            'bank_account_number' => $validated['bank_account_number'],
            'bank_account_type' => $validated['bank_account_type'],
            'bank_holder_name' => $validated['bank_holder_name'],
            'bank_holder_document' => $validated['bank_holder_document'] ?? '',
            'bank_holder_document_type' => $validated['bank_holder_document_type'] ?? '',
            'name' => $validated['name'] ?? null,
            'is_active' => true,
            'priority' => $user->paymentMethods()->count(),
        ]);

        if ($request->expectsJson()) {
            return response()->json([
                'success' => true,
                'paymentMethod' => array_merge($method->toArray(), [
                    'display_name' => $method->display_name,
                    'type_label' => $method->type_label,
                    'masked_account' => $method->masked_account_number,
                    'bank_logo_url' => $method->bank_logo ? asset('storage/' . $method->bank_logo) : null,
                ]),
                'message' => 'Cuenta bancaria agregada exitosamente',
            ]);
        }

        return back()->with('success', 'Cuenta bancaria agregada exitosamente');
    }

    /**
     * Store a new international bank account.
     */
    public function storeInternationalBank(Request $request): JsonResponse|RedirectResponse
    {
        $validated = $request->validate([
            'bank_name' => 'required|string|max:255',
            'bank_country' => 'required|string|max:100',
            'bank_swift' => 'nullable|string|max:11',
            'bank_iban' => 'nullable|string|max:34',
            'bank_account_number' => 'required|string|max:50',
            'bank_holder_name' => 'required|string|max:255',
            'bank_currency' => 'required|string|max:10',
            'bank_routing_number' => 'nullable|string|max:20',
            'bank_additional_info' => 'nullable|string|max:500',
            'name' => 'nullable|string|max:100',
        ]);

        $user = $request->user();

        $method = $user->paymentMethods()->create([
            'type' => CoachPaymentMethod::TYPE_BANK_INTERNATIONAL,
            'bank_name' => $validated['bank_name'],
            'bank_country' => $validated['bank_country'],
            'bank_swift' => $validated['bank_swift'] ?? null,
            'bank_iban' => $validated['bank_iban'] ?? null,
            'bank_account_number' => $validated['bank_account_number'],
            'bank_holder_name' => $validated['bank_holder_name'],
            'bank_currency' => $validated['bank_currency'],
            'bank_routing_number' => $validated['bank_routing_number'] ?? null,
            'bank_additional_info' => $validated['bank_additional_info'] ?? null,
            'name' => $validated['name'] ?? null,
            'is_active' => true,
            'priority' => $user->paymentMethods()->count(),
        ]);

        if ($request->expectsJson()) {
            return response()->json([
                'success' => true,
                'paymentMethod' => array_merge($method->toArray(), [
                    'display_name' => $method->display_name,
                    'type_label' => $method->type_label,
                ]),
                'message' => 'Banco internacional agregado exitosamente',
            ]);
        }

        return back()->with('success', 'Banco internacional agregado exitosamente');
    }

    /**
     * Store Western Union info.
     */
    public function storeWesternUnion(Request $request): JsonResponse|RedirectResponse
    {
        $validated = $request->validate([
            'wu_full_name' => 'required|string|max:255',
            'wu_country' => 'required|string|max:100',
            'wu_city' => 'required|string|max:100',
            'wu_phone' => 'required|string|max:20',
            'wu_id_type' => 'nullable|string|max:50',
            'wu_id_number' => 'nullable|string|max:50',
            'name' => 'nullable|string|max:100',
        ]);

        $user = $request->user();

        // Check if already has Western Union
        $existingWU = $user->paymentMethods()
            ->ofType(CoachPaymentMethod::TYPE_WESTERN_UNION)
            ->first();

        if ($existingWU) {
            $existingWU->update($validated);
            $method = $existingWU;
        } else {
            $method = $user->paymentMethods()->create([
                'type' => CoachPaymentMethod::TYPE_WESTERN_UNION,
                'wu_full_name' => $validated['wu_full_name'],
                'wu_country' => $validated['wu_country'],
                'wu_city' => $validated['wu_city'],
                'wu_phone' => $validated['wu_phone'],
                'wu_id_type' => $validated['wu_id_type'] ?? null,
                'wu_id_number' => $validated['wu_id_number'] ?? null,
                'name' => $validated['name'] ?? null,
                'is_active' => true,
                'priority' => $user->paymentMethods()->count(),
            ]);
        }

        if ($request->expectsJson()) {
            return response()->json([
                'success' => true,
                'paymentMethod' => array_merge($method->fresh()->toArray(), [
                    'display_name' => $method->display_name,
                    'type_label' => $method->type_label,
                ]),
                'message' => 'Western Union configurado exitosamente',
            ]);
        }

        return back()->with('success', 'Western Union configurado exitosamente');
    }

    /**
     * Update a payment method.
     */
    public function update(Request $request, CoachPaymentMethod $paymentMethod): JsonResponse|RedirectResponse
    {
        $user = $request->user();

        if ($paymentMethod->coach_id !== $user->id) {
            abort(403);
        }

        $validated = $request->validate([
            'name' => 'nullable|string|max:100',
            'is_active' => 'boolean',
            'priority' => 'nullable|integer|min:0',
        ]);

        $paymentMethod->update($validated);

        if ($request->expectsJson()) {
            return response()->json([
                'success' => true,
                'method' => array_merge($paymentMethod->fresh()->toArray(), [
                    'display_name' => $paymentMethod->display_name,
                    'type_label' => $paymentMethod->type_label,
                ]),
                'message' => 'Método de pago actualizado',
            ]);
        }

        return back()->with('success', 'Método de pago actualizado');
    }

    /**
     * Toggle active status.
     */
    public function toggleActive(Request $request, CoachPaymentMethod $paymentMethod): JsonResponse
    {
        $user = $request->user();

        if ($paymentMethod->coach_id !== $user->id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $paymentMethod->update([
            'is_active' => !$paymentMethod->is_active,
        ]);

        return response()->json([
            'success' => true,
            'is_active' => $paymentMethod->is_active,
            'message' => $paymentMethod->is_active ? 'Método activado' : 'Método desactivado',
        ]);
    }

    /**
     * Update priorities (reorder).
     */
    public function updatePriorities(Request $request): JsonResponse
    {
        $request->validate([
            'methods' => 'required|array',
            'methods.*.id' => 'required|integer',
            'methods.*.priority' => 'required|integer|min:0',
        ]);

        $user = $request->user();

        foreach ($request->input('methods') as $item) {
            $user->paymentMethods()
                ->where('id', $item['id'])
                ->update(['priority' => $item['priority']]);
        }

        return response()->json([
            'success' => true,
            'message' => 'Orden actualizado',
        ]);
    }

    /**
     * Delete a payment method.
     */
    public function destroy(Request $request, CoachPaymentMethod $paymentMethod): JsonResponse|RedirectResponse
    {
        $user = $request->user();

        if ($paymentMethod->coach_id !== $user->id) {
            abort(403);
        }

        // Soft delete
        $paymentMethod->delete();

        if ($request->expectsJson()) {
            return response()->json([
                'success' => true,
                'message' => 'Método de pago eliminado',
            ]);
        }

        return back()->with('success', 'Método de pago eliminado');
    }

    /**
     * Verify PayPal email by sending a test request.
     */
    public function verifyPaypal(Request $request, CoachPaymentMethod $paymentMethod): JsonResponse
    {
        $user = $request->user();

        if ($paymentMethod->coach_id !== $user->id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        if ($paymentMethod->type !== CoachPaymentMethod::TYPE_PAYPAL) {
            return response()->json(['error' => 'Invalid payment method type'], 400);
        }

        // Send verification email
        try {
            $token = $paymentMethod->verification_token;
            $verificationUrl = route('coach.payment-methods.verify-token', [
                'token' => $token,
            ]);

            // In a real implementation, send an email
            // Mail::to($paymentMethod->paypal_email)->send(new VerifyPayPalEmail($verificationUrl));

            return response()->json([
                'success' => true,
                'message' => 'Correo de verificación enviado a ' . $paymentMethod->paypal_email,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'error' => 'No se pudo enviar el correo de verificación',
            ], 500);
        }
    }

    /**
     * Confirm verification token.
     */
    public function verifyToken(Request $request, string $token): RedirectResponse
    {
        $method = CoachPaymentMethod::where('verification_token', $token)->first();

        if (!$method) {
            return redirect()->route('coach.plans.index')
                ->with('error', 'Token de verificación inválido');
        }

        $method->update([
            'is_verified' => true,
            'verified_at' => now(),
            'verification_token' => null,
        ]);

        return redirect()->route('coach.plans.index')
            ->with('success', 'Método de pago verificado exitosamente');
    }

    /**
     * Get all payment methods for API.
     */
    public function list(Request $request): JsonResponse
    {
        $user = $request->user();

        $methods = $user->paymentMethods()
            ->active()
            ->ordered()
            ->get()
            ->map(fn($method) => array_merge($method->toArray(), [
                'display_name' => $method->display_name,
                'type_label' => $method->type_label,
                'masked_account' => $method->masked_account_number,
            ]));

        return response()->json([
            'methods' => $methods,
            'dominicanBanks' => CoachPaymentMethod::DOMINICAN_BANKS,
            'accountTypes' => CoachPaymentMethod::ACCOUNT_TYPES,
        ]);
    }
}
