<?php

declare(strict_types=1);

namespace App\Modules\Reporting\Presentation\Controllers;

use App\Core\Auth;
use App\Core\Request;
use App\Core\Response;
use App\Modules\Finance\Application\Services\FinanceRouteContext;
use App\Modules\Reporting\Application\Services\BankReportService;
use App\Modules\Reporting\Application\Services\ReportFileExportService;

final class BankReportController
{
    private FinanceRouteContext $routeContext;

    public function __construct(private ?BankReportService $service = null)
    {
        $this->service ??= new BankReportService(db());
        $this->routeContext = new FinanceRouteContext();
    }

    public function statement(): void
    {
        Auth::requireLogin();
        require_permission('banks.txns.view');
        $this->service->ensureSchema();

        $data = $this->service->statement(
            (int) Request::get('bank_account_id', 0),
            trim((string) Request::get('from', '')),
            trim((string) Request::get('to', '')),
            trim((string) Request::get('q', '')),
        );
        $page = max(1, (int) Request::get('page', 1));
        $pagination = paginate_rows($data['rows'] ?? [], $page, 25);

        Response::view('pages/banks/statement', [
            'bankAccounts' => $data['bankAccounts'],
            'bank_account_id' => $data['bankId'],
            'account' => $data['account'],
            'from' => $data['from'],
            'to' => $data['to'],
            'q' => $data['q'],
            'rows' => $pagination['items'],
            'page' => $pagination['page'],
            'per_page' => $pagination['per_page'],
            'total_pages' => $pagination['total_pages'],
            'total_rows' => $pagination['total_rows'],
            'from_row' => $pagination['from'],
            'to_row' => $pagination['to'],
            'opening' => $data['opening'],
            'closing' => $data['closing'],
            'totals' => $data['totals'],
            'page_title' => 'كشف حساب بنك',
            'breadcrumbs' => [
                $this->routeContext->dashboardCrumb(),
                ['label' => 'البنوك'],
                ['label' => 'كشف حساب بنك'],
            ],
            'bank_transactions_url' => $this->routeContext->bankTransactionsPath(),
        ]);
    }

    public function printStatement(): void
    {
        Auth::requireLogin();
        require_permission('banks.txns.view');
        $this->service->ensureSchema();

        $format = strtolower(trim((string) Request::get('format', '')));
        if ($format === '') {
            $this->chooseFormat('طباعة كشف حساب بنك', false);
            return;
        }
        if ($format !== 'a4') {
            $format = 'a4';
        }

        $data = $this->service->statement(
            (int) Request::get('bank_account_id', 0),
            trim((string) Request::get('from', '')),
            trim((string) Request::get('to', '')),
            trim((string) Request::get('q', '')),
        );

        if ((int) ($data['bankId'] ?? 0) <= 0 || empty($data['account'])) {
            echo 'يجب اختيار الحساب البنكي';
            return;
        }

        print_view($format, 'bank_statement', [
            'title' => 'كشف حساب بنك',
            'meta' => [
                'no' => (string)($data['account']['account_no'] ?? $data['account']['name'] ?? ''),
                'date' => date('Y-m-d'),
                'status' => 'الرصيد: ' . format_money($data['closing'] ?? 0),
                'title_en' => 'Bank Statement',
            ],
            'company' => company_profile(db()),
            'footer' => ['page_hint' => '', 'note' => 'كشف حساب بنكي صادر من النظام بناءً على الحركات المسجلة.'],
            'print_format' => $format,
            'account' => $data['account'],
            'rows' => $data['rows'],
            'opening' => $data['opening'],
            'closing' => $data['closing'],
            'totals' => $data['totals'],
            'from' => $data['from'],
            'to' => $data['to'],
            'q' => $data['q'],
        ]);
    }

    public function balances(): void
    {
        Auth::requireLogin();
        require_permission('banks.accounts.view');
        $this->service->ensureSchema();

        $q = trim((string) Request::get('q', ''));
        $data = $this->service->balances($q);
        $page = max(1, (int) Request::get('page', 1));
        $pagination = paginate_rows($data['rows'] ?? [], $page, 25);

        Response::view('pages/banks/balances_report', [
            'rows' => $pagination['items'],
            'page' => $pagination['page'],
            'per_page' => $pagination['per_page'],
            'total_pages' => $pagination['total_pages'],
            'total_rows' => $pagination['total_rows'],
            'from_row' => $pagination['from'],
            'to_row' => $pagination['to'],
            'q' => $data['q'],
            'totals' => $data['totals'],
            'page_title' => 'تقرير أرصدة البنوك',
            'breadcrumbs' => [
                $this->routeContext->dashboardCrumb(),
                ['label' => 'البنوك'],
                ['label' => 'أرصدة البنوك'],
            ],
            'bank_accounts_url' => $this->routeContext->bankAccountsPath(),
        ]);
    }

    public function printBalances(): void
    {
        Auth::requireLogin();
        require_permission('banks.accounts.view');
        $this->service->ensureSchema();

        $format = strtolower(trim((string) Request::get('format', '')));
        if ($format === '') {
            $this->chooseFormat('طباعة أرصدة البنوك', false);
            return;
        }
        if ($format !== 'a4') {
            $format = 'a4';
        }

        $data = $this->service->balances(trim((string) Request::get('q', '')));
        print_view($format, 'bank_balances_report', [
            'title' => 'تقرير أرصدة البنوك',
            'meta' => [
                'no' => 'BANKS',
                'date' => date('Y-m-d'),
                'status' => 'الإجمالي الحالي: ' . format_money($data['totals']['current'] ?? 0),
                'title_en' => 'Bank Balances',
            ],
            'company' => company_profile(db()),
            'footer' => ['page_hint' => '', 'note' => 'تقرير أرصدة البنوك يوضح أرصدة الحسابات حسب آخر الحركات المسجلة.'],
            'print_format' => $format,
            'rows' => $data['rows'],
            'totals' => $data['totals'],
            'q' => $data['q'],
        ]);
    }


    public function exportStatementExcel(): void
    {
        Auth::requireLogin();
        require_permission('banks.txns.view');
        $this->service->ensureSchema();
        $data = $this->service->statement((int) Request::get('bank_account_id', 0), trim((string) Request::get('from', '')), trim((string) Request::get('to', '')), trim((string) Request::get('q', '')));
        if ((int)($data['bankId'] ?? 0) <= 0 || empty($data['account'])) { http_response_code(400); exit('يجب اختيار الحساب البنكي'); }
        $balance = (float)($data['opening'] ?? 0);
        $rows = [[0, (string)($data['from'] ?? ''), 'رصيد أول المدة', '', '', '', '', format_money($balance)]];
        $i = 0;
        foreach (($data['rows'] ?? []) as $r) {
            $i++;
            $in = (($r['trx_type'] ?? '') === 'in') ? (float)($r['amount'] ?? 0) : 0.0;
            $out = (($r['trx_type'] ?? '') === 'out') ? (float)($r['amount'] ?? 0) : 0.0;
            $balance += $in - $out;
            $rows[] = [$i, date('Y-m-d H:i', strtotime((string)($r['trx_date'] ?? 'now'))), reference_type_label((string)($r['source_type'] ?? '')), human_reference_label((string)($r['source_type'] ?? ''), (int)($r['source_id'] ?? 0), (string)($r['ref_no'] ?? '')), (string)($r['notes'] ?? ''), $in ? format_money($in) : '', $out ? format_money($out) : '', format_money($balance)];
        }
        $account = is_array($data['account'] ?? null) ? $data['account'] : [];
        $totals = is_array($data['totals'] ?? null) ? $data['totals'] : [];
        (new ReportFileExportService())->sendExcel('bank-statement-' . date('Ymd-His'), 'كشف حساب بنك', [
            'الحساب' => (string)($account['name'] ?? ''),
            'الفترة' => (string)($data['from'] ?? '') . ' - ' . (string)($data['to'] ?? ''),
            'رصيد أول المدة' => format_money($data['opening'] ?? 0),
            'إجمالي دائن' => format_money($totals['in'] ?? 0),
            'إجمالي مدين' => format_money($totals['out'] ?? 0),
            'الرصيد الختامي' => format_money($data['closing'] ?? 0),
        ], ['#','التاريخ','النوع','المرجع','الملاحظات','دائن','مدين','الرصيد'], $rows);
    }

    public function exportStatementPdf(): void
    {
        Auth::requireLogin();
        require_permission('banks.txns.view');
        $_GET['format'] = 'a4';
        ob_start();
        $this->printStatement();
        $html = (string)ob_get_clean();
        (new ReportFileExportService())->sendPdfFromHtml($html, 'bank-statement-' . date('Ymd-His'));
    }

    public function exportBalancesExcel(): void
    {
        Auth::requireLogin();
        require_permission('banks.accounts.view');
        $this->service->ensureSchema();
        $data = $this->service->balances(trim((string) Request::get('q', '')));
        $rows = [];
        $i = 0;
        foreach (($data['rows'] ?? []) as $r) {
            $i++;
            $rows[] = [$i, (string)($r['name'] ?? ''), (string)($r['bank_name'] ?? ''), (string)($r['account_no'] ?? ''), (string)($r['currency_code'] ?? 'EGP'), format_money($r['opening_balance'] ?? 0), format_money($r['current_balance'] ?? 0), ((int)($r['is_active'] ?? 0) === 1 ? 'نشط' : 'غير نشط')];
        }
        $totals = is_array($data['totals'] ?? null) ? $data['totals'] : [];
        (new ReportFileExportService())->sendExcel('bank-balances-' . date('Ymd-His'), 'تقرير أرصدة البنوك', [
            'بحث' => (string)($data['q'] ?? ''),
            'إجمالي الافتتاحي' => format_money($totals['opening'] ?? 0),
            'إجمالي الرصيد الحالي' => format_money($totals['current'] ?? 0),
        ], ['#','اسم الحساب','البنك','رقم الحساب','العملة','رصيد افتتاحي','الرصيد الحالي','الحالة'], $rows);
    }

    public function exportBalancesPdf(): void
    {
        Auth::requireLogin();
        require_permission('banks.accounts.view');
        $_GET['format'] = 'a4';
        ob_start();
        $this->printBalances();
        $html = (string)ob_get_clean();
        (new ReportFileExportService())->sendPdfFromHtml($html, 'bank-balances-' . date('Ymd-His'));
    }

    private function chooseFormat(string $title, bool $allowReceipt = true): void
    {
        $path = Request::path();
        $qs = $_GET;
        $qs['format'] = 'a4';
        $a4Url = $path . '?' . http_build_query($qs);
        $receiptUrl = '';
        if ($allowReceipt) {
            $qs['format'] = 'receipt';
            $receiptUrl = $path . '?' . http_build_query($qs);
        }
        print_format_chooser($a4Url, $receiptUrl, $title, 'a4');
    }
}
