<?php
// app/Http/Controllers/Api/Customer/OrderController.php
namespace App\Http\Controllers\Api\Customer;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Customer\OrderRequest;
use App\Http\Requests\Api\Customer\OrderCancelRequest;
use App\Http\Resources\Api\Customer\OrderResource;
use App\Http\Resources\Api\Customer\PaymentMethodResource;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Menu;
use App\Models\Payment;
use App\Models\PaymentMethod;
use App\Models\Promo;
use App\Services\OrderService;
use App\Traits\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;

class OrderController extends Controller
{
    use ApiResponse;

    protected $orderService;

    public function __construct(OrderService $orderService)
    {
        $this->orderService = $orderService;
    }

    /**
     * Get checkout summary (pre-checkout validation)
     * GET /api/customer/orders/checkout-summary
     */
    public function checkoutSummary(Request $request): JsonResponse
    {
        $user = $request->user();
        $cart = Cache::get("cart:{$user->id}", []);

        if (empty($cart)) {
            return $this->errorResponse('Keranjang kosong', 400);
        }

        // Validate cart items
        $validation = $this->orderService->validateCart($cart);
        
        // Get available payment methods
        $paymentMethods = PaymentMethod::active()->get();
        
        // Calculate with promo if provided
        $promoDiscount = 0;
        $promoMessage = null;
        
        if ($request->promo_code) {
            $promo = Promo::where('code', $request->promo_code)->first();
            if ($promo) {
                $promoDiscount = $promo->calculateDiscount($validation['subtotal']);
                $promoMessage = "Promo diterapkan: {$promo->name}";
                
                // Update estimated total with promo discount
                $validation['estimated_total'] = $validation['estimated_total'] - $promoDiscount;
                $validation['summary']['formatted_total'] = 'Rp ' . number_format($validation['estimated_total'], 0, ',', '.');
            } else {
                $promoMessage = "Kode promo tidak valid";
            }
        }

        return $this->successResponse([
            'cart_validation' => $validation,
            'promo' => [
                'code' => $request->promo_code,
                'discount' => $promoDiscount,
                'message' => $promoMessage,
                'is_valid' => $promoDiscount > 0,
            ],
            'payment_methods' => PaymentMethodResource::collection($paymentMethods),
            'order_types' => [
                ['value' => 'dine_in', 'label' => '🍽️ Makan di Tempat'],
                ['value' => 'takeaway', 'label' => '🥡 Bawa Pulang'],
                ['value' => 'delivery', 'label' => '🚚 Delivery'],
            ],
            'instructions' => [
                'dine_in' => 'Silakan duduk di meja yang tersedia',
                'takeaway' => 'Pesanan dapat diambil di kasir',
                'delivery' => 'Pesanan akan dikirim ke alamat yang terdaftar',
            ]
        ], 'Ringkasan checkout berhasil diambil');
    }

    /**
     * Create new order
     * POST /api/customer/orders
     */
    public function store(OrderRequest $request): JsonResponse
    {
        try {
            DB::beginTransaction();

            $user = $request->user();
            $cart = Cache::get("cart:{$user->id}", []);

            if (empty($cart)) {
                return $this->errorResponse('Keranjang kosong', 400);
            }

            // Validate cart before checkout
            $validation = $this->orderService->validateCart($cart);
            if (!$validation['can_checkout']) {
                return $this->errorResponse(
                    'Tidak dapat checkout. Ada item yang tidak tersedia.', 
                    400,
                    ['unavailable_items' => $validation['unavailable_items']]
                );
            }

            // Generate order number
            $orderNumber = $this->orderService->generateOrderNumber();

            // Calculate order totals
            $orderData = $this->orderService->calculateOrder($cart, $request->all());

            // Create order
            $order = Order::create([
                'order_number' => $orderNumber,
                'customer_id' => $user->id,
                'order_type' => $request->order_type,
                'table_number' => $request->order_type === 'dine_in' ? $request->table_number : null,
                'total_amount' => $orderData['subtotal'],
                'tax_amount' => $orderData['tax'],
                'service_fee' => $orderData['service_fee'],
                'discount_amount' => $orderData['discount'],
                'final_amount' => $orderData['final_total'],
                'notes' => $request->notes,
                'status' => 'pending',
                'scheduled_for' => $request->scheduled_for,
            ]);

            // Create order items and reduce stock
            foreach ($orderData['items'] as $item) {
                OrderItem::create([
                    'order_id' => $order->id,
                    'menu_id' => $item['menu_id'],
                    'quantity' => $item['quantity'],
                    'unit_price' => $item['unit_price'],
                    'subtotal' => $item['subtotal'],
                    'notes' => $item['notes'],
                ]);

                // Reduce menu stock
                $menu = $item['menu'];
                $menu->reduceStock($item['quantity']);
            }

            // Create initial payment record
            $payment = Payment::create([
                'order_id' => $order->id,
                'payment_method_id' => $request->payment_method_id,
                'amount' => $orderData['final_total'],
                'status' => 'pending',
                'reference_number' => 'PAY-' . strtoupper(uniqid()),
            ]);

            // Clear cart after successful checkout
            Cache::forget("cart:{$user->id}");

            DB::commit();

            // Load relationships for response
            $order->load(['items.menu', 'payments.paymentMethod']);

            return $this->successResponse(
                new OrderResource($order),
                '🎉 Pesanan berhasil dibuat! Silakan selesaikan pembayaran.',
                201
            );

        } catch (\Exception $e) {
            DB::rollBack();
            return $this->errorResponse('Gagal membuat pesanan: ' . $e->getMessage(), 500);
        }
    }

    /**
     * Get customer orders
     * GET /api/customer/orders
     */
    public function index(Request $request): JsonResponse
    {
        $user = $request->user();
        
        $orders = Order::with(['items.menu', 'payments.paymentMethod'])
                    ->where('customer_id', $user->id)
                    ->when($request->status, function ($q, $status) {
                        return $q->where('status', $status);
                    })
                    ->when($request->date_from && $request->date_to, function ($q) use ($request) {
                        return $q->whereBetween('created_at', [
                            $request->date_from . ' 00:00:00',
                            $request->date_to . ' 23:59:59'
                        ]);
                    })
                    ->when($request->order_type, function ($q, $type) {
                        return $q->where('order_type', $type);
                    })
                    ->orderBy('created_at', 'desc')
                    ->paginate($request->per_page ?? 10);

        // Get order statistics
        $stats = [
            'total' => Order::where('customer_id', $user->id)->count(),
            'pending' => Order::where('customer_id', $user->id)->where('status', 'pending')->count(),
            'preparing' => Order::where('customer_id', $user->id)->where('status', 'preparing')->count(),
            'ready' => Order::where('customer_id', $user->id)->where('status', 'ready')->count(),
            'completed' => Order::where('customer_id', $user->id)->where('status', 'completed')->count(),
            'cancelled' => Order::where('customer_id', $user->id)->where('status', 'cancelled')->count(),
        ];

        return $this->successResponse([
            'orders' => OrderResource::collection($orders),
            'pagination' => [
                'total' => $orders->total(),
                'per_page' => $orders->perPage(),
                'current_page' => $orders->currentPage(),
                'last_page' => $orders->lastPage(),
                'from' => $orders->firstItem(),
                'to' => $orders->lastItem(),
            ],
            'statistics' => $stats,
            'filters' => [
                'status' => $request->status,
                'date_from' => $request->date_from,
                'date_to' => $request->date_to,
                'order_type' => $request->order_type,
            ]
        ], 'Riwayat pesanan berhasil diambil');
    }

    /**
     * Get order detail
     * GET /api/customer/orders/{id}
     */
    public function show(Request $request, $id): JsonResponse
    {
        $order = Order::with(['items.menu', 'payments.paymentMethod'])
                    ->where('customer_id', $request->user()->id)
                    ->find($id);

        if (!$order) {
            return $this->errorResponse('Pesanan tidak ditemukan', 404);
        }

        // Get order timeline/status history
        $timeline = $this->getOrderTimeline($order);

        $response = new OrderResource($order);
        $responseData = $response->toArray($request);
        $responseData['timeline'] = $timeline;
        $responseData['next_possible_actions'] = $this->getNextPossibleActions($order);

        return $this->successResponse(
            $responseData,
            'Detail pesanan berhasil diambil'
        );
    }

    /**
     * Cancel order
     * POST /api/customer/orders/{id}/cancel
     */
    public function cancel(OrderCancelRequest $request, $id): JsonResponse
    {
        DB::beginTransaction();
        
        try {
            $order = Order::where('customer_id', $request->user()->id)
                        ->where('status', '!=', 'completed')
                        ->where('status', '!=', 'cancelled')
                        ->find($id);

            if (!$order) {
                return $this->errorResponse('Pesanan tidak dapat dibatalkan', 400);
            }

            if (!$order->canBeCancelled()) {
                return $this->errorResponse('Pesanan tidak dapat dibatalkan pada status ini', 400);
            }

            // Update order status
            $order->update([
                'status' => 'cancelled',
                'notes' => $order->notes . "\n[Dibatalkan: " . $request->reason . "]"
            ]);

            // Restore stock for all items
            foreach ($order->items as $item) {
                if ($item->menu) {
                    $item->menu->addStock($item->quantity);
                }
            }

            // Update payment status if exists
            $payment = $order->payments()->first();
            if ($payment) {
                $payment->update([
                    'status' => 'refunded',
                    'notes' => $request->reason . ' - Pesanan dibatalkan',
                ]);
            }

            DB::commit();

            return $this->successResponse(
                new OrderResource($order->fresh(['items.menu', 'payments'])),
                '✅ Pesanan berhasil dibatalkan. Stok telah dikembalikan.'
            );

        } catch (\Exception $e) {
            DB::rollBack();
            return $this->errorResponse('Gagal membatalkan pesanan: ' . $e->getMessage(), 500);
        }
    }

    /**
     * Get payment methods
     * GET /api/customer/payments/methods
     */
    public function getPaymentMethods(): JsonResponse
    {
        $paymentMethods = PaymentMethod::active()
            ->orderBy('name')
            ->get();

        return $this->successResponse(
            PaymentMethodResource::collection($paymentMethods),
            'Metode pembayaran berhasil diambil'
        );
    }

    /**
     * Get order timeline
     */
    private function getOrderTimeline(Order $order): array
    {
        $timeline = [];

        // Order created
        $timeline[] = [
            'status' => 'created',
            'title' => 'Pesanan dibuat',
            'description' => 'Pesanan Anda telah diterima sistem',
            'time' => $order->created_at->format('Y-m-d H:i:s'),
            'icon' => '📝',
            'completed' => true,
        ];

        // If confirmed
        if (in_array($order->status, ['confirmed', 'preparing', 'ready', 'completed'])) {
            $timeline[] = [
                'status' => 'confirmed',
                'title' => 'Pesanan dikonfirmasi',
                'description' => 'Pesanan Anda telah dikonfirmasi oleh restoran',
                'time' => $order->updated_at->format('Y-m-d H:i:s'),
                'icon' => '✅',
                'completed' => true,
            ];
        }

        // If preparing
        if (in_array($order->status, ['preparing', 'ready', 'completed'])) {
            $timeline[] = [
                'status' => 'preparing',
                'title' => 'Sedang disiapkan',
                'description' => 'Pesanan Anda sedang diproses di dapur',
                'time' => $order->updated_at->format('Y-m-d H:i:s'),
                'icon' => '👨‍🍳',
                'completed' => true,
            ];
        }

        // If ready
        if (in_array($order->status, ['ready', 'completed'])) {
            $timeline[] = [
                'status' => 'ready',
                'title' => 'Siap diambil',
                'description' => 'Pesanan Anda sudah siap',
                'time' => $order->updated_at->format('Y-m-d H:i:s'),
                'icon' => '📦',
                'completed' => true,
            ];
        }

        // If completed
        if ($order->status === 'completed') {
            $timeline[] = [
                'status' => 'completed',
                'title' => 'Selesai',
                'description' => 'Pesanan telah selesai',
                'time' => $order->completed_at?->format('Y-m-d H:i:s') ?? $order->updated_at->format('Y-m-d H:i:s'),
                'icon' => '🎉',
                'completed' => true,
            ];
        }

        // If cancelled
        if ($order->status === 'cancelled') {
            $timeline[] = [
                'status' => 'cancelled',
                'title' => 'Dibatalkan',
                'description' => 'Pesanan telah dibatalkan',
                'time' => $order->updated_at->format('Y-m-d H:i:s'),
                'icon' => '❌',
                'completed' => true,
            ];
        }

        // Add current pending status
        $currentStatus = [
            'pending' => ['title' => 'Menunggu konfirmasi', 'icon' => '⏳'],
            'confirmed' => ['title' => 'Terkonfirmasi', 'icon' => '✅'],
            'preparing' => ['title' => 'Sedang disiapkan', 'icon' => '👨‍🍳'],
            'ready' => ['title' => 'Siap diambil', 'icon' => '📦'],
            'completed' => ['title' => 'Selesai', 'icon' => '🎉'],
            'cancelled' => ['title' => 'Dibatalkan', 'icon' => '❌'],
        ];

        if (isset($currentStatus[$order->status]) && !in_array($order->status, ['completed', 'cancelled'])) {
            $timeline[] = [
                'status' => $order->status,
                'title' => $currentStatus[$order->status]['title'],
                'description' => 'Status saat ini',
                'time' => 'Sekarang',
                'icon' => $currentStatus[$order->status]['icon'],
                'completed' => false,
                'current' => true,
            ];
        }

        return $timeline;
    }

    /**
     * Get next possible actions for order
     */
    private function getNextPossibleActions(Order $order): array
    {
        $actions = [];

        // Cancel action
        if ($order->canBeCancelled()) {
            $actions[] = [
                'action' => 'cancel',
                'label' => 'Batalkan Pesanan',
                'description' => 'Batalkan pesanan ini',
                'icon' => '❌',
                'method' => 'POST',
                'url' => "/api/customer/orders/{$order->id}/cancel",
            ];
        }

        // Review action (if completed and not reviewed)
        if ($order->status === 'completed') {
            $hasReviewed = $order->items()->whereNotNull('rating')->exists();
            if (!$hasReviewed) {
                $actions[] = [
                    'action' => 'review',
                    'label' => 'Beri Ulasan',
                    'description' => 'Beri rating dan ulasan untuk pesanan ini',
                    'icon' => '⭐',
                    'method' => 'POST',
                    'url' => "/api/customer/orders/{$order->id}/review",
                ];
            }
        }

        // Reorder action
        if (in_array($order->status, ['completed', 'cancelled'])) {
            $actions[] = [
                'action' => 'reorder',
                'label' => 'Pesan Ulang',
                'description' => 'Pesan kembali item yang sama',
                'icon' => '🔄',
                'method' => 'POST',
                'url' => "/api/customer/orders/{$order->id}/reorder",
            ];
        }

        return $actions;
    }

    /**
     * Reorder from previous order
     * POST /api/customer/orders/{id}/reorder
     */
    public function reorder(Request $request, $id): JsonResponse
    {
        $user = $request->user();
        $order = Order::where('customer_id', $user->id)->find($id);

        if (!$order) {
            return $this->errorResponse('Pesanan tidak ditemukan', 404);
        }

        // Get current cart
        $cart = Cache::get("cart:{$user->id}", []);

        foreach ($order->items as $item) {
            $menu = Menu::available()->find($item->menu_id);
            
            if (!$menu) {
                continue;
            }

            // Check if already in cart
            $existingIndex = null;
            foreach ($cart as $index => $cartItem) {
                if ($cartItem['menu_id'] == $menu->id) {
                    $existingIndex = $index;
                    break;
                }
            }

            if ($existingIndex !== null) {
                // Update quantity
                $cart[$existingIndex]['quantity'] += $item->quantity;
            } else {
                // Add new item
                $cart[] = [
                    'menu_id' => $menu->id,
                    'quantity' => $item->quantity,
                    'notes' => $item->notes,
                    'added_at' => now()->toDateTimeString(),
                ];
            }
        }

        // Save updated cart
        Cache::put("cart:{$user->id}", $cart, now()->addDays(3));

        return $this->successResponse(
            ['item_count' => count($cart)],
            '✅ Item berhasil ditambahkan ke keranjang dari pesanan sebelumnya'
        );
    }
}