<?php

namespace Modules\Finance\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Modules\Finance\Clients\FinanceModuleClient;
use Modules\Finance\ViewModels\TransactionView;

class TransactionController extends Controller
{
    public function __construct(
        private readonly FinanceModuleClient $finance,
    ) {}

    public function index(Request $request): View
    {
        $this->authorize('finance.transactions.view');

        return view('finance::transactions.index', [
            'transactions' => $this->finance->paginateTransactions($this->filters($request)),
            'filters' => $this->filters($request),
        ]);
    }

    public function create(): View
    {
        $this->authorize('finance.transactions.create');

        return view('finance::transactions.create', [
            'incomeCategories' => $this->finance->listIncomeCategories(),
            'expenseCategories' => $this->finance->listExpenseCategories(),
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $this->authorize('finance.transactions.create');

        $this->finance->createTransaction($this->validated($request));

        return redirect()
            ->route('finance.transactions.index')
            ->with('status', 'Transaction recorded.');
    }

    public function show(TransactionView $transaction): View
    {
        $this->authorize('finance.transactions.view');

        return view('finance::transactions.show', [
            'transaction' => $transaction,
        ]);
    }

    public function edit(TransactionView $transaction): View
    {
        $this->authorize('finance.transactions.update');

        return view('finance::transactions.edit', [
            'transaction' => $transaction,
            'incomeCategories' => $this->finance->listIncomeCategories(),
            'expenseCategories' => $this->finance->listExpenseCategories(),
        ]);
    }

    public function update(Request $request, TransactionView $transaction): RedirectResponse
    {
        $this->authorize('finance.transactions.update');

        $this->finance->updateTransaction($transaction->getKey(), $this->validated($request));

        return redirect()
            ->route('finance.transactions.index')
            ->with('status', 'Transaction updated.');
    }

    public function destroy(TransactionView $transaction): RedirectResponse
    {
        $this->authorize('finance.transactions.delete');

        $this->finance->deleteTransaction($transaction->getKey());

        return redirect()
            ->route('finance.transactions.index')
            ->with('status', 'Transaction deleted.');
    }

    /**
     * @return array<string, mixed>
     */
    private function validated(Request $request): array
    {
        return $request->validate([
            'type' => ['required', 'in:income,expense'],
            'income_category_id' => ['nullable', 'required_if:type,income', 'integer'],
            'expense_category_id' => ['nullable', 'required_if:type,expense', 'integer'],
            'amount' => ['required', 'numeric', 'min:0.01'],
            'note' => ['nullable', 'string'],
            'transaction_at' => ['required', 'date'],
            'reference_number' => ['nullable', 'string', 'max:100'],
            'attachment' => ['nullable', 'file', 'max:5120'],
        ]);
    }

    /**
     * @return array<string, mixed>
     */
    private function filters(Request $request): array
    {
        return $request->only([
            'date_preset',
            'date_from',
            'date_to',
            'type',
            'search',
        ]);
    }
}
