<?php
namespace App\Http\Controllers\Api\Customer;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Customer\CartRequest;
use App\Http\Resources\Api\Customer\CartResource;
use App\Models\Menu;
use App\Traits\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;

class CartController extends Controller
{
    use ApiResponse;

    /**
     * Get cart items
     * GET /api/customer/cart
     */
    public function index(Request $request): JsonResponse
    {
        $cart = $this->getCart($request->user()->id);
        $total = 0;
        $itemCount = 0;
        $availableItems = 0;
        $unavailableItems = 0;

        // Format cart items with menu details
        $formattedItems = [];
        foreach ($cart as $item) {
            $menu = Menu::with('category')->find($item['menu_id']);
            
            if ($menu) {
                $subtotal = $item['quantity'] * $menu->price;
                $total += $subtotal;
                $itemCount++;
                
                // Check availability
                $isAvailable = $menu->is_available && $menu->stock >= $item['quantity'];
                if ($isAvailable) {
                    $availableItems++;
                } else {
                    $unavailableItems++;
                }

                $formattedItems[] = [
                    'menu_id' => $item['menu_id'],
                    'menu' => [
                        'id' => $menu->id,
                        'name' => $menu->name,
                        'description' => $menu->description,
                        'price' => (float) $menu->price,
                        'formatted_price' => 'Rp ' . number_format($menu->price, 0, ',', '.'),
                        'image_url' => $menu->image_url,
                        'is_available' => $menu->is_available,
                        'stock' => $menu->stock,
                        'category' => $menu->category ? [
                            'id' => $menu->category->id,
                            'name' => $menu->category->name,
                        ] : null,
                    ],
                    'quantity' => $item['quantity'],
                    'notes' => $item['notes'] ?? null,
                    'subtotal' => (float) $subtotal,
                    'formatted_subtotal' => 'Rp ' . number_format($subtotal, 0, ',', '.'),
                    'is_available' => $isAvailable,
                    'availability_message' => $this->getItemAvailabilityMessage($menu, $item['quantity']),
                    'added_at' => $item['added_at'] ?? null,
                ];
            }
        }

        return $this->successResponse([
            'items' => $formattedItems,
            'summary' => [
                'total_items' => $itemCount,
                'total_quantity' => array_sum(array_column($cart, 'quantity')),
                'subtotal' => (float) $total,
                'formatted_subtotal' => 'Rp ' . number_format($total, 0, ',', '.'),
                'available_items' => $availableItems,
                'unavailable_items' => $unavailableItems,
                'can_checkout' => $availableItems > 0 && $unavailableItems === 0,
            ]
        ], 'Keranjang berhasil diambil');
    }

    /**
     * Add item to cart
     * POST /api/customer/cart
     */
    public function store(CartRequest $request): JsonResponse
    {
        $user = $request->user();
        $menu = Menu::available()->find($request->menu_id);

        if (!$menu) {
            return $this->errorResponse('Menu tidak tersedia', 404);
        }

        if ($menu->stock < $request->quantity) {
            return $this->errorResponse(
                'Stok tidak mencukupi. Stok tersedia: ' . $menu->stock, 
                400
            );
        }

        $cart = $this->getCart($user->id);
        $existingIndex = $this->findCartItemIndex($cart, $request->menu_id);

        if ($existingIndex !== false) {
            // Update quantity
            $newQuantity = $cart[$existingIndex]['quantity'] + $request->quantity;
            
            if ($menu->stock < $newQuantity) {
                return $this->errorResponse(
                    'Stok tidak mencukupi untuk menambah jumlah. Stok tersedia: ' . $menu->stock, 
                    400
                );
            }
            
            $cart[$existingIndex]['quantity'] = $newQuantity;
            $cart[$existingIndex]['notes'] = $request->notes ?? $cart[$existingIndex]['notes'];
            $cart[$existingIndex]['updated_at'] = now()->toDateTimeString();
        } else {
            // Add new item
            $cart[] = [
                'menu_id' => $menu->id,
                'quantity' => $request->quantity,
                'notes' => $request->notes ?? null,
                'added_at' => now()->toDateTimeString(),
                'updated_at' => now()->toDateTimeString(),
            ];
        }

        $this->saveCart($user->id, $cart);

        return $this->successResponse(
            $this->getFormattedCart($user->id),
            $existingIndex !== false ? 'Keranjang diperbarui' : 'Item ditambahkan ke keranjang'
        );
    }

    /**
     * Update cart item
     * PUT /api/customer/cart/{menu_id}
     */
    public function update(CartRequest $request, $menuId): JsonResponse
    {
        $user = $request->user();
        $cart = $this->getCart($user->id);
        $index = $this->findCartItemIndex($cart, $menuId);

        if ($index === false) {
            return $this->errorResponse('Item tidak ditemukan di keranjang', 404);
        }

        $menu = Menu::find($menuId);
        if (!$menu) {
            return $this->errorResponse('Menu tidak ditemukan', 404);
        }

        if (!$menu->is_available) {
            return $this->errorResponse('Menu tidak tersedia', 400);
        }

        if ($menu->stock < $request->quantity) {
            return $this->errorResponse(
                'Stok tidak mencukupi. Stok tersedia: ' . $menu->stock, 
                400
            );
        }

        $cart[$index]['quantity'] = $request->quantity;
        $cart[$index]['updated_at'] = now()->toDateTimeString();
        
        if ($request->has('notes')) {
            $cart[$index]['notes'] = $request->notes;
        }

        $this->saveCart($user->id, $cart);

        return $this->successResponse(
            $this->getFormattedCart($user->id),
            'Item keranjang berhasil diperbarui'
        );
    }

    /**
     * Remove item from cart
     * DELETE /api/customer/cart/{menu_id}
     */
    public function destroy(Request $request, $menuId): JsonResponse
    {
        $user = $request->user();
        $cart = $this->getCart($user->id);
        $index = $this->findCartItemIndex($cart, $menuId);

        if ($index === false) {
            return $this->errorResponse('Item tidak ditemukan di keranjang', 404);
        }

        // Store item info for response message
        $item = $cart[$index];
        $menu = Menu::find($menuId);
        $itemName = $menu ? $menu->name : 'Item';

        array_splice($cart, $index, 1);
        $this->saveCart($user->id, $cart);

        return $this->successResponse(
            $this->getFormattedCart($user->id),
            "{$itemName} berhasil dihapus dari keranjang"
        );
    }

    /**
     * Clear cart
     * DELETE /api/customer/cart
     */
    public function clear(Request $request): JsonResponse
    {
        $user = $request->user();
        $cart = $this->getCart($user->id);
        $itemCount = count($cart);
        
        $this->saveCart($user->id, []);

        return $this->successResponse(
            [],
            "Keranjang berhasil dikosongkan. {$itemCount} item dihapus."
        );
    }

    // ==================== HELPER METHODS ====================

    /**
     * Get cart from cache
     */
    private function getCart($userId): array
    {
        return Cache::get("cart:{$userId}", []);
    }

    /**
     * Save cart to cache
     */
    private function saveCart($userId, array $cart): void
    {
        Cache::put("cart:{$userId}", $cart, now()->addDays(3)); // Cart expires in 3 days
    }

    /**
     * Find cart item index by menu_id
     */
    private function findCartItemIndex(array $cart, $menuId)
    {
        foreach ($cart as $index => $item) {
            if ($item['menu_id'] == $menuId) {
                return $index;
            }
        }
        return false;
    }

    /**
     * Get formatted cart with menu details
     */
    private function getFormattedCart($userId): array
    {
        $cart = $this->getCart($userId);
        $total = 0;
        $items = [];
        $availableItems = 0;
        $unavailableItems = 0;

        foreach ($cart as $item) {
            $menu = Menu::find($item['menu_id']);
            if ($menu) {
                $subtotal = $item['quantity'] * $menu->price;
                $total += $subtotal;
                
                $isAvailable = $menu->is_available && $menu->stock >= $item['quantity'];
                if ($isAvailable) {
                    $availableItems++;
                } else {
                    $unavailableItems++;
                }

                $items[] = [
                    'menu' => [
                        'id' => $menu->id,
                        'name' => $menu->name,
                        'price' => (float) $menu->price,
                        'formatted_price' => 'Rp ' . number_format($menu->price, 0, ',', '.'),
                        'image_url' => $menu->image_url,
                        'is_available' => $menu->is_available,
                        'stock' => $menu->stock,
                    ],
                    'quantity' => $item['quantity'],
                    'notes' => $item['notes'] ?? null,
                    'subtotal' => (float) $subtotal,
                    'formatted_subtotal' => 'Rp ' . number_format($subtotal, 0, ',', '.'),
                    'is_available' => $isAvailable,
                    'availability_message' => $this->getItemAvailabilityMessage($menu, $item['quantity']),
                ];
            }
        }

        return [
            'items' => $items,
            'summary' => [
                'total_items' => count($items),
                'total_quantity' => array_sum(array_column($cart, 'quantity')),
                'subtotal' => (float) $total,
                'formatted_subtotal' => 'Rp ' . number_format($total, 0, ',', '.'),
                'available_items' => $availableItems,
                'unavailable_items' => $unavailableItems,
                'can_checkout' => $availableItems > 0 && $unavailableItems === 0,
            ]
        ];
    }

    /**
     * Get availability message for cart item
     */
    private function getItemAvailabilityMessage(Menu $menu, $quantity): string
    {
        if (!$menu->is_available) {
            return 'Menu tidak tersedia';
        }
        
        if ($menu->stock < $quantity) {
            return "Stok tidak mencukupi (tersedia: {$menu->stock})";
        }
        
        return 'Tersedia';
    }

    /**
     * Check if cart can proceed to checkout
     * Optional: Public method to check checkout eligibility
     */
    public function checkCheckout(Request $request): JsonResponse
    {
        $formattedCart = $this->getFormattedCart($request->user()->id);
        
        return $this->successResponse([
            'can_checkout' => $formattedCart['summary']['can_checkout'],
            'summary' => $formattedCart['summary'],
            'unavailable_items' => array_filter($formattedCart['items'], function ($item) {
                return !$item['is_available'];
            }),
        ], 'Checkout eligibility check');
    }
}