<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Booking;
use App\Models\Payment;
use App\Models\Setting;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

/**
 * PaymentController - Handles Flutterwave payment processing
 */
class PaymentController extends Controller
{
    /**
     * Initialize online payment (Flutterwave or PayPal)
     */
    public function initializePayment(Request $request, $reference)
    {
        try {
            $payment = Payment::with(['booking', 'booking.package'])
                ->where('payment_reference', $reference)
                ->firstOrFail();

            if ($payment->status !== 'pending') {
                return back()->with('error', __('This payment has already been processed.'));
            }

            $method = $request->get('method') ?? $payment->payment_method ?? 'flutterwave';

            // Check if the payment method is enabled in admin settings
            if ($method === 'flutterwave' && !Setting::get('payment_flutterwave_enabled', true)) {
                return back()->with('error', __('Flutterwave payments are currently disabled.'));
            }

            if ($method === 'paypal' && !Setting::get('payment_paypal_enabled', false)) {
                return back()->with('error', __('PayPal payments are currently disabled.'));
            }

            if ($method === 'flutterwave') {
                $result = $this->flutterWaveInitialize($payment);
                $paymentMethod = 'flutterwave';
            } elseif ($method === 'paypal') {
                $result = $this->paypalInitialize($payment);
                $paymentMethod = 'paypal';
            } else {
                return back()->with('error', __('Invalid payment method selected.'));
            }

            if (!$result['success']) {
                return back()->with('error', $result['message'] ?? 'Failed to initialize payment');
            }

            // Update payment record
            $payment->update([
                'payment_method' => $paymentMethod,
                'payment_details' => $result['data'] ?? [],
            ]);

            if (isset($result['link'])) {
                return redirect()->to($result['link'])->with('payment_initialized', true);
            }

            return back()->with('error', __('Unable to redirect to payment gateway.'));

        } catch (\Exception $e) {
            Log::error('Payment initialization error: ' . $e->getMessage());
            return back()->with('error', __('Failed to process payment. Please try again.'));
        }
    }

    /**
     * Handle Flutterwave callback/redirect
     */
    public function handleCallback(Request $request)
    {
        $status = $request->get('status');
        $transactionId = $request->get('transaction_id');
        $txRef = $request->get('tx_ref');

        if (!$status || !$transactionId || !$txRef) {
            return redirect()->route('booking.failed', $txRef)
                ->with('error', __('Invalid payment response from Flutterwave.'));
        }

        try {
            $payment = Payment::where('payment_reference', $txRef)->firstOrFail();

            // Verify payment with Flutterwave
            $result = $this->flutterWaveVerify($transactionId);

            if ($result['success']) {
                // Update payment status
                $payment->update([
                    'status' => 'completed',
                    'transaction_id' => $transactionId,
                    'confirmed_at' => now(),
                    'payment_details' => $result['data'] ?? [],
                ]);

                // Mark booking as paid
                $payment->booking->markAsPaid();

                // Send confirmation email
                try {
                    \Mail::to($payment->booking->email)
                        ->send(new \App\Mail\PaymentRequestMail($payment, true));
                } catch (\Exception $e) {
                    Log::error('Payment confirmation email failed: ' . $e->getMessage());
                }

                return redirect()->route('booking.success', $payment->booking->booking_reference)
                    ->with('success', __('Payment confirmed successfully!'));
            } else {
                // Payment verification failed
                $payment->update([
                    'status' => 'failed',
                    'transaction_id' => $transactionId,
                ]);

                return redirect()->route('booking.failed', $txRef)
                    ->with('error', __('Payment verification failed. Please contact support.'));
            }

        } catch (\Exception $e) {
            Log::error('Payment callback error: ' . $e->getMessage());
            return redirect()->route('booking.failed', $txRef ?? 'unknown')
                ->with('error', __('An error occurred while processing your payment.'));
        }
    }

    /**
     * Handle Flutterwave webhook
     */
    public function handleWebhook(Request $request)
    {
        try {
            $signature = $request->header('verif-hash');
            $payload = $request->getContent();
            $secretKey = config('flutterwave.secret_key');

            if (!$signature || !$this->verifyWebhookSignature($payload, $signature, $secretKey)) {
                Log::warning('Invalid Flutterwave webhook signature');
                return response()->json(['error' => 'Invalid signature'], 401);
            }

            $data = $request->json()->all();
            $txRef = $data['data']['tx_ref'] ?? null;
            $status = $data['data']['status'] ?? null;

            if (!$txRef) {
                return response()->json(['error' => 'Missing tx_ref'], 400);
            }

            $payment = Payment::where('payment_reference', $txRef)->first();

            if (!$payment) {
                return response()->json(['error' => 'Payment not found'], 404);
            }

            // Update payment based on webhook status
            if ($status === 'successful') {
                if ($payment->status === 'pending') {
                    $payment->update([
                        'status' => 'completed',
                        'transaction_id' => $data['data']['id'] ?? null,
                        'confirmed_at' => now(),
                        'payment_details' => $data['data'],
                    ]);

                    $payment->booking->markAsPaid();
                }
            } elseif ($status === 'failed' && $payment->status === 'pending') {
                $payment->update([
                    'status' => 'failed',
                    'transaction_id' => $data['data']['id'] ?? null,
                    'admin_notes' => 'Failed via webhook: ' . ($data['data']['processor_response'] ?? 'Unknown reason'),
                ]);
            }

            Log::info('Flutterwave webhook processed', ['tx_ref' => $txRef, 'status' => $status]);

            return response()->json(['success' => true], 200);

        } catch (\Exception $e) {
            Log::error('Webhook processing error: ' . $e->getMessage());
            return response()->json(['error' => 'Webhook processing failed'], 500);
        }
    }

    /**
     * Initialize Flutterwave payment
     */
    private function flutterWaveInitialize(Payment $payment)
    {
        try {
            $baseUrl = 'https://api.flutterwave.com/v3';
            $secretKey = config('flutterwave.secret_key');
            $booking = $payment->booking;
            $package = $booking->package;

            $payload = [
                'tx_ref' => $payment->payment_reference,
                'amount' => (float) $payment->amount,
                'currency' => $payment->currency,
                'payment_options' => config('flutterwave.payment_options', 'card,banktransfer,ussd'),
                'customer' => [
                    'email' => $booking->email,
                    'phonenumber' => $booking->phone,
                    'name' => $booking->full_name,
                ],
                'customizations' => [
                    'title' => 'Tourism Booking Payment',
                    'description' => "Payment for {$package->title} - {$booking->booking_reference}",
                    'logo' => config('flutterwave.logo_url'),
                ],
                'redirect_url' => route('payment.callback'),
                'meta' => [
                    'booking_id' => $booking->id,
                    'payment_id' => $payment->id,
                ],
            ];

            $response = Http::withToken($secretKey)
                ->post("{$baseUrl}/payments", $payload);

            if ($response->successful()) {
                $data = $response->json();
                return [
                    'success' => true,
                    'data' => $data['data'] ?? null,
                    'link' => $data['data']['link'] ?? null,
                ];
            }

            Log::error('Flutterwave initialization failed', [
                'status' => $response->status(),
                'response' => $response->json(),
            ]);

            return [
                'success' => false,
                'message' => 'Failed to initialize payment',
            ];

        } catch (\Exception $e) {
            Log::error('Flutterwave initialization error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Error initializing payment',
            ];
        }
    }

    /**
     * Verify Flutterwave payment
     */
    private function flutterWaveVerify($transactionId)
    {
        try {
            $baseUrl = 'https://api.flutterwave.com/v3';
            $secretKey = config('flutterwave.secret_key');

            $response = Http::withToken($secretKey)
                ->get("{$baseUrl}/transactions/{$transactionId}/verify");

            if ($response->successful()) {
                $data = $response->json()['data'] ?? [];
                return [
                    'success' => $data['status'] === 'successful',
                    'data' => $data,
                ];
            }

            Log::error('Flutterwave verification failed', [
                'transaction_id' => $transactionId,
                'status' => $response->status(),
            ]);

            return [
                'success' => false,
                'message' => 'Failed to verify payment',
            ];

        } catch (\Exception $e) {
            Log::error('Flutterwave verification error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Error verifying payment',
            ];
        }
    }

    /**
     * Verify webhook signature
     */
    private function verifyWebhookSignature($payload, $signature, $secretKey)
    {
        try {
            $hash = hash_hmac('sha256', $payload, $secretKey);
            return hash_equals($hash, $signature);
        } catch (\Exception $e) {
            Log::error('Webhook signature verification error: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Get available payment methods
     */
    public function paymentMethods()
    {
        return response()->json([
            'methods' => [
                [
                    'id' => 'flutterwave',
                    'name' => 'Flutterwave',
                    'description' => 'Pay securely with card, bank transfer, USSD, or mobile money',
                    'enabled' => Setting::get('payment_flutterwave_enabled', true),
                ],
                [
                    'id' => 'paypal',
                    'name' => 'PayPal',
                    'description' => 'Pay securely with PayPal (International)',
                    'enabled' => Setting::get('payment_paypal_enabled', false),
                ],
                [
                    'id' => 'whatsapp',
                    'name' => 'WhatsApp',
                    'description' => 'Manual payment confirmation via WhatsApp',
                    'enabled' => true,
                ],
            ]
        ]);
    }

    /**
     * Initialize PayPal payment
     */
    private function paypalInitialize($payment)
    {
        try {
            $booking = $payment->booking;
            $package = $booking->package;

            $provider = new \Srmklive\PayPal\Services\PayPal;
            $provider->setApiCredentials(config('paypal'));
            $provider->setAccessToken($provider->getAccessToken());

            $order = $provider->createOrder([
                'intent' => 'CAPTURE',
                'purchase_units' => [
                    [
                        'reference_id' => $payment->payment_reference,
                        'description' => "Payment for {$package->title}",
                        'amount' => [
                            'currency_code' => $payment->currency,
                            'value' => number_format($payment->amount, 2, '.', ''),
                        ],
                        'custom_id' => $payment->id,
                    ],
                ],
                'application_context' => [
                    'return_url' => route('payment.callback') . '?method=paypal',
                    'cancel_url' => route('booking.failed', $payment->payment_reference),
                ],
            ]);

            $approvalLink = collect($order['links'])->firstWhere('rel', 'approve')['href'] ?? null;

            if ($approvalLink) {
                $payment->update([
                    'payment_details' => ['order_id' => $order['id']],
                ]);

                return [
                    'success' => true,
                    'link' => $approvalLink,
                    'data' => $order,
                ];
            }

            return ['success' => false, 'message' => 'Failed to create PayPal order'];

        } catch (\Exception $e) {
            Log::error('PayPal initialization error: ' . $e->getMessage());
            return ['success' => false, 'message' => 'PayPal error: ' . $e->getMessage()];
        }
    }

    /**
     * Handle PayPal callback
     */
    public function handlePayPalCallback(Request $request)
    {
        $orderId = $request->get('token');
        $payerId = $request->get('PayerID');

        if (!$orderId || !$payerId) {
            return redirect()->route('home')->with('error', 'Invalid PayPal response.');
        }

        try {
            $provider = new \Srmklive\PayPal\Services\PayPal;
            $provider->setApiCredentials(config('paypal'));
            $provider->setAccessToken($provider->getAccessToken());

            $result = $provider->capturePaymentOrder($orderId);

            if ($result['status'] === 'COMPLETED') {
                $reference = $result['purchase_units'][0]['reference_id'] ?? null;

                $payment = Payment::where('payment_reference', $reference)->firstOrFail();

                $payment->update([
                    'status' => 'completed',
                    'transaction_id' => $result['id'],
                    'confirmed_at' => now(),
                    'payment_details' => $result,
                ]);

                $payment->booking->markAsPaid();

                return redirect()->route('booking.success', $payment->booking->booking_reference)
                    ->with('success', 'Payment completed successfully via PayPal!');
            }

            return redirect()->route('booking.failed', $reference)
                ->with('error', 'PayPal payment was not completed.');

        } catch (\Exception $e) {
            Log::error('PayPal callback error: ' . $e->getMessage());
            return redirect()->route('home')->with('error', 'Error processing PayPal payment.');
        }
    }
                [
                    'id' => 'offline',
                    'name' => 'Offline Payment',
                    'description' => 'Pay via bank transfer, mobile money, or check',
                    'enabled' => Setting::get('offline_payment_enabled', true),
                ],
            ],
        ]);
    }
}
