<?php

namespace App\Http\Controllers\Epelcon;

use App\Http\Controllers\Controller;
use App\Models\ActivityLog;
use App\Models\KitchenStockItem;
use App\Models\KitchenStockLog;
use App\Models\MenuItem;
use Illuminate\Http\Request;

class KitchenStockController extends Controller
{
    private const LOCATIONS = [
        'fridge' => 'Fridge',
        'freezer' => 'Freezer',
        'pot' => 'Pot / Stove',
        'store' => 'Dry store',
        'shelf' => 'Shelf',
        'prep' => 'Prepped',
    ];

    private const UNITS = ['portions', 'litres', 'kg', 'pcs', 'bowls'];

    private const CATEGORIES = ['Soups', 'Proteins', 'Grains', 'Vegetables', 'Dairy', 'Other'];

    public function index(Request $request)
    {
        $items = KitchenStockItem::with('menuItem')
            ->when($request->filled('location'), fn ($q) => $q->where('location', $request->location))
            ->when($request->filled('q'), fn ($q) => $q->where('name', 'like', '%' . $request->q . '%'))
            ->orderBy('name')
            ->get();

        $summary = [
            'items' => KitchenStockItem::count(),
            'low' => KitchenStockItem::where('par_level', '>', 0)->whereColumn('quantity', '<=', 'par_level')->count(),
            'portions_ready' => (float) KitchenStockItem::where('unit', 'portions')->sum('quantity'),
            'out' => KitchenStockItem::where('quantity', '<=', 0)->count(),
        ];

        $grouped = $items->groupBy('location');

        $menuItems = MenuItem::orderBy('name')->get(['id', 'name']);

        return view('epelcon.kitchenstock.index', [
            'grouped' => $grouped,
            'summary' => $summary,
            'menuItems' => $menuItems,
            'locations' => self::LOCATIONS,
            'units' => self::UNITS,
            'categories' => self::CATEGORIES,
        ]);
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'name' => 'required|string|max:120',
            'category' => 'nullable|in:' . implode(',', self::CATEGORIES),
            'location' => 'required|in:' . implode(',', array_keys(self::LOCATIONS)),
            'unit' => 'required|in:' . implode(',', self::UNITS),
            'quantity' => 'required|numeric|min:0',
            'par_level' => 'required|numeric|min:0',
            'menu_item_id' => 'nullable|exists:menu_items,id',
            'notes' => 'nullable|string|max:255',
        ]);

        $item = KitchenStockItem::create($data);

        KitchenStockLog::create([
            'kitchen_stock_item_id' => $item->id,
            'user_id' => auth()->id(),
            'change_type' => 'set',
            'quantity_before' => 0,
            'quantity_after' => $item->quantity,
            'reason' => 'Opening stock',
        ]);

        ActivityLog::record('added kitchen stock', 'kitchen', $item->name);

        return back()->with('success', "“{$item->name}” added to kitchen stock.");
    }

    public function update(KitchenStockItem $item, Request $request)
    {
        $data = $request->validate([
            'name' => 'required|string|max:120',
            'category' => 'nullable|in:' . implode(',', self::CATEGORIES),
            'location' => 'required|in:' . implode(',', array_keys(self::LOCATIONS)),
            'unit' => 'required|in:' . implode(',', self::UNITS),
            'par_level' => 'required|numeric|min:0',
            'menu_item_id' => 'nullable|exists:menu_items,id',
            'notes' => 'nullable|string|max:255',
        ]);

        $item->update($data);

        return back()->with('success', 'Item updated.');
    }

    public function adjust(KitchenStockItem $item, Request $request)
    {
        $data = $request->validate([
            'change_type' => 'required|in:set,add,deduct,waste',
            'quantity' => 'required|numeric|min:0.01',
            'reason' => 'nullable|string|max:255',
        ]);

        $before = (float) $item->quantity;
        $qty = (float) $data['quantity'];

        $after = match ($data['change_type']) {
            'set' => $qty,
            'add' => $before + $qty,
            'deduct', 'waste' => max(0, $before - $qty),
        };

        KitchenStockLog::create([
            'kitchen_stock_item_id' => $item->id,
            'user_id' => auth()->id(),
            'change_type' => $data['change_type'],
            'quantity_before' => $before,
            'quantity_after' => $after,
            'reason' => $data['reason'] ?? null,
        ]);

        $item->update(['quantity' => $after]);

        ActivityLog::record('kitchen stock ' . $data['change_type'], 'kitchen', "{$item->name}: {$before} → {$after} {$item->unit}");

        return back()->with('success', "{$item->name} updated to " . ($after + 0) . " {$item->unit}.");
    }

    public function shiftReport(Request $request)
    {
        $grouped = KitchenStockItem::orderBy('name')->get()->groupBy('location');

        $logs = KitchenStockLog::with(['item', 'user'])->latest()->limit(30)->get();

        return view('epelcon.kitchenstock.shift', [
            'grouped' => $grouped,
            'logs' => $logs,
            'locations' => self::LOCATIONS,
        ]);
    }

    public function logs(Request $request)
    {
        $logs = KitchenStockLog::with(['item', 'user'])
            ->when($request->filled('item'), fn ($q) => $q->where('kitchen_stock_item_id', $request->item))
            ->latest()
            ->paginate(30)->withQueryString();

        $items = KitchenStockItem::orderBy('name')->get(['id', 'name']);

        return view('epelcon.kitchenstock.logs', compact('logs', 'items'));
    }
}
