<?php

namespace App\Http\Controllers;

use App\Models\KitchenIssuance;
use App\Models\KitchenIssuanceItem;
use App\Models\InventoryItem;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;

class KitchenIssuanceController extends Controller
{
    /**
     * Get all kitchen issuances
     */
    public function index(Request $request): JsonResponse
    {
        $query = KitchenIssuance::with([
            'items.inventoryItem',
            'issuedBy:id,name',
            'receivedBy:id,name',
            'branch:id,name'
        ])
        ->where('restaurant_id', $request->user()->restaurant_id);

        // Filter by branch
        if ($request->branch_id) {
            $query->where('branch_id', $request->branch_id);
        } elseif ($request->user()->branch_id) {
            $query->where('branch_id', $request->user()->branch_id);
        }

        // Filter by status
        if ($request->status) {
            $query->where('status', $request->status);
        }

        // Filter by date range
        if ($request->start_date && $request->end_date) {
            $query->whereBetween('issued_at', [
                $request->start_date . ' 00:00:00',
                $request->end_date . ' 23:59:59'
            ]);
        }

        // Search
        if ($request->search) {
            $query->where(function($q) use ($request) {
                $q->where('issuance_number', 'like', '%' . $request->search . '%')
                  ->orWhere('notes', 'like', '%' . $request->search . '%');
            });
        }

        $issuances = $query->orderBy('issued_at', 'desc')
            ->paginate($request->per_page ?? 50);

        return response()->json($issuances);
    }

    /**
     * Create a new kitchen issuance
     */
    public function store(Request $request): JsonResponse
    {
        $request->validate([
            'items' => 'required|array|min:1',
            'items.*.inventory_item_id' => 'required|exists:inventory_items,id',
            'items.*.quantity' => 'required|numeric|min:0.001',
            'notes' => 'nullable|string',
        ]);

        DB::beginTransaction();
        try {
            // Create issuance
            $issuance = KitchenIssuance::create([
                'restaurant_id' => $request->user()->restaurant_id,
                'branch_id' => $request->branch_id ?? $request->user()->branch_id,
                'issued_by' => $request->user()->id,
                'status' => 'pending',
                'notes' => $request->notes,
                'issued_at' => now(),
            ]);

            // Add items and adjust inventory
            foreach ($request->items as $itemData) {
                $inventoryItem = InventoryItem::findOrFail($itemData['inventory_item_id']);

                // Check if sufficient stock
                if ($inventoryItem->current_stock < $itemData['quantity']) {
                    throw new \Exception("Insufficient stock for {$inventoryItem->name}. Available: {$inventoryItem->current_stock} {$inventoryItem->unit}");
                }

                // Create issuance item
                $issuanceItem = $issuance->items()->create([
                    'inventory_item_id' => $inventoryItem->id,
                    'quantity' => $itemData['quantity'],
                    'unit' => $inventoryItem->unit,
                    'unit_cost' => $inventoryItem->cost_per_unit,
                    'total_cost' => $itemData['quantity'] * $inventoryItem->cost_per_unit,
                    'notes' => $itemData['notes'] ?? null,
                ]);

                // Adjust inventory stock
                $inventoryItem->adjustStock(
                    -$itemData['quantity'],
                    'kitchen_issuance',
                    $issuance->issuance_number,
                    "Issued to kitchen - {$issuance->issuance_number}",
                    $request->user()
                );
            }

            DB::commit();

            return response()->json([
                'message' => 'Kitchen issuance created successfully',
                'issuance' => $issuance->load([
                    'items.inventoryItem',
                    'issuedBy:id,name',
                    'branch:id,name'
                ]),
            ], 201);

        } catch (\Exception $e) {
            DB::rollback();
            return response()->json(['error' => $e->getMessage()], 400);
        }
    }

    /**
     * Get a single kitchen issuance
     */
    public function show(KitchenIssuance $issuance): JsonResponse
    {
        $issuance->load([
            'items.inventoryItem',
            'issuedBy:id,name,role',
            'receivedBy:id,name,role',
            'branch:id,name'
        ]);

        return response()->json($issuance);
    }

    /**
     * Mark issuance as received
     */
    public function receive(Request $request, KitchenIssuance $issuance): JsonResponse
    {
        if ($issuance->status !== 'pending') {
            return response()->json([
                'error' => 'Only pending issuances can be received'
            ], 400);
        }

        $issuance->update([
            'status' => 'received',
            'received_by' => $request->user()->id,
            'received_at' => now(),
        ]);

        return response()->json([
            'message' => 'Issuance marked as received',
            'issuance' => $issuance->load([
                'items.inventoryItem',
                'issuedBy:id,name',
                'receivedBy:id,name'
            ]),
        ]);
    }

    /**
     * Cancel an issuance and restore inventory
     */
    public function cancel(Request $request, KitchenIssuance $issuance): JsonResponse
    {
        if ($issuance->status !== 'pending') {
            return response()->json([
                'error' => 'Only pending issuances can be cancelled'
            ], 400);
        }

        DB::beginTransaction();
        try {
            // Restore inventory for each item
            foreach ($issuance->items as $item) {
                $inventoryItem = $item->inventoryItem;
                
                $inventoryItem->adjustStock(
                    $item->quantity,
                    'kitchen_issuance_cancelled',
                    $issuance->issuance_number,
                    "Issuance cancelled - {$issuance->issuance_number}",
                    $request->user()
                );
            }

            // Update issuance status
            $issuance->update(['status' => 'cancelled']);

            DB::commit();

            return response()->json([
                'message' => 'Issuance cancelled and inventory restored',
                'issuance' => $issuance->load([
                    'items.inventoryItem',
                    'issuedBy:id,name'
                ]),
            ]);

        } catch (\Exception $e) {
            DB::rollback();
            return response()->json(['error' => $e->getMessage()], 400);
        }
    }

    /**
     * Get issuance summary/statistics
     */
    public function summary(Request $request): JsonResponse
    {
        $query = KitchenIssuance::where('restaurant_id', $request->user()->restaurant_id);

        if ($request->branch_id) {
            $query->where('branch_id', $request->branch_id);
        } elseif ($request->user()->branch_id) {
            $query->where('branch_id', $request->user()->branch_id);
        }

        // Filter by date range only if provided
        if ($request->start_date && $request->end_date) {
            $query->whereBetween('issued_at', [
                $request->start_date . ' 00:00:00',
                $request->end_date . ' 23:59:59'
            ]);
        }

        $allIssuances = $query->with('items')->get();

        $summary = [
            'total_issuances' => $allIssuances->count(),
            'pending_issuances' => $allIssuances->where('status', 'pending')->count(),
            'received_issuances' => $allIssuances->where('status', 'received')->count(),
            'cancelled_issuances' => $allIssuances->where('status', 'cancelled')->count(),
            'total_value' => $allIssuances->sum('total_cost'),
            'formatted_total_value' => 'KES ' . number_format($allIssuances->sum('total_cost'), 2),
            'total_items_issued' => $allIssuances->sum('total_items'),
            'today' => [
                'count' => $allIssuances->where('issued_at', '>=', today())->count(),
                'value' => $allIssuances->where('issued_at', '>=', today())->sum('total_cost'),
                'formatted_value' => 'KES ' . number_format($allIssuances->where('issued_at', '>=', today())->sum('total_cost'), 2),
            ],
            'this_week' => [
                'count' => $allIssuances->where('issued_at', '>=', now()->startOfWeek())->count(),
                'value' => $allIssuances->where('issued_at', '>=', now()->startOfWeek())->sum('total_cost'),
                'formatted_value' => 'KES ' . number_format($allIssuances->where('issued_at', '>=', now()->startOfWeek())->sum('total_cost'), 2),
            ],
        ];

        return response()->json($summary);
    }

    /**
     * Get most issued items
     */
    public function topIssuedItems(Request $request): JsonResponse
    {
        $query = KitchenIssuanceItem::with('inventoryItem')
            ->whereHas('kitchenIssuance', function($q) use ($request) {
                $q->where('restaurant_id', $request->user()->restaurant_id);
                
                if ($request->branch_id) {
                    $q->where('branch_id', $request->branch_id);
                } elseif ($request->user()->branch_id) {
                    $q->where('branch_id', $request->user()->branch_id);
                }

                // Filter by date range only if provided
                if ($request->start_date && $request->end_date) {
                    $q->whereBetween('issued_at', [
                        $request->start_date . ' 00:00:00',
                        $request->end_date . ' 23:59:59'
                    ]);
                }
            });

        $topItems = $query->select('inventory_item_id')
            ->selectRaw('SUM(quantity) as total_quantity')
            ->selectRaw('SUM(total_cost) as total_cost')
            ->selectRaw('COUNT(*) as issuance_count')
            ->groupBy('inventory_item_id')
            ->orderBy('total_quantity', 'desc')
            ->limit($request->limit ?? 10)
            ->get()
            ->map(function($item) {
                return [
                    'inventory_item' => $item->inventoryItem,
                    'total_quantity' => $item->total_quantity,
                    'formatted_quantity' => number_format($item->total_quantity, 3) . ' ' . $item->inventoryItem->unit,
                    'total_cost' => $item->total_cost,
                    'formatted_cost' => 'KES ' . number_format($item->total_cost, 2),
                    'issuance_count' => $item->issuance_count,
                ];
            });

        return response()->json($topItems);
    }
}
