<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\CartItem;
use App\Models\Coupon;
use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class OrderController extends Controller
{
    public function index(Request $request)
    {
        $orders = $request->user()
            ->orders()
            ->with('items.product')
            ->latest()
            ->paginate(10);

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

    public function store(Request $request)
    {
        $data = $request->validate([
            'payment_method'   => 'required|in:bkash,nagad,card,bank,cod',
            'address_id'       => 'required|exists:addresses,id',
            'coupon_code'      => 'nullable|string',
            'delivery_type'    => 'required|in:standard,express',
            'items'            => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id',
            'items.*.quantity' => 'required|integer|min:1',
            'items.*.size'     => 'nullable|string',
            'items.*.color'    => 'nullable|string',
            'notes'            => 'nullable|string|max:500',
        ]);

        return DB::transaction(function () use ($data, $request) {

            $address = $request->user()->addresses()->findOrFail($data['address_id']);

            // Build order items + calculate subtotal
            $subtotal  = 0;
            $orderItems = [];

            foreach ($data['items'] as $item) {
                $product = Product::findOrFail($item['product_id']);

                if ($product->stock < $item['quantity']) {
                    return response()->json([
                        'success' => false,
                        'message' => "Insufficient stock for: {$product->name}",
                    ], 422);
                }

                $price     = $product->effective_price;
                $subtotal += $price * $item['quantity'];

                $orderItems[] = [
                    'product_id' => $product->id,
                    'name'       => $product->name,
                    'price'      => $price,
                    'quantity'   => $item['quantity'],
                    'size'       => $item['size'] ?? null,
                    'color'      => $item['color'] ?? null,
                    'image'      => $product->images[0] ?? null,
                ];

                // Deduct stock
                $product->decrement('stock', $item['quantity']);
            }

            // Delivery charge
            $deliveryCharge = match($data['delivery_type']) {
                'express' => 150.00,
                default   => $subtotal >= 1500 ? 0.00 : 80.00,
            };

            // Coupon
            $couponDiscount = 0;
            $coupon         = null;
            if (!empty($data['coupon_code'])) {
                $coupon = Coupon::where('code', $data['coupon_code'])->first();
                if ($coupon && $coupon->isValid($subtotal)) {
                    $couponDiscount = $coupon->calculateDiscount($subtotal);
                    $coupon->increment('used_count');
                }
            }

            $total = $subtotal + $deliveryCharge - $couponDiscount;

            // Create order
            $order = Order::create([
                'user_id'          => $request->user()->id,
                'order_number'     => Order::generateOrderNumber(),
                'status'           => Order::STATUS_PENDING,
                'payment_status'   => Order::PAYMENT_PENDING,
                'payment_method'   => $data['payment_method'],
                'subtotal'         => $subtotal,
                'delivery_charge'  => $deliveryCharge,
                'coupon_id'        => $coupon?->id,
                'coupon_code'      => $coupon?->code,
                'coupon_discount'  => $couponDiscount,
                'total'            => $total,
                'address_id'       => $address->id,
                'shipping_name'    => $address->name,
                'shipping_phone'   => $address->phone,
                'shipping_address' => $address->address,
                'shipping_district'=> $address->district,
                'notes'            => $data['notes'] ?? null,
            ]);

            // Create order items
            foreach ($orderItems as $item) {
                $order->items()->create($item);
            }

            // Award loyalty points (1 point per ৳100)
            $points = (int) floor($total / 100);
            $request->user()->increment('loyalty_points', $points);

            // Clear cart
            CartItem::where('user_id', $request->user()->id)->delete();

            return response()->json([
                'success'        => true,
                'message'        => 'Order placed successfully!',
                'order'          => $order->load('items.product'),
                'loyalty_earned' => $points,
            ], 201);
        });
    }

    public function show(Request $request, int $id)
    {
        $order = $request->user()
            ->orders()
            ->with('items.product')
            ->findOrFail($id);

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

    public function cancel(Request $request, int $id)
    {
        $order = $request->user()->orders()->findOrFail($id);

        if (!$order->canBeCancelled()) {
            return response()->json(['success' => false, 'message' => 'Order cannot be cancelled at this stage.'], 422);
        }

        DB::transaction(function () use ($order) {
            // Restore stock
            foreach ($order->items as $item) {
                if ($item->product) {
                    $item->product->increment('stock', $item->quantity);
                }
            }
            $order->update(['status' => Order::STATUS_CANCELLED]);
        });

        return response()->json(['success' => true, 'message' => 'Order cancelled successfully.']);
    }

    public function track(Request $request)
    {
        $request->validate([
            'order_number' => 'required|string',
            'phone'        => 'required|string',
        ]);

        $order = Order::where('order_number', $request->order_number)
            ->where('shipping_phone', $request->phone)
            ->with('items.product')
            ->firstOrFail();

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

    public function requestReturn(Request $request, int $id)
    {
        $request->validate(['reason' => 'required|string|max:500']);
        $order = $request->user()->orders()->where('status', Order::STATUS_DELIVERED)->findOrFail($id);
        $order->update(['status' => Order::STATUS_RETURNED]);
        return response()->json(['success' => true, 'message' => 'Return request submitted.']);
    }
}
