<?php

namespace App\Http\Controllers;

use App\Jobs\ProcessPackageOrder;
use App\Models\Coupon;
use App\Models\OrderPackage;
use App\Models\Package;
use App\Models\WalletTransaction;
use Illuminate\Http\Request;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Stripe\Stripe;
use Stripe\Checkout\Session;

class PackageController extends Controller
{
    /**
     * Display a listing of the resource.
     */

    public function index(Request $request)
    {
        $packages = Package::query()
            ->where('is_active', true)
            ->with('packageCategory')
            ->when($request->has('featured'), function ($query) {
                $query->where('is_featured', true);
            })
            ->when($request->has('category_id'), function ($query) use ($request) {
                $query->where('package_category_id', $request->category_id);
            })
            ->latest()
            ->get();

        return response()->json([
            'success' => true,
            'data' => $packages,
        ]);
    }

    /**
     * Get single package by slug
     */
    public function show(string $slug)
    {
        $package = Package::where('slug', '=', $slug)

            ->with('packageCategory')
            ->firstOrFail();

        return response()->json([
            'success' => true,
            'data' => $package,
        ]);
    }

    /**
     * Get featured packages
     */
    public function featured()
    {
        $packages = Package::where('is_active', true)
            ->where('is_featured', true)
            ->with('packageCategory')
            ->latest()
            ->get();

        return response()->json([
            'success' => true,
            'data' => $packages,
        ]);
    }
    public function orderPackageIndex(Request $request)
    {
        $query = OrderPackage::with(['package', 'user', 'coupon']);

        // Optional filters
        if ($request->has('status') && $request->status !== null) {
            $query->where('status', $request->status);
        }

        if ($request->has('is_paid') && $request->is_paid !== null) {
            $query->where('is_paid', $request->is_paid);
        }

        if ($request->has('pm_type') && $request->pm_type !== null) {
            $query->where('pm_type', $request->pm_type);
        }

        $data = $query->latest()->paginate(20);

        return response()->json([
            'success' => true,
            'data' => $data
        ]);
    }

    /**
     * Store a newly created resource.
     */

    public function orderPackageStore(Request $request)
    {
        $validated = $request->validate([
            'package_id' => ['required', 'exists:packages,id'],
            'pm_type'    => ['required', 'in:wallet,stripe'],
            'coupon_id'  => ['nullable', 'exists:coupons,id'],
        ]);

        $user    = Auth::user();
        $package = Package::findOrFail($validated['package_id']);

        $amount   = $package->price;
        $discount = 0;

        /**
         * ------------------------------------
         * APPLY COUPON (OPTIONAL)
         * ------------------------------------
         */
        if (! empty($validated['coupon_id'])) {
            $coupon = Coupon::where('id', $validated['coupon_id'])
                ->where('is_active', true)
                ->first();

            if ($coupon) {
                $discount = $coupon->type === 'percent'
                    ? ($amount * $coupon->amount) / 100
                    : $coupon->amount;
            }
        }

        $finalAmount = max(0, round($amount - $discount, 2));

        /**
         * ------------------------------------
         * CREATE ORDER (ATOMIC)
         * ------------------------------------
         */
        $order = DB::transaction(function () use (
            $validated,
            $user,
            $package,
            $finalAmount
        ) {

            $order = OrderPackage::create([
                'package_id' => $package->id,
                'user_id'    => $user->id,
                'pm_type'    => $validated['pm_type'],
                'amount'     => $finalAmount,
                'status'     => 'pending',
                'is_paid'    => false,
                'coupon_id'  => $validated['coupon_id'] ?? null,
            ]);

            /**
             * --------------------------------
             * WALLET PAYMENT
             * --------------------------------
             */
            if ($validated['pm_type'] === 'wallet') {

                $wallet = $user->wallet;

                if (! $wallet || ! $wallet->is_active) {
                    throw new \Exception('Wallet not available.');
                }

                if ($wallet->balance < $finalAmount) {
                    return $order; // stay pending
                }

                $walletTransaction = WalletTransaction::create([
                    'pm_type'   => 'wallet',
                    'type'      => 'debit',
                    'status'    => 'completed',
                    'amount'    => $finalAmount,
                    'wallet_id' => $wallet->id,
                    'user_id'   => $user->id,
                ]);

                $order->update([
                    'wallet_transaction_id' => $walletTransaction->id,
                    'status'                => 'completed',
                    'is_paid'               => true,
                ]);

                // 🔔 Apply package immediately
                ProcessPackageOrder::dispatchSync($order);
            }

            return $order;
        });

        /**
         * --------------------------------
         * STRIPE CHECKOUT
         * --------------------------------
         */
        if ($validated['pm_type'] === 'stripe') {

            Stripe::setApiKey(config('services.stripe.secret'));

            $session = Session::create([
                'mode' => 'payment',
                'payment_method_types' => ['card'],
                'line_items' => [[
                    'price_data' => [
                        'currency' => 'usd',
                        'unit_amount' => (int) round($finalAmount * 100),
                        'product_data' => [
                            'name' => $package->name,
                        ],
                    ],
                    'quantity' => 1,
                ]],
                'success_url' => route('stripe.package.success') . '?session_id={CHECKOUT_SESSION_ID}',
                'cancel_url'  => route('stripe.package.cancel'),
                'metadata' => [
                    'order_id'  => $order->id,
                    'user_id'   => $user->id,
                    'package_id' => $package->id,
                    'amount'    => $finalAmount,
                ],
            ]);

            return response()->json([
                'success'       => true,
                'checkout_url'  => $session->url,
                'order_id'      => $order->id,
            ]);
        }

        /**
         * --------------------------------
         * WALLET RESPONSE
         * --------------------------------
         */
        return response()->json([
            'success'        => true,
            'message'        => $order->is_paid
                ? 'Package purchased successfully using wallet. You will receive the package email shortly.'
                : 'Order created. Awaiting payment.',
            'original_price' => $amount,
            'discount'       => $discount,
            'final_amount'   => $finalAmount,
            'wallet_balance' => optional($user->wallet)->balance,
            'data'           => $order,
        ], 201);
    }
    public function packageSuccess(Request $request)
    {
        $sessionId = $request->query('session_id');

        abort_if(! $sessionId, 400, 'Missing session ID');

        Stripe::setApiKey(config('services.stripe.secret'));

        $session = Session::retrieve($sessionId);

        abort_if($session->payment_status !== 'paid', 400, 'Payment not completed');

        $orderId = $session->metadata->order_id ?? null;

        abort_if(! $orderId, 400, 'Missing order metadata');

        $order = OrderPackage::where('id', $orderId)
            ->where('status', 'pending')
            ->firstOrFail();

        $order->update([
            'status'  => 'completed',
            'is_paid' => true,
        ]);

        ProcessPackageOrder::dispatch($order);

        return redirect()->away(
            env('APP_FRONTEND_URL') . '/package-success?' . http_build_query([
                'order_id' => $order->id,
                'status'   => $order->status,
                'amount'   => $order->amount,
                'package'  => $order->package->name,
                'pm_type'  => $order->pm_type,
            ])
        );
    }
}
