<?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\Reporting\Application\Services\SupplierAgingReportService;
use App\Modules\Reporting\Application\Services\ReportFileExportService;

final class SupplierAgingReportController
{
    public function __construct(private ?SupplierAgingReportService $service = null)
    {
        $this->service ??= new SupplierAgingReportService(db());
    }

    public function index(): void
    {
        Auth::requireLogin();
        require_permission('suppliers.aging.view');
        $this->service->ensureSchema();

        $data = $this->service->report(
            (int) Request::get('supplier_id', Request::get('party_id', 0)),
            trim((string) Request::get('as_of', '')),
        );
        $page = max(1, (int) Request::get('page', 1));
        $pagination = paginate_rows($data['rows'] ?? [], $page, 25);
        $data['rows'] = $pagination['items'];

        Response::view('pages/purchases/supplier_aging_report', $data + [
            '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'],
            'page_title' => 'تقرير أعمار ديون الموردين',
            'breadcrumbs' => [
                ['label' => 'لوحة التحكم', 'url' => '/admin/dashboard'],
                ['label' => 'المشتريات'],
                ['label' => 'تقرير أعمار ديون الموردين'],
            ],
        ]);
    }

    public function print(): void
    {
        Auth::requireLogin();
        require_permission('suppliers.aging.view');
        $this->service->ensureSchema();

        $format = strtolower(trim((string) Request::get('format', '')));
        if ($format === '') {
            $this->chooseFormat('طباعة تقرير أعمار ديون الموردين');
            return;
        }

        $data = $this->service->report(
            (int) Request::get('supplier_id', Request::get('party_id', 0)),
            trim((string) Request::get('as_of', '')),
        );

        $title = 'تقرير أعمار ديون الموردين';
        $meta = ['as_of' => $data['as_of']];
        if (is_array($data['selected_supplier'] ?? null)) {
            $title = 'تقرير أعمار ديون المورد: ' . (string) (($data['selected_supplier']['name'] ?? ''));
            $meta['supplier'] = (string) (($data['selected_supplier']['name'] ?? ''));
        }

        print_view($format, 'supplier_aging_report', [
            'title' => $title,
            'meta' => $meta,
            'company' => company_profile(db()),
            'footer' => [],
            'buckets' => $data['buckets'],
            'rows' => $this->normalizePrintRows($data['rows']),
            'totals' => $this->normalizePrintTotals($data['totals']),
            'as_of' => $data['as_of'],
        ]);
    }


    public function exportExcel(): void
    {
        Auth::requireLogin();
        require_permission('suppliers.aging.view');
        $this->service->ensureSchema();
        $data = $this->service->report((int) Request::get('supplier_id', Request::get('party_id', 0)), trim((string) Request::get('as_of', '')));
        $rows = [];
        $i = 0;
        foreach ($this->normalizePrintRows($data['rows'] ?? []) as $r) {
            $i++;
            $rows[] = [$i, (string)($r['supplier_name'] ?? ''), (string)($r['supplier_code'] ?? ''), format_money($r['b1'] ?? 0), format_money($r['b2'] ?? 0), format_money($r['b3'] ?? 0), format_money($r['b4'] ?? 0), format_money($r['total'] ?? 0)];
        }
        $totals = $this->normalizePrintTotals(is_array($data['totals'] ?? null) ? $data['totals'] : []);
        (new ReportFileExportService())->sendExcel('supplier-aging-' . date('Ymd-His'), 'تقرير أعمار ديون الموردين', [
            'حتى تاريخ' => (string)($data['as_of'] ?? ''),
            'إجمالي الدين' => format_money($totals['total'] ?? 0),
        ], ['#','المورد','الكود','0-30','31-60','61-90','أكثر من 90','الإجمالي'], $rows);
    }

    public function exportPdf(): void
    {
        Auth::requireLogin();
        require_permission('suppliers.aging.view');
        $_GET['format'] = 'a4';
        ob_start();
        $this->print();
        $html = (string)ob_get_clean();
        (new ReportFileExportService())->sendPdfFromHtml($html, 'supplier-aging-' . date('Ymd-His'));
    }

    /** @param array<int,array<string,mixed>> $rows */
    private function normalizePrintRows(array $rows): array
    {
        $out = [];
        foreach ($rows as $row) {
            $supplier = is_array($row['supplier'] ?? null) ? $row['supplier'] : [];
            $buckets = is_array($row['buckets'] ?? null) ? $row['buckets'] : [];
            $out[] = [
                'supplier_name' => (string) ($supplier['name'] ?? ''),
                'supplier_code' => (string) ($supplier['code'] ?? ''),
                'b1' => (float) ($buckets['0-30'] ?? 0),
                'b2' => (float) ($buckets['31-60'] ?? 0),
                'b3' => (float) ($buckets['61-90'] ?? 0),
                'b4' => (float) ($buckets['+90'] ?? 0),
                'total' => (float) ($buckets['total'] ?? 0),
            ];
        }
        return $out;
    }

    /** @param array<string,mixed> $totals */
    private function normalizePrintTotals(array $totals): array
    {
        return [
            'b1' => (float) ($totals['0-30'] ?? 0),
            'b2' => (float) ($totals['31-60'] ?? 0),
            'b3' => (float) ($totals['61-90'] ?? 0),
            'b4' => (float) ($totals['+90'] ?? 0),
            'total' => (float) ($totals['total'] ?? 0),
        ];
    }

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