<?php

namespace App\Http\Controllers;

use App\Models\Branch;
use App\Models\Purchase;
use App\Models\Supplier;
use App\Models\Warehouse;
use App\Services\PurchaseService;
use Illuminate\Http\Request;

class PurchaseController extends Controller
{
    public function __construct(private PurchaseService $purchases) {}

    public function index(Request $request)
    {
        $purchases = Purchase::with(['supplier', 'warehouse'])
            ->when($request->filled('q'), fn ($q) => $q->where(fn ($sub) => $sub->where('purchase_no', 'like', '%'.$request->q.'%')->orWhere('supplier_invoice_no', 'like', '%'.$request->q.'%')->orWhereHas('supplier', fn ($supplier) => $supplier->where('name_en', 'like', '%'.$request->q.'%'))))
            ->when($request->filled('status'), fn ($q) => $q->where('status', $request->status))
            ->latest('purchase_date')->latest('id')->paginate(30)->withQueryString();
        return view('purchases.index', compact('purchases'));
    }

    public function create()
    {
        $suppliers = Supplier::where('status', 'active')->orderBy('name_en')->limit(200)->get();
        $warehouses = Warehouse::where('status', 'active')->where('type', '!=', 'van')->orderBy('name_en')->get();
        $branches = Branch::where('status', 'active')->orderBy('name_en')->get();
        return view('purchases.create', compact('suppliers', 'warehouses', 'branches'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'supplier_id' => 'required|exists:suppliers,id', 'warehouse_id' => 'required|exists:warehouses,id',
            'branch_id' => 'nullable|exists:branches,id', 'purchase_date' => 'required|date',
            'supplier_invoice_no' => 'nullable|string|max:100', 'payment_type' => 'required|in:cash,credit,bank,card,transfer,mixed',
            'reference' => 'nullable|string|max:100', 'po_reference' => 'nullable|string|max:100', 'notes' => 'nullable|string|max:2000',
            'action' => 'required|in:hold,finalize', 'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id', 'items.*.unit_id' => 'nullable|exists:units,id',
            'items.*.quantity' => 'required|numeric|gt:0', 'items.*.free_quantity' => 'nullable|numeric|min:0',
            'items.*.unit_cost' => 'required|numeric|min:0', 'items.*.vat_rate' => 'required|numeric|min:0|max:100',
            'items.*.discount_type' => 'nullable|in:fixed,percentage', 'items.*.discount_value' => 'nullable|numeric|min:0',
            'items.*.batch_number' => 'nullable|string|max:100', 'items.*.expiry_date' => 'nullable|date',
            'payments' => 'nullable|array', 'payments.*.payment_method' => 'required_with:payments|in:cash,bank,card,transfer',
            'payments.*.amount' => 'required_with:payments|numeric|min:0', 'payments.*.reference' => 'nullable|string|max:100',
        ]);
        try {
            $purchase = $this->purchases->createDraft($data, $data['items'], $data['payments'] ?? []);
            if ($data['action'] === 'finalize') $purchase = $this->purchases->finalize($purchase);
            return redirect()->route('purchases.show', $purchase)->with('success', $purchase->status === 'draft' ? 'Purchase held as draft.' : 'Purchase finalized successfully.');
        } catch (\Throwable $e) { report($e); return back()->withInput()->with('error', $e->getMessage()); }
    }

    public function show(Purchase $purchase)
    {
        $purchase->load(['supplier', 'warehouse', 'items.product', 'payments', 'returns']);
        return view('purchases.show', compact('purchase'));
    }

    public function finalize(Purchase $purchase)
    {
        try { $this->purchases->finalize($purchase); return back()->with('success', 'Purchase finalized successfully.'); }
        catch (\Throwable $e) { report($e); return back()->with('error', $e->getMessage()); }
    }
}
