<?php
declare(strict_types=1);

namespace App\Modules\Accounting\Controllers;

use App\Core\Controller;
use App\Core\App;
use App\Core\Response;
use App\Modules\Accounting\Models\FiscalYear;
use App\Modules\Accounting\Models\CostCenter;
use App\Modules\Accounting\Models\AccountPayable;
use App\Modules\Accounting\Models\AccountReceivable;
use App\Modules\Accounting\Services\LedgerService;
use App\Modules\Accounting\Services\FinancialReportService;

class ReportController extends Controller
{
    public function dashboard(): Response
    {
        $this->authorize('accounting.reports.view');

        $db = App::getInstance()->db();
        $currentFY = FiscalYear::current();

        // Quick stats
        $today = date('Y-m-d');
        $monthStart = date('Y-m-01');

        $monthlyTotals = $db->selectOne(
            "SELECT COALESCE(SUM(total_debit), 0) as total_debit, COUNT(*) as count
             FROM journal_entries
             WHERE status = 'posted' AND entry_date >= ? AND entry_date <= ? AND is_archived = 0",
            [$monthStart, $today]
        );

        $arSummary = AccountReceivable::getAgingSummary();
        $apSummary = AccountPayable::getAgingSummary();

        $draftCount = $db->selectOne(
            "SELECT COUNT(*) as cnt FROM journal_entries WHERE status = 'draft' AND is_archived = 0"
        );

        return $this->view('Accounting/Views/dashboard/index', [
            'fiscal_year'    => $currentFY ? $currentFY->toArray() : null,
            'monthly_totals' => $monthlyTotals,
            'ar_summary'     => $arSummary,
            'ap_summary'     => $apSummary,
            'draft_count'    => (int) ($draftCount['cnt'] ?? 0),
        ]);
    }

    public function trialBalance(): Response
    {
        $this->authorize('accounting.reports.trial_balance');

        $currentFY = FiscalYear::current();
        $dateFrom = $_GET['date_from'] ?? ($currentFY ? $currentFY->start_date : date('Y-01-01'));
        $dateTo = $_GET['date_to'] ?? date('Y-m-d');
        $costCenterId = !empty($_GET['cost_center_id']) ? (int) $_GET['cost_center_id'] : null;
        $branchId = !empty($_GET['branch_id']) ? (int) $_GET['branch_id'] : null;

        $result = LedgerService::getTrialBalance($dateFrom, $dateTo, null, $costCenterId, $branchId);

        $costCenters = CostCenter::getActive();
        $db = App::getInstance()->db();
        $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_archived = 0 ORDER BY name_ar");

        return $this->view('Accounting/Views/reports/trial_balance', [
            'result'       => $result,
            'date_from'    => $dateFrom,
            'date_to'      => $dateTo,
            'cost_centers' => $costCenters,
            'branches'     => $branches,
            'filters'      => [
                'cost_center_id' => $costCenterId,
                'branch_id'      => $branchId,
            ],
        ]);
    }

    public function generalLedger(): Response
    {
        $this->authorize('accounting.reports.general_ledger');

        $accountId = (int) ($_GET['account_id'] ?? 0);
        $currentFY = FiscalYear::current();
        $dateFrom = $_GET['date_from'] ?? ($currentFY ? $currentFY->start_date : date('Y-01-01'));
        $dateTo = $_GET['date_to'] ?? date('Y-m-d');
        $costCenterId = !empty($_GET['cost_center_id']) ? (int) $_GET['cost_center_id'] : null;
        $branchId = !empty($_GET['branch_id']) ? (int) $_GET['branch_id'] : null;

        $ledger = null;
        if ($accountId > 0) {
            $ledger = LedgerService::getAccountLedger($accountId, $dateFrom, $dateTo, $costCenterId, $branchId);
        }

        $costCenters = CostCenter::getActive();
        $db = App::getInstance()->db();
        $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_archived = 0 ORDER BY name_ar");

        return $this->view('Accounting/Views/reports/general_ledger', [
            'ledger'       => $ledger,
            'account_id'   => $accountId,
            'date_from'    => $dateFrom,
            'date_to'      => $dateTo,
            'cost_centers' => $costCenters,
            'branches'     => $branches,
            'filters'      => [
                'cost_center_id' => $costCenterId,
                'branch_id'      => $branchId,
            ],
        ]);
    }

    public function incomeStatement(): Response
    {
        $this->authorize('accounting.reports.income_statement');

        $currentFY = FiscalYear::current();
        $dateFrom = $_GET['date_from'] ?? ($currentFY ? $currentFY->start_date : date('Y-01-01'));
        $dateTo = $_GET['date_to'] ?? date('Y-m-d');
        $costCenterId = !empty($_GET['cost_center_id']) ? (int) $_GET['cost_center_id'] : null;
        $branchId = !empty($_GET['branch_id']) ? (int) $_GET['branch_id'] : null;

        $result = FinancialReportService::getIncomeStatement($dateFrom, $dateTo, $costCenterId, $branchId);

        $costCenters = CostCenter::getActive();
        $db = App::getInstance()->db();
        $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_archived = 0 ORDER BY name_ar");

        return $this->view('Accounting/Views/reports/income_statement', [
            'result'       => $result,
            'date_from'    => $dateFrom,
            'date_to'      => $dateTo,
            'cost_centers' => $costCenters,
            'branches'     => $branches,
            'filters'      => [
                'cost_center_id' => $costCenterId,
                'branch_id'      => $branchId,
            ],
        ]);
    }

    public function balanceSheet(): Response
    {
        $this->authorize('accounting.reports.balance_sheet');

        $asOfDate = $_GET['as_of_date'] ?? date('Y-m-d');
        $costCenterId = !empty($_GET['cost_center_id']) ? (int) $_GET['cost_center_id'] : null;
        $branchId = !empty($_GET['branch_id']) ? (int) $_GET['branch_id'] : null;

        $result = FinancialReportService::getBalanceSheet($asOfDate, $costCenterId, $branchId);

        $costCenters = CostCenter::getActive();
        $db = App::getInstance()->db();
        $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_archived = 0 ORDER BY name_ar");

        return $this->view('Accounting/Views/reports/balance_sheet', [
            'result'       => $result,
            'as_of_date'   => $asOfDate,
            'cost_centers' => $costCenters,
            'branches'     => $branches,
            'filters'      => [
                'cost_center_id' => $costCenterId,
                'branch_id'      => $branchId,
            ],
        ]);
    }

    public function consolidatedBalanceSheet(): Response
    {
        $this->authorize('accounting.reports.consolidated');

        $asOfDate = $_GET['as_of_date'] ?? date('Y-m-d');
        $result = FinancialReportService::getConsolidatedBalanceSheet($asOfDate);

        return $this->view('Accounting/Views/reports/consolidated_balance_sheet', [
            'result'     => $result,
            'as_of_date' => $asOfDate,
        ]);
    }

    public function accountsReceivable(): Response
    {
        $this->authorize('accounting.reports.ar');

        $memberId = !empty($_GET['member_id']) ? (int) $_GET['member_id'] : null;
        $outstanding = AccountReceivable::getOutstanding($memberId);
        $aging = AccountReceivable::getAgingSummary();

        return $this->view('Accounting/Views/reports/accounts_receivable', [
            'outstanding' => $outstanding,
            'aging'       => $aging,
            'member_id'   => $memberId,
        ]);
    }

    public function accountsPayable(): Response
    {
        $this->authorize('accounting.reports.ap');

        $supplierId = !empty($_GET['supplier_id']) ? (int) $_GET['supplier_id'] : null;
        $outstanding = AccountPayable::getOutstanding($supplierId);
        $aging = AccountPayable::getAgingSummary();

        return $this->view('Accounting/Views/reports/accounts_payable', [
            'outstanding'  => $outstanding,
            'aging'        => $aging,
            'supplier_id'  => $supplierId,
        ]);
    }

    public function memberStatement(): Response
    {
        $this->authorize('accounting.reports.member_statement');

        $memberId = (int) ($_GET['member_id'] ?? 0);
        $dateFrom = $_GET['date_from'] ?? date('Y-01-01');
        $dateTo = $_GET['date_to'] ?? date('Y-m-d');

        $entries = [];
        $member = null;
        if ($memberId > 0) {
            $db = App::getInstance()->db();
            $member = $db->selectOne("SELECT id, full_name_ar, form_number FROM members WHERE id = ?", [$memberId]);
            $entries = LedgerService::getMemberStatement($memberId, $dateFrom, $dateTo);
        }

        return $this->view('Accounting/Views/reports/member_statement', [
            'member'    => $member,
            'entries'   => $entries,
            'member_id' => $memberId,
            'date_from' => $dateFrom,
            'date_to'   => $dateTo,
        ]);
    }
}
