<?php

namespace App\Http\Controllers;

use App\Models\Product;
use App\Models\ProductCategory;
use App\Models\OrderProduct;
use App\Jobs\ProcessProductOrder;
use App\Models\Coupon;
use App\Models\WalletTransaction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Stripe\Stripe;
use Stripe\Checkout\Session;
class ProductController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | PRODUCTS
    |--------------------------------------------------------------------------
    */

    public function index(Request $request)
    {
        $products = Product::query()
            ->where('is_active', true)
            ->with('productCategory')
            ->when($request->has('featured'), fn ($q) =>
                $q->where('is_featured', true)
            )
            ->when($request->has('category_id'), fn ($q) =>
                $q->where('product_category_id', $request->category_id)
            )
            ->latest()
            ->get();

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

    public function show(string $slug)
    {
        $product = Product::where('slug', $slug)
            ->where('is_active', true)
            ->with('productCategory')
            ->firstOrFail();

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

    public function featured()
    {
        $products = Product::where('is_active', true)
            ->where('is_featured', true)
            ->with('productCategory')
            ->latest()
            ->get();

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

    /*
    |--------------------------------------------------------------------------
    | PRODUCT CATEGORIES
    |--------------------------------------------------------------------------
    */

    public function categories()
    {
        $categories = ProductCategory::where('is_active', true)
            ->latest()
            ->get();

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

    public function categoryProducts(string $slug)
    {
        $category = ProductCategory::where('slug', $slug)
            ->where('is_active', true)
            ->firstOrFail();

        $products = Product::where('is_active', true)
            ->where('product_category_id', $category->id)
            ->with('productCategory')
            ->latest()
            ->get();

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

    /*
    |--------------------------------------------------------------------------
    | ORDER PRODUCTS
    |--------------------------------------------------------------------------
    */

    public function orderProductIndex(Request $request)
    {
        $query = OrderProduct::with(['product', 'user', 'coupon']);

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        if ($request->filled('is_paid')) {
            $query->where('is_paid', $request->is_paid);
        }

        if ($request->filled('pm_type')) {
            $query->where('pm_type', $request->pm_type);
        }

        if ($request->filled('user_id')) {
            $query->where('user_id', $request->user_id);
        }

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

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


public function orderProductStore(Request $request)
{
    $validated = $request->validate([
        'product_id' => ['required', 'exists:products,id'],
        'quantity'   => ['required', 'numeric', 'min:1'],
        'pm_type'    => ['required', 'in:wallet,stripe'],
        'coupon_id'  => ['nullable', 'exists:coupons,id'],
    ]);

    $user    = Auth::user();
    $product = Product::findOrFail($validated['product_id']);

    $amount   = $product->price * $validated['quantity'];
    $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,
        $product,
        $finalAmount
    ) {

        $order = OrderProduct::create([
            'product_id' => $product->id,
            'user_id'    => $user->id,
            'quantity'   => $validated['quantity'],
            '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; // keep pending
            }

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

            // ✅ ONLY CHANGE IS HERE
            $order->update([
                'wallet_transaction_id' => $walletTransaction->id,
                'status'                => 'completed',
                'is_paid'               => true,
            ]);

            ProcessProductOrder::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' => $product->name,
                    ],
                ],
                'quantity' => 1,
            ]],
            'success_url' => route('stripe.product.success') . '?session_id={CHECKOUT_SESSION_ID}',
            'cancel_url'  => route('stripe.product.cancel'),
            'metadata' => [
                'order_id'   => $order->id,
                'user_id'    => $user->id,
                'product_id' => $product->id,
                'quantity'   => $validated['quantity'],
                '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
            ? 'Product purchased successfully using wallet.'
            : 'Order created. Awaiting payment.',
        'original_price' => $amount,
        'discount'       => $discount,
        'final_amount'   => $finalAmount,
        'wallet_balance' => optional($user->wallet)->balance,
        'data'           => $order,
    ], 201);
}

public function productSuccess(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 = OrderProduct::where('id', $orderId)
        ->where('status', 'pending')
        ->firstOrFail();

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

    ProcessProductOrder::dispatch($order);

    return redirect()->away(
        env('APP_FRONTEND_URL')
        . '/product-success?order_id=' . $order->id
    );
}

}
