<?php
declare(strict_types=1);

namespace App\Modules\Accounting\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\App;
use App\Core\Response;
use App\Modules\Accounting\Models\AccountBudget;
use App\Modules\Accounting\Models\CostCenterBudget;
use App\Modules\Accounting\Services\BudgetService;

class BudgetController extends Controller
{
    public function index(Request $request): Response
    {
        $this->authorize('accounting.budget.view');

        $db = App::getInstance()->db();
        $fiscalYears = $db->select("SELECT id, name_ar, start_date, end_date, status FROM fiscal_years WHERE is_archived = 0 ORDER BY start_date DESC");
        $currentYear = $db->selectOne("SELECT id FROM fiscal_years WHERE is_current = 1 AND is_archived = 0");
        $selectedYearId = (int)($request->get('fiscal_year_id') ?? ($currentYear['id'] ?? 0));

        $accounts = $db->select("
            SELECT id, code, name_ar, account_type, is_header
            FROM chart_of_accounts
            WHERE is_archived = 0 AND is_header = 0
            ORDER BY code
        ");

        $budgets = [];
        if ($selectedYearId) {
            $rows = AccountBudget::getForYear($selectedYearId);
            foreach ($rows as $row) {
                $budgets[(int)$row['account_id']][$row['period']] = $row;
            }
        }

        return $this->view('Accounting/Views/budgets/index', [
            'fiscalYears'    => $fiscalYears,
            'selectedYearId' => $selectedYearId,
            'accounts'       => $accounts,
            'budgets'        => $budgets,
        ]);
    }

    public function store(Request $request): Response
    {
        $this->authorize('accounting.budget.manage');

        $fiscalYearId = (int)$request->post('fiscal_year_id');
        $accountId = (int)$request->post('account_id');
        $session = App::getInstance()->session();
        $userId = (int)($session->get('employee_id') ?? 0);

        if (!$fiscalYearId || !$accountId) {
            return $this->redirect('/accounting/budgets')
                ->withError('بيانات غير مكتملة');
        }

        $amounts = $request->post('amounts', []);
        $notes = $request->post('budget_notes', '');

        foreach ($amounts as $period => $amount) {
            $amount = (float)$amount;
            if ($amount == 0) {
                continue;
            }
            AccountBudget::upsert($fiscalYearId, $accountId, $period, $amount, $notes ?: null, $userId ?: null);
        }

        return $this->redirect('/accounting/budgets?fiscal_year_id=' . $fiscalYearId)
            ->withSuccess('تم حفظ الموازنة بنجاح');
    }

    public function costCenters(Request $request): Response
    {
        $this->authorize('accounting.budget.view');

        $db = App::getInstance()->db();
        $fiscalYears = $db->select("SELECT id, name_ar, start_date, end_date, status FROM fiscal_years WHERE is_archived = 0 ORDER BY start_date DESC");
        $currentYear = $db->selectOne("SELECT id FROM fiscal_years WHERE is_current = 1 AND is_archived = 0");
        $selectedYearId = (int)($request->get('fiscal_year_id') ?? ($currentYear['id'] ?? 0));

        $costCenters = $db->select("SELECT id, code, name_ar FROM cost_centers WHERE is_active = 1 ORDER BY code");

        $budgets = [];
        if ($selectedYearId) {
            $rows = CostCenterBudget::getForYear($selectedYearId);
            foreach ($rows as $row) {
                $budgets[(int)$row['cost_center_id']][$row['period']] = $row;
            }
        }

        return $this->view('Accounting/Views/budgets/cost_centers', [
            'fiscalYears'    => $fiscalYears,
            'selectedYearId' => $selectedYearId,
            'costCenters'    => $costCenters,
            'budgets'        => $budgets,
        ]);
    }

    public function storeCostCenter(Request $request): Response
    {
        $this->authorize('accounting.budget.manage');

        $fiscalYearId = (int)$request->post('fiscal_year_id');
        $costCenterId = (int)$request->post('cost_center_id');
        $accountId = $request->post('account_id') ? (int)$request->post('account_id') : null;
        $session = App::getInstance()->session();
        $userId = (int)($session->get('employee_id') ?? 0);

        if (!$fiscalYearId || !$costCenterId) {
            return $this->redirect('/accounting/budgets/cost-centers')
                ->withError('بيانات غير مكتملة');
        }

        $amounts = $request->post('amounts', []);
        $notes = $request->post('budget_notes', '');

        foreach ($amounts as $period => $amount) {
            $amount = (float)$amount;
            if ($amount == 0) {
                continue;
            }
            CostCenterBudget::upsert($fiscalYearId, $costCenterId, $accountId, $period, $amount, $notes ?: null, $userId ?: null);
        }

        return $this->redirect('/accounting/budgets/cost-centers?fiscal_year_id=' . $fiscalYearId)
            ->withSuccess('تم حفظ موازنة مركز التكلفة بنجاح');
    }

    public function varianceReport(Request $request): Response
    {
        $this->authorize('accounting.budget.view');

        $db = App::getInstance()->db();
        $fiscalYears = $db->select("SELECT id, name_ar, start_date, end_date FROM fiscal_years WHERE is_archived = 0 ORDER BY start_date DESC");
        $currentYear = $db->selectOne("SELECT id FROM fiscal_years WHERE is_current = 1 AND is_archived = 0");
        $selectedYearId = (int)($request->get('fiscal_year_id') ?? ($currentYear['id'] ?? 0));
        $fromPeriod = $request->get('from_period');
        $toPeriod = $request->get('to_period');

        $report = [];
        if ($selectedYearId) {
            $report = BudgetService::getVarianceReport($selectedYearId, $fromPeriod, $toPeriod);
        }

        return $this->view('Accounting/Views/budgets/variance_report', [
            'fiscalYears'    => $fiscalYears,
            'selectedYearId' => $selectedYearId,
            'fromPeriod'     => $fromPeriod,
            'toPeriod'       => $toPeriod,
            'report'         => $report,
        ]);
    }
}
