<?php

namespace App\Http\Controllers\Epelcon;

use App\Http\Controllers\Controller;
use App\Models\ActivityLog;
use App\Models\InventoryItem;
use App\Models\StockMovement;
use App\Models\Supplier;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class InventoryController extends Controller
{
    public function index(Request $request)
    {
        $items = InventoryItem::with('supplier')
            ->when($request->filled('location'), fn ($q) => $q->where('location', $request->location))
            ->when($request->filled('q'), fn ($q) => $q->where(fn ($w) => $w->where('name', 'like', '%' . $request->q . '%')->orWhere('sku', 'like', '%' . $request->q . '%')))
            ->when($request->input('filter') === 'low', fn ($q) => $q->whereColumn('quantity', '<=', 'reorder_level'))
            ->orderBy('name')
            ->paginate(20)->withQueryString();

        $summary = [
            'items' => InventoryItem::count(),
            'low' => InventoryItem::whereColumn('quantity', '<=', 'reorder_level')->count(),
            'value' => (float) InventoryItem::selectRaw('COALESCE(SUM(quantity * cost_price), 0) as v')->value('v'),
            'expiring' => InventoryItem::whereNotNull('expiry_date')->whereBetween('expiry_date', [today(), today()->addDays(30)])->count(),
        ];

        $suppliers = Supplier::where('status', 'active')->orderBy('name')->get(['id', 'name']);

        return view('epelcon.inventory.index', compact('items', 'summary', 'suppliers'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'name' => 'required|string|max:120',
            'category' => 'nullable|string|max:60',
            'unit' => 'required|string|max:20',
            'quantity' => 'required|numeric|min:0',
            'reorder_level' => 'required|numeric|min:0',
            'cost_price' => 'required|numeric|min:0',
            'selling_price' => 'nullable|numeric|min:0',
            'supplier_id' => 'nullable|exists:suppliers,id',
            'location' => 'required|in:main_store,kitchen,bar,housekeeping',
            'expiry_date' => 'nullable|date',
        ]);

        $data['sku'] = 'SKU-' . strtoupper(Str::random(6));

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

        if ((float) $data['quantity'] > 0) {
            StockMovement::create([
                'inventory_item_id' => $item->id,
                'type' => 'in',
                'quantity' => $data['quantity'],
                'to_location' => $data['location'],
                'reference' => 'Opening stock',
                'user_id' => auth()->id(),
            ]);
        }

        ActivityLog::record('created inventory item', 'inventory', $data['name']);

        return back()->with('success', "“{$data['name']}” added to inventory.");
    }

    public function update(Request $request, InventoryItem $item)
    {
        $data = $request->validate([
            'name' => 'required|string|max:120',
            'category' => 'nullable|string|max:60',
            'unit' => 'required|string|max:20',
            'reorder_level' => 'required|numeric|min:0',
            'cost_price' => 'required|numeric|min:0',
            'selling_price' => 'nullable|numeric|min:0',
            'supplier_id' => 'nullable|exists:suppliers,id',
            'location' => 'required|in:main_store,kitchen,bar,housekeeping',
            'expiry_date' => 'nullable|date',
        ]);

        $item->update($data);

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

    public function recordMovement(Request $request, InventoryItem $item)
    {
        $data = $request->validate([
            'type' => 'required|in:in,out,adjustment,transfer',
            'quantity' => 'required|numeric|min:0.01',
            'to_location' => 'nullable|in:main_store,kitchen,bar,housekeeping',
            'reference' => 'nullable|string|max:120',
            'notes' => 'nullable|string',
        ]);

        $qty = (float) $data['quantity'];

        if (in_array($data['type'], ['out']) && $qty > (float) $item->quantity) {
            return back()->with('error', 'Not enough stock. Available: ' . $item->quantity . ' ' . $item->unit);
        }

        match ($data['type']) {
            'in' => $item->increment('quantity', $qty),
            'out' => $item->decrement('quantity', $qty),
            'adjustment' => $item->update(['quantity' => $qty]),
            'transfer' => $item->update(['location' => $data['to_location'] ?? $item->location]),
        };

        StockMovement::create([
            'inventory_item_id' => $item->id,
            'type' => $data['type'],
            'quantity' => $qty,
            'from_location' => $item->getOriginal('location'),
            'to_location' => $data['to_location'] ?? $item->location,
            'reference' => $data['reference'] ?? null,
            'notes' => $data['notes'] ?? null,
            'user_id' => auth()->id(),
        ]);

        ActivityLog::record('stock ' . $data['type'], 'inventory', "{$item->name}: {$qty} {$item->unit}");

        return back()->with('success', 'Stock movement recorded.');
    }

    public function movements(Request $request)
    {
        $movements = StockMovement::with(['item', 'user'])
            ->when($request->filled('type'), fn ($q) => $q->where('type', $request->type))
            ->latest()
            ->paginate(25)->withQueryString();

        return view('epelcon.inventory.movements', compact('movements'));
    }
}
