<?php

namespace App\Http\Controllers;

use App\Models\ChartOfAccount;
use App\Models\Customer;
use App\Models\Expense;
use App\Models\Payment;
use App\Models\Purchase;
use App\Models\Receipt;
use App\Models\Sale;
use App\Models\Supplier;
use App\Services\TreasuryService;
use Illuminate\Http\Request;

class TreasuryController extends Controller
{
    public function __construct(private TreasuryService $treasury) {}

    public function index(Request $request, string $type)
    {
        abort_unless(in_array($type, ['receipts', 'payments', 'expenses']), 404);
        $this->authorizeType($request, $type, 'view');
        $records = match ($type) {
            'receipts' => Receipt::with('customer')->latest('receipt_date')->paginate(30),
            'payments' => Payment::with('supplier')->latest('payment_date')->paginate(30),
            'expenses' => Expense::with(['expenseAccount', 'paymentAccount'])->latest('expense_date')->paginate(30),
        };
        return view('treasury.index', compact('records', 'type'));
    }

    public function create(Request $request, string $type)
    {
        abort_unless(in_array($type, ['receipts', 'payments', 'expenses']), 404);
        $this->authorizeType($request, $type, 'create');
        $customers = $type === 'receipts' ? Customer::where('status', 'active')->orderBy('name_en')->get() : collect();
        $suppliers = $type === 'payments' ? Supplier::where('status', 'active')->orderBy('name_en')->get() : collect();
        $expenseAccounts = $type === 'expenses' ? ChartOfAccount::where('type', 'expense')->where('status', 'active')->orderBy('code')->get() : collect();
        $paymentAccounts = $type === 'expenses' ? ChartOfAccount::whereIn('code', ['1110', '1120'])->get() : collect();
        return view('treasury.create', compact('type', 'customers', 'suppliers', 'expenseAccounts', 'paymentAccounts'));
    }

    public function store(Request $request, string $type)
    {
        abort_unless(in_array($type, ['receipts', 'payments', 'expenses']), 404);
        $this->authorizeType($request, $type, 'create');
        try {
            if ($type === 'receipts') {
                $data = $request->validate(['receipt_date' => 'required|date', 'customer_id' => 'required|exists:customers,id', 'amount' => 'required|numeric|gt:0', 'payment_method' => 'required|in:cash,bank,card,transfer', 'reference' => 'nullable|string|max:100', 'notes' => 'nullable|string|max:1000', 'allocations' => 'nullable|array', 'allocations.*.sale_id' => 'required_with:allocations|exists:sales,id', 'allocations.*.amount' => 'required_with:allocations|numeric|min:0']);
                $record = $this->treasury->receipt($data, $data['allocations'] ?? []);
            } elseif ($type === 'payments') {
                $data = $request->validate(['payment_date' => 'required|date', 'supplier_id' => 'required|exists:suppliers,id', 'amount' => 'required|numeric|gt:0', 'payment_method' => 'required|in:cash,bank,card,transfer', 'reference' => 'nullable|string|max:100', 'notes' => 'nullable|string|max:1000', 'allocations' => 'nullable|array', 'allocations.*.purchase_id' => 'required_with:allocations|exists:purchases,id', 'allocations.*.amount' => 'required_with:allocations|numeric|min:0']);
                $record = $this->treasury->payment($data, $data['allocations'] ?? []);
            } else {
                $data = $request->validate(['expense_date' => 'required|date', 'expense_account_id' => 'required|exists:chart_of_accounts,id', 'payment_account_id' => 'required|exists:chart_of_accounts,id', 'taxable_amount' => 'required|numeric|gt:0', 'vat_amount' => 'nullable|numeric|min:0', 'reference' => 'nullable|string|max:100', 'notes' => 'nullable|string|max:1000']);
                $record = $this->treasury->expense($data);
            }
            return redirect()->route('treasury.index', $type)->with('success', ucfirst(rtrim($type, 's')).' posted successfully.');
        } catch (\Throwable $e) { report($e); return back()->withInput()->with('error', $e->getMessage()); }
    }

    public function customerDocuments(Request $request, Customer $customer) { $this->authorizeType($request, 'receipts', 'create'); return response()->json(Sale::where('customer_id', $customer->id)->where('status', 'finalized')->where('balance_total', '>', 0)->orderBy('invoice_date')->get(['id', 'invoice_no', 'invoice_date', 'balance_total'])); }
    public function supplierDocuments(Request $request, Supplier $supplier) { $this->authorizeType($request, 'payments', 'create'); return response()->json(Purchase::where('supplier_id', $supplier->id)->where('status', 'finalized')->where('balance_total', '>', 0)->orderBy('purchase_date')->get(['id', 'purchase_no', 'purchase_date', 'balance_total'])); }

    private function authorizeType(Request $request, string $type, string $action): void
    {
        abort_unless($request->user()?->hasPermission($type.'.'.$action), 403, 'You do not have permission for this treasury operation.');
    }
}
