<?php

namespace App\Http\Controllers;

use App\Models\AccountHead;
use App\Models\Expense;
use App\Models\Project;
use App\Services\AccountingService;
use App\Services\CodeGeneratorService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class ExpenseController extends Controller
{
    public function __construct(
        private CodeGeneratorService $codeGenerator,
        private AccountingService $accounting
    ) {}

    public function index(Request $request): Response
    {
        $this->authorize('viewAny', \App\Models\Invoice::class);

        $expenses = Expense::with(['accountHead', 'paidFrom', 'project'])
            ->when($request->project_id, fn($q, $p) => $q->where('project_id', $p))
            ->orderByDesc('expense_date')
            ->paginate(25)->withQueryString();

        return Inertia::render('Accounts/Expenses/Index', ['expenses' => $expenses, 'filters' => $request->only(['project_id'])]);
    }

    public function create(): Response
    {
        $this->authorize('create', \App\Models\Invoice::class);

        return Inertia::render('Accounts/Expenses/Create', [
            'expenseHeads' => AccountHead::whereHas('group', fn($q) => $q->where('type', 'expense'))
                ->where('is_active', true)->select('id', 'name', 'code')->get(),
            'cashBankHeads' => AccountHead::whereHas('group', fn($q) => $q->where('type', 'asset'))
                ->where('is_active', true)->select('id', 'name', 'code')->get(),
            'projects' => Project::whereNotIn('status', ['completed', 'cancelled'])->select('id', 'name', 'code')->get(),
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $this->authorize('create', \App\Models\Invoice::class);

        $validated = $request->validate([
            'account_head_id' => 'required|uuid|exists:account_heads,id',
            'project_id' => 'nullable|uuid|exists:projects,id',
            'amount' => 'required|numeric|min:0.01',
            'expense_date' => 'required|date',
            'paid_from' => 'required|uuid|exists:account_heads,id',
            'description' => 'required|string|max:250',
            'reference' => 'nullable|string|max:150',
            'receipt_path' => 'nullable|string',
        ]);

        $code = $this->codeGenerator->generate('EXP', 'expenses');
        $expense = Expense::create(array_merge($validated, [
            'code' => $code,
            'created_by' => auth()->id(),
        ]));

        $this->accounting->postExpenseRecorded($expense->fresh(['accountHead']));

        return redirect()->route('accounts.expenses.index')->with('success', 'Expense recorded.');
    }

    public function show(Expense $expense): Response
    {
        $this->authorize('viewAny', \App\Models\Invoice::class);
        $expense->load(['accountHead', 'paidFrom', 'project', 'createdBy']);
        return Inertia::render('Accounts/Expenses/Show', ['expense' => $expense]);
    }

    public function edit(Expense $expense): Response { abort(403); }
    public function update(Request $request, Expense $expense): RedirectResponse { abort(403); }
    public function destroy(Expense $expense): RedirectResponse { abort(403); }
}
