<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Booking;
use App\Models\Order;
use App\Models\OrderItem;
use Darryldecode\Cart\Facades\CartFacade as Cart;
use App\Notifications\BookingPaidNotification;
use App\Notifications\OrderPaidNotification;
use App\Services\PaypalService;
use App\Services\PaystackService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Inertia\Inertia;

class PaymentController extends Controller
{
    /**
     * Initiate a Paystack payment.
     */
    public function initiatePaystackPayment(Request $request, PaystackService $paystackService)
    {
        $request->validate([
            'amount' => 'required|numeric|min:1',
        ]);

        $cart = $request->session()->get('cart', []);

        if (empty($cart)) {
            return redirect()->route('cart.view')->with('error', 'Your cart is empty.');
        }

        $totalAmount = 0;
        foreach ($cart as $item) {
            $totalAmount += $item['price'] * $item['quantity'];
        }

        $order = Order::create([
            'id' => Str::uuid(),
            'user_id' => Auth::id(),
            'total_amount' => $totalAmount,
            'status' => 'pending',
        ]);

        foreach ($cart as $item) {
            OrderItem::create([
                'id' => Str::uuid(),
                'order_id' => $order->id,
                'item_type' => 'App\\Models\\' . ucfirst($item['item_type']),
                'item_id' => $item['item_id'],
                'quantity' => $item['quantity'],
                'price' => $item['price'],
            ]);
        }

        $user = Auth::user();
        $email = $user ? $user->email : 'guest@example.com'; // Use authenticated user's email or a default
        $orderId = $order->id; // Use the newly created order ID

        try {
            $data = [
                'amount' => $totalAmount * 100, // Paystack expects amount in kobo
                'email' => $email,
                'orderID' => $orderId, // Custom data you want to pass to Paystack
                'callback_url' => route('paystack.callback'),
                'reference' => $orderId, // Use order_id as reference
                'metadata' => [
                    'order_id' => $orderId, // Pass order ID in metadata
                ],
            ];

            $result = $paystackService->initializePayment($data);

            if ($result['status']) {
                return Inertia::location($result['authorization_url']);
            }

            \Log::error('Paystack initialization failed: ' . ($result['message'] ?? 'Unknown error'));
            return redirect()->back()->with('error', $result['message'] ?? 'Payment initialization failed. Please try again.');
        } catch (\Exception $e) {
            \Log::error('Paystack payment initiation error: ' . $e->getMessage());
            return redirect()->back()->with('error', 'An error occurred during payment initiation. Please try again later.');
        }
    }

    /**
     * Handle Paystack payment callback.
     */
    public function paystackCallback(Request $request, PaystackService $paystackService)
    {
        \Log::debug('Paystack callback hit.');
        $reference = $request->reference;

        if (empty($reference)) {
            return redirect()->route('payment.failure')->with('error', 'No reference provided.');
        }

        try {
            $result = $paystackService->verifyPayment($reference);
            \Log::info('Paystack verification result for reference ' . $reference . ': ' . json_encode($result));

            if ($result['status']) {
                $paymentData = $result['data'];
                $orderId = $paymentData['metadata']['order_id'] ?? null;
                $bookingId = $paymentData['metadata']['booking_id'] ?? null;
                \Log::info('Paystack payment successful. Order ID: ' . ($orderId ?? 'N/A') . ', Booking ID: ' . ($bookingId ?? 'N/A'));

                if ($orderId) {
                    $order = Order::find($orderId);
                    if ($order && $order->status !== 'completed') {
                        $order->update(['status' => 'completed']);
                        Cart::clear();
                        $user = $order->user;
                        if ($user) {
                            $user->notify(new OrderPaidNotification($order));
                        }
                        return redirect()->route('payment.success')->with('success', 'Payment successful and order confirmed!');
                    } else if ($order && $order->status === 'completed') {
                        return redirect()->route('payment.success')->with('info', 'Payment already verified and order completed.');
                    } else {
                        \Log::error('Order not found for Paystack callback. Order ID: ' . $orderId);
                        return redirect()->route('payment.failure')->with('error', 'Payment successful, but order not found.');
                    }
                } elseif ($bookingId) {
                    $booking = Booking::find($bookingId);
                    if ($booking && $booking->status !== 'confirmed') {
                        $booking->update(['status' => 'confirmed']);
                        $user = $booking->user;
                        \Log::info('Attempting to send BookingPaidNotification for booking ID: ' . $booking->id);
                        if ($user) {
                            \Log::info('User found for booking ID: ' . $booking->id . ', User ID: ' . $user->id . ', User Email: ' . $user->email);
                             $user->notify(new BookingPaidNotification($booking));
                        } else {
                            \Log::warning('User not found for booking ID: ' . $booking->id . '. Notification not sent.');
                        }
                        return redirect()->route('payment.success')->with('success', 'Payment successful and booking confirmed!');
                    } else if ($booking && $booking->status === 'confirmed') {
                        return redirect()->route('payment.success')->with('info', 'Payment already verified and booking confirmed.');
                    } else {
                        \Log::error('Booking not found for Paystack callback. Booking ID: ' . $bookingId);
                        return redirect()->route('payment.failure')->with('error', 'Payment successful, but booking not found.');
                    }
                } else {
                    \Log::error('Neither Order ID nor Booking ID found in Paystack response metadata. Reference: ' . $reference);
                    return redirect()->route('payment.failure')->with('error', 'Payment successful, but no associated order or booking found.');
                }
            }

            \Log::error('Paystack verification failed: ' . ($result['message'] ?? 'Unknown error') . ' Reference: ' . $reference);
            return redirect()->route('payment.failure')->with('error', $result['message'] ?? 'Payment verification failed.');
        } catch (\Exception $e) {
            \Log::error('Paystack payment verification error: ' . $e->getMessage() . ' Reference: ' . $reference);
            return redirect()->route('payment.failure')->with('error', 'An error occurred during payment verification. Please try again later.');
        }
    }

    /**
     * Initiate a PayPal payment.
     */
    public function initiatePaypalPayment(Request $request, PaypalService $paypalService)
    {
        $request->validate([
            'amount' => 'required|numeric|min:1',
        ]);

        $cart = $request->session()->get('cart', []);

        if (empty($cart)) {
            return redirect()->route('cart.view')->with('error', 'Your cart is empty.');
        }

        $totalAmount = 0;
        foreach ($cart as $item) {
            $totalAmount += $item['price'] * $item['quantity'];
        }

        $order = Order::create([
            'id' => Str::uuid(),
            'user_id' => Auth::id(),
            'total_amount' => $totalAmount,
            'status' => 'pending',
        ]);

        foreach ($cart as $item) {
            OrderItem::create([
                'id' => Str::uuid(),
                'order_id' => $order->id,
                'item_type' => 'App\\Models\\' . ucfirst($item['item_type']),
                'item_id' => $item['item_id'],
                'quantity' => $item['quantity'],
                'price' => $item['price'],
            ]);
        }



        $data = [
            'amount' => $totalAmount,
            'order_id' => $order->id,
            'custom_id' => $order->id, // Pass order_id as custom_id for PayPal metadata
        ];

        try {
            $result = $paypalService->initializePayment($data);

            if ($result['status']) {
                return Inertia::location($result['authorization_url']);
            }

            \Log::error('PayPal initialization failed: ' . ($result['message'] ?? 'Unknown error'));
            return redirect()->back()->with('error', $result['message'] ?? 'Payment initialization failed. Please try again.');
        } catch (\Exception $e) {
            \Log::error('PayPal payment initiation error: ' . $e->getMessage());
            return redirect()->back()->with('error', 'An error occurred during payment initiation. Please try again later.');
        }
    }

    /**
     * Handle PayPal payment success.
     */
    public function paypalSuccess(Request $request, PaypalService $paypalService)
    {
        \Log::debug('PayPal success callback hit.');
        $paypalOrderId = $request->input('token');

        if (empty($paypalOrderId)) {
            return redirect()->route('home')->with('error', 'PayPal order ID not found.');
        }

        try {
            $result = $paypalService->verifyPayment($paypalOrderId);
            \Log::info('PayPal verification result for order ID ' . $paypalOrderId . ': ' . json_encode($result));

            if ($result['status']) {
                $paypalData = $result['data'];
                $customId = $paypalData['purchase_units'][0]['custom_id'] ?? null;
                \Log::info('PayPal payment successful. Custom ID: ' . ($customId ?? 'N/A'));

                if ($customId) {
                    // Check if it's an Order ID
                    $order = Order::find($customId);
                    if ($order) {
                        if ($order->status !== 'completed') {
                            $order->update(['status' => 'completed']);
                            Cart::clear();
                            $user = $order->user;
                            if ($user) {
                                $user->notify(new OrderPaidNotification($order));
                            }
                            return redirect()->route('payment.success')->with('success', 'Payment successful and order confirmed!');
                        } else {
                            return redirect()->route('payment.success')->with('info', 'Payment already verified and order completed!');
                        }
                    }

                    // Check if it's a Booking ID
                    $booking = Booking::find($customId);
                    if ($booking) {
                        if ($booking->status !== 'confirmed') {
                            $booking->update(['status' => 'confirmed']);
                            $user = $booking->user;
                            \Log::info('Attempting to send BookingPaidNotification for booking ID: ' . $booking->id);
                            if ($user) {
                                \Log::info('User found for booking ID: ' . $booking->id . ', User ID: ' . $user->id . ', User Email: ' . $user->email);
                                $user->notify(new BookingPaidNotification($booking));
                            } else {
                                \Log::warning('User not found for booking ID: ' . $booking->id . '. Notification not sent.');
                            }
                            return redirect()->route('payment.success')->with('success', 'Payment successful and booking confirmed!');
                        } else {
                            return redirect()->route('payment.success')->with('info', 'Payment already verified and booking confirmed!');
                        }
                    }

                    \Log::error('Neither Order ID nor Booking ID found for PayPal success. Custom ID: ' . $customId);
                    return redirect()->route('payment.failure')->with('error', 'Payment successful, but no associated order or booking found.');
                } else {
                    \Log::error('Custom ID not found in PayPal response. PayPal Order ID: ' . $paypalOrderId);
                    return redirect()->route('payment.failure')->with('error', 'Payment successful, but custom ID missing.');
                }
            }

            \Log::error('PayPal verification failed: ' . ($result['message'] ?? 'Unknown error') . ' PayPal Order ID: ' . $paypalOrderId);
            return redirect()->route('payment.failure')->with('error', $result['message'] ?? 'Payment verification failed.');
        } catch (\Exception $e) {
            \Log::error('PayPal payment verification error: ' . $e->getMessage() . ' PayPal Order ID: ' . $paypalOrderId);
            return redirect()->route('payment.failure')->with('error', 'An error occurred during payment verification. Please try again later.');
        }
    }

    /**
     * Handle PayPal payment cancellation.
     */
    public function paypalCancel()
    {
        return redirect()->route('home')->with('error', 'Payment cancelled by user.');
    }
}