<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Models\Waste;
use App\Models\Outlet;
use App\Models\Ingredient;
use App\Models\Product;
use App\Models\OutletIngredient;
use App\Models\OutletProduct;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;

class WasteController extends Controller
{
    public function index(Request $request): Response
    {
        $user = $request->user();
        $outlets = Outlet::select('id', 'name')->get();
        
        $outletFilter = $request->input('outlet_id');
        $outletId = $user->outlet_id 
            ? (int)$user->outlet_id 
            : ($outletFilter 
                ? (int)$outletFilter 
                : ($outlets->first() ? $outlets->first()->id : null));

        $wastes = Waste::with(['outlet', 'user'])
            ->when($outletId, fn($q) => $q->where('outlet_id', $outletId))
            ->latest()
            ->paginate(15)
            ->withQueryString();

        $wastes->getCollection()->transform(function ($waste) {
            return [
                'id' => $waste->id,
                'outlet_id' => $waste->outlet_id,
                'outlet_name' => $waste->outlet ? $waste->outlet->name : 'Unknown',
                'user_name' => $waste->user ? $waste->user->name : 'Unknown',
                'item_type' => $waste->item_type,
                'item_id' => $waste->item_id,
                'name' => $waste->item ? $waste->item->name : 'Unknown',
                'qty' => (float)$waste->qty,
                'notes' => $waste->notes,
                'created_at' => $waste->created_at->format('Y-m-d H:i:s'),
            ];
        });
        
        $ingredients = Ingredient::select('id', 'name', 'unit')->get();
        $products = Product::select('id', 'name')->where('is_active', true)->get();

        return Inertia::render('CafePOS/Wastes/Index', [
            'wastes' => $wastes,
            'outlets' => $outlets,
            'ingredients' => $ingredients,
            'products' => $products,
            'filters' => [
                'outlet_id' => $outletId ? (string)$outletId : null,
            ]
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $request->validate([
            'outlet_id' => ['required', 'integer', 'exists:outlets,id'],
            'item_type' => ['required', 'string', 'in:Ingredient,Product'],
            'item_id' => ['required', 'integer'],
            'qty' => ['required', 'numeric', 'min:0.0001'],
            'notes' => ['nullable', 'string'],
        ]);

        $user = $request->user();
        $outletId = (int)$request->outlet_id;

        if ($user->outlet_id && (int)$user->outlet_id !== $outletId) {
            return redirect()->back()->with('error', 'Unauthorized outlet access.');
        }

        try {
            DB::transaction(function () use ($request, $outletId, $user) {
                $qty = (float)$request->qty;
                $itemId = (int)$request->item_id;

                // Check stock and deduct
                if ($request->item_type === 'Ingredient') {
                    $outletIng = OutletIngredient::where('outlet_id', $outletId)
                        ->where('ingredient_id', $itemId)
                        ->first();

                    if (!$outletIng || (float)$outletIng->stock_qty < $qty) {
                        throw new \Exception('Insufficient stock for this ingredient waste.');
                    }
                    $outletIng->decrement('stock_qty', $qty);
                } else {
                    $outletProd = OutletProduct::where('outlet_id', $outletId)
                        ->where('product_id', $itemId)
                        ->first();

                    if (!$outletProd || (float)$outletProd->stock_qty < $qty) {
                        throw new \Exception('Insufficient stock for this product waste.');
                    }
                    $outletProd->decrement('stock_qty', $qty);
                }

                Waste::create([
                    'outlet_id' => $outletId,
                    'user_id' => $user->id,
                    'item_type' => $request->item_type,
                    'item_id' => $itemId,
                    'qty' => $qty,
                    'notes' => $request->notes,
                ]);
            });

            return redirect()->back()->with('success', 'Stock waste recorded successfully.');
        } catch (\Exception $e) {
            return redirect()->back()->with('error', $e->getMessage());
        }
    }

    public function destroy(Waste $waste): RedirectResponse
    {
        // Revert stock when waste record is deleted
        try {
            DB::transaction(function () use ($waste) {
                if ($waste->item_type === 'Ingredient') {
                    $outletIng = OutletIngredient::where('outlet_id', $waste->outlet_id)
                        ->where('ingredient_id', $waste->item_id)
                        ->first();
                    if ($outletIng) {
                        $outletIng->increment('stock_qty', $waste->qty);
                    }
                } else {
                    $outletProd = OutletProduct::where('outlet_id', $waste->outlet_id)
                        ->where('product_id', $waste->item_id)
                        ->first();
                    if ($outletProd) {
                        $outletProd->increment('stock_qty', $waste->qty);
                    }
                }
                $waste->delete();
            });

            return redirect()->back()->with('success', 'Waste record deleted and stock reverted.');
        } catch (\Exception $e) {
            return redirect()->back()->with('error', $e->getMessage());
        }
    }
}
