<?php

declare(strict_types=1);

namespace App\Http\Controllers\Barangay;

use App\Enums\UserActions;
use App\Http\Controllers\Helpers\Permissions\UserPermissions;
use App\Http\Controllers\Helpers\ResponseHelper;
use App\Models\Barangay\BarangayBudget;
use Hypervel\Http\Request;
use Hypervel\Support\Facades\Auth;
use Hypervel\Support\Facades\Validator;

class BudgetController
{
    private function checkRead(): bool
    {
        return UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ViewBarangayBudget);
    }

    private function checkWrite(): bool
    {
        return UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ManageBarangayBudget);
    }

    public function index(Request $request)
    {
        if (!$this->checkRead()) return ResponseHelper::returnUnauthorized();

        $query = BarangayBudget::with('encodedBy')->orderByDesc('date');

        if ($year = $request->input('year')) $query->byYear((int) $year);
        if ($category = $request->input('category')) $query->where('category', $category);

        $entries = $query->paginate((int) $request->input('per_page', 30));

        return response()->json(['success' => true, 'data' => $entries]);
    }

    public function summary(Request $request)
    {
        if (!$this->checkRead()) return ResponseHelper::returnUnauthorized();

        $year = (int) $request->input('year', date('Y'));

        $income  = BarangayBudget::byYear($year)->income()->sum('amount');
        $expense = BarangayBudget::byYear($year)->expense()->sum('amount');

        $bySource = BarangayBudget::byYear($year)
            ->selectRaw('category, source, SUM(amount) as total')
            ->groupBy('category', 'source')
            ->orderBy('category')
            ->orderByDesc('total')
            ->get();

        return response()->json([
            'success' => true,
            'data' => [
                'year'    => $year,
                'income'  => $income,
                'expense' => $expense,
                'balance' => $income - $expense,
                'by_source' => $bySource,
            ],
        ]);
    }

    public function store(Request $request)
    {
        if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized();

        $validator = Validator::make($request->all(), [
            'fiscal_year' => 'required|integer|min:2020|max:2100',
            'category'    => 'required|in:INCOME,EXPENSE',
            'source'      => 'required|string|max:255',
            'amount'      => 'required|numeric|min:0.01',
            'description' => 'nullable|string|max:500',
            'date'        => 'required|date',
            'reference'   => 'nullable|string|max:100',
        ]);

        if ($validator->fails()) {
            return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
        }

        $data = $validator->validated();
        $data['hashkey']    = hash('sha256', uniqid((string) now(), true));
        $data['encoded_by'] = Auth::id();

        $entry = BarangayBudget::create($data);

        return response()->json(['success' => true, 'data' => $entry, 'message' => 'Budget entry recorded']);
    }

    public function update(Request $request)
    {
        if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized();

        $entry = BarangayBudget::where('hashkey', $request->input('target'))->first();
        if (!$entry) return ResponseHelper::returnError('Entry not found', 404);

        $data = $request->only(['source', 'amount', 'description', 'date', 'reference', 'category']);
        $entry->update($data);

        return response()->json(['success' => true, 'data' => $entry, 'message' => 'Budget entry updated']);
    }

    public function destroy(Request $request)
    {
        if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized();

        $entry = BarangayBudget::where('hashkey', $request->input('target'))->first();
        if (!$entry) return ResponseHelper::returnError('Entry not found', 404);

        $entry->delete();

        return response()->json(['success' => true, 'message' => 'Budget entry deleted']);
    }

    public function fiscalYears()
    {
        $years = BarangayBudget::distinct()->orderByDesc('fiscal_year')->pluck('fiscal_year');
        return response()->json(['success' => true, 'data' => $years]);
    }
}
