<?php

namespace App\Http\Controllers;

use App\Models\Currency;
use App\Models\Customer;
use App\Models\FuelQuality;
use App\Models\FuelType;
use App\Models\Purchase;
use App\Models\PurchaseItem;
use App\Models\StockLedger;
use App\Models\Supplier;
use App\Models\Tank;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class PurchaseController extends Controller
{
    public function index(Request $request)
    {
        $purchases = Purchase::with(['supplier','currency','items.fuelType'])->latest()->paginate(20);
        return view('purchases.index', compact('purchases'));
    }

    public function create()
    {
        return view('purchases.create', [
            'suppliers' => Supplier::all(),
            'customers' => Customer::where('is_active', true)->get(),
            'currencies' => Currency::where('is_active', true)->get(),
            'fuelTypes' => FuelType::where('is_active', true)->get(),
            'qualities' => FuelQuality::where('is_active', true)->get(),
            'tanks' => Tank::with('fuelType')->where('is_active', true)->get(),
        ]);
    }

    public function store(Request $request)
    {
        $request->validate([
            'purchase_date' => ['required','date'],
            'supplier_id' => ['required','exists:suppliers,id'],
            'currency_id' => ['required','exists:currencies,id'],
            'fuel_type_id' => ['required','exists:fuel_types,id'],
            'tank_id' => ['required','exists:tanks,id'],
            'owner_type' => ['required','in:own,customer'],
            'customer_id' => ['nullable','required_if:owner_type,customer','exists:customers,id'],
            'quantity' => ['required','numeric','min:0.001'],
            // Purchase price is taken from fuel_types.purchase_price. Simple users do not enter price.
            'paid_amount' => ['required','numeric','min:0'],
        ]);

        try {
            DB::transaction(function () use ($request) {
                $tank = Tank::lockForUpdate()->findOrFail($request->tank_id);
                if ((int)$tank->fuel_type_id !== (int)$request->fuel_type_id) {
                    throw new \Exception('Selected tank does not match selected fuel type.');
                }
                if (($tank->current_qty + $request->quantity) > $tank->capacity) {
                    throw new \Exception('Tank capacity is not enough for this purchase.');
                }

                $fuel = FuelType::findOrFail($request->fuel_type_id);
                $unitPrice = (float) $fuel->purchase_price;
                $subtotal = $request->quantity * $unitPrice;
                $paid = min($request->paid_amount, $subtotal);
                $due = max($subtotal - $paid, 0);

                $purchase = Purchase::create([
                    'purchase_no' => 'PUR-'.now()->format('YmdHis'),
                    'supplier_id' => $request->supplier_id,
                    'currency_id' => $request->currency_id,
                    'exchange_rate' => $request->exchange_rate ?? 1,
                    'purchase_date' => $request->purchase_date,
                    'tanker_no' => $request->tanker_no,
                    'driver_name' => $request->driver_name,
                    'subtotal' => $subtotal,
                    'paid_amount' => $paid,
                    'due_amount' => $due,
                    'notes' => $request->notes,
                    'user_id' => Auth::id(),
                ]);

                PurchaseItem::create([
                    'purchase_id' => $purchase->id,
                    'fuel_type_id' => $request->fuel_type_id,
                    'fuel_quality_id' => $request->fuel_quality_id,
                    'tank_id' => $request->tank_id,
                    'owner_type' => $request->owner_type,
                    'customer_id' => $request->owner_type === 'customer' ? $request->customer_id : null,
                    'quantity' => $request->quantity,
                    'unit_price' => $unitPrice,
                    'total' => $subtotal,
                ]);

                $tank->current_qty += $request->quantity;
                if ($request->owner_type === 'own') {
                    $tank->own_qty += $request->quantity;
                } else {
                    $tank->customer_qty += $request->quantity;
                }
                $tank->save();

                StockLedger::create([
                    'ledger_date' => $request->purchase_date,
                    'fuel_type_id' => $request->fuel_type_id,
                    'tank_id' => $request->tank_id,
                    'owner_type' => $request->owner_type,
                    'customer_id' => $request->owner_type === 'customer' ? $request->customer_id : null,
                    'qty_in' => $request->quantity,
                    'qty_out' => 0,
                    'balance' => $tank->current_qty,
                    'reference_type' => 'purchase',
                    'reference_id' => $purchase->id,
                    'notes' => 'Purchase '.$purchase->purchase_no,
                    'user_id' => Auth::id(),
                ]);
            });
        } catch (\Throwable $e) {
            return back()->withInput()->with('error', $e->getMessage());
        }

        return redirect()->route('purchases.index')->with('success', __('app.saved_successfully'));
    }

    public function show(Purchase $purchase)
    {
        $purchase->load(['supplier','currency','items.fuelType','items.quality','items.tank','items.customer']);
        return view('purchases.show', compact('purchase'));
    }
}
