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

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

    public function period(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');

        try {
            $this->service->ensureSchema();
            $data = $this->service->period(
                trim((string) Request::get('from', '')),
                trim((string) Request::get('to', '')),
                (int) Request::get('party_id', 0),
                (int) Request::get('warehouse_id', 0),
            );
        } catch (\RuntimeException $e) {
            Response::view('pages/dashboard', ['error' => $e->getMessage()]);
            return;
        }

        $page = max(1, (int) Request::get('page', 1));
        $pagination = paginate_rows($data['rows'] ?? [], $page, 25);
        $data['rows'] = $pagination['items'];
        Response::view('pages/purchases/purchase_report_period', $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']]);
    }

    public function printPeriod(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');

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

        try {
            $this->service->ensureSchema();
            $data = $this->service->period(
                trim((string) Request::get('from', '')),
                trim((string) Request::get('to', '')),
                (int) Request::get('party_id', 0),
                (int) Request::get('warehouse_id', 0),
            );
        } catch (\RuntimeException $e) {
            http_response_code(500);
            exit($e->getMessage());
        }

        $meta = ['من' => $data['date_from'], 'إلى' => $data['date_to']];
        if ($data['supplier_name'] !== '') { $meta['الطرف'] = $data['supplier_name']; }
        if ($data['warehouse_name'] !== '') { $meta['المخزن'] = $data['warehouse_name']; }

        print_view($format, 'purchase_report_period', [
            'title' => 'تقرير مشتريات خلال فترة',
            'meta' => $meta,
            'company' => company_profile(db()),
            'footer' => [],
            'rows' => $data['rows'],
            'summary' => $data['summary'],
        ]);
    }

    public function bySupplier(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');

        try {
            $this->service->ensureSchema();
            $data = $this->service->bySupplier(
                trim((string) Request::get('from', '')),
                trim((string) Request::get('to', '')),
                (int) Request::get('warehouse_id', 0),
            );
        } catch (\RuntimeException $e) {
            Response::view('pages/dashboard', ['error' => $e->getMessage()]);
            return;
        }

        $page = max(1, (int) Request::get('page', 1));
        $pagination = paginate_rows($data['rows'] ?? [], $page, 25);
        $data['rows'] = $pagination['items'];
        Response::view('pages/purchases/purchase_report_by_supplier', $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']]);
    }

    public function printBySupplier(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');

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

        try {
            $this->service->ensureSchema();
            $data = $this->service->bySupplier(
                trim((string) Request::get('from', '')),
                trim((string) Request::get('to', '')),
                (int) Request::get('warehouse_id', 0),
            );
        } catch (\RuntimeException $e) {
            http_response_code(500);
            exit($e->getMessage());
        }

        $meta = ['من' => $data['date_from'], 'إلى' => $data['date_to']];
        if ($data['warehouse_name'] !== '') { $meta['المخزن'] = $data['warehouse_name']; }

        print_view($format, 'purchase_report_by_supplier', [
            'title' => 'مشتريات حسب مورد',
            'meta' => $meta,
            'company' => company_profile(db()),
            'footer' => [],
            'rows' => $data['rows'],
            'totals' => $data['totals'],
        ]);
    }

    public function items(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');

        try {
            $this->service->ensureSchema();
            $data = $this->service->items(
                trim((string) Request::get('from', '')),
                trim((string) Request::get('to', '')),
                (int) Request::get('party_id', 0),
                (int) Request::get('warehouse_id', 0),
                (int) Request::get('item_id', 0),
            );
        } catch (\RuntimeException $e) {
            Response::view('pages/dashboard', ['error' => $e->getMessage()]);
            return;
        }

        $page = max(1, (int) Request::get('page', 1));
        $pagination = paginate_rows($data['rows'] ?? [], $page, 25);
        $data['rows'] = $pagination['items'];
        Response::view('pages/purchases/purchase_report_items', $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']]);
    }

    public function printItems(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');

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

        try {
            $this->service->ensureSchema();
            $data = $this->service->items(
                trim((string) Request::get('from', '')),
                trim((string) Request::get('to', '')),
                (int) Request::get('party_id', 0),
                (int) Request::get('warehouse_id', 0),
                (int) Request::get('item_id', 0),
            );
        } catch (\RuntimeException $e) {
            http_response_code(500);
            exit($e->getMessage());
        }

        $meta = ['من' => $data['date_from'], 'إلى' => $data['date_to']];
        if ($data['supplier_name'] !== '') { $meta['الطرف'] = $data['supplier_name']; }
        if ($data['warehouse_name'] !== '') { $meta['المخزن'] = $data['warehouse_name']; }
        if ($data['item_name'] !== '') { $meta['الصنف'] = $data['item_name']; }

        print_view($format, 'purchase_report_items', [
            'title' => 'تقرير الأصناف المشتراة',
            'meta' => $meta,
            'company' => company_profile(db()),
            'footer' => [],
            'rows' => $data['rows'],
            'totals' => $data['totals'],
        ]);
    }


    public function exportPeriodExcel(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');
        $this->service->ensureSchema();
        $data = $this->service->period(trim((string) Request::get('from', '')), trim((string) Request::get('to', '')), (int) Request::get('party_id', 0), (int) Request::get('warehouse_id', 0));
        $rows = [];
        $i = 0;
        foreach (($data['rows'] ?? []) as $r) {
            $i++;
            $rows[] = [$i, substr((string)($r['inv_date'] ?? ''),0,10), (string)($r['inv_no'] ?? $r['invoice_no'] ?? ''), (string)($r['supplier_name'] ?? ''), (string)($r['warehouse_name'] ?? ''), format_money($r['subtotal'] ?? 0), format_money($r['discount_amount'] ?? 0), format_money($r['tax_amount'] ?? 0), format_money($r['total'] ?? 0)];
        }
        $summary = is_array($data['summary'] ?? null) ? $data['summary'] : [];
        (new ReportFileExportService())->sendExcel('purchase-period-' . date('Ymd-His'), 'تقرير مشتريات خلال فترة', [
            'الفترة' => (string)$data['date_from'] . ' - ' . (string)$data['date_to'],
            'المورد' => (string)($data['supplier_name'] ?? ''),
            'المخزن' => (string)($data['warehouse_name'] ?? ''),
            'عدد الفواتير' => (string)($summary['count'] ?? 0),
            'الإجمالي' => format_money($summary['total'] ?? 0),
        ], ['#','التاريخ','رقم الفاتورة','المورد','المخزن','قبل الخصم','الخصم','الضريبة','الإجمالي'], $rows);
    }

    public function exportPeriodPdf(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');
        $_GET['format'] = 'a4';
        ob_start();
        $this->printPeriod();
        $html = (string)ob_get_clean();
        (new ReportFileExportService())->sendPdfFromHtml($html, 'purchase-period-' . date('Ymd-His'));
    }

    public function exportBySupplierExcel(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');
        $this->service->ensureSchema();
        $data = $this->service->bySupplier(trim((string) Request::get('from', '')), trim((string) Request::get('to', '')), (int) Request::get('warehouse_id', 0));
        $rows = [];
        $i = 0;
        foreach (($data['rows'] ?? []) as $r) {
            $i++;
            $rows[] = [$i, (string)($r['supplier_name'] ?? ''), (string)($r['inv_count'] ?? 0), format_money($r['subtotal'] ?? 0), format_money($r['discount_amount'] ?? 0), format_money($r['tax_amount'] ?? 0), format_money($r['total'] ?? 0)];
        }
        $totals = is_array($data['totals'] ?? null) ? $data['totals'] : [];
        (new ReportFileExportService())->sendExcel('purchase-by-supplier-' . date('Ymd-His'), 'مشتريات حسب مورد', [
            'الفترة' => (string)$data['date_from'] . ' - ' . (string)$data['date_to'],
            'المخزن' => (string)($data['warehouse_name'] ?? ''),
            'عدد الفواتير' => (string)($totals['inv_count'] ?? 0),
            'الإجمالي' => format_money($totals['total'] ?? 0),
        ], ['#','المورد','عدد الفواتير','قبل الخصم','الخصم','الضريبة','الإجمالي'], $rows);
    }

    public function exportBySupplierPdf(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');
        $_GET['format'] = 'a4';
        ob_start();
        $this->printBySupplier();
        $html = (string)ob_get_clean();
        (new ReportFileExportService())->sendPdfFromHtml($html, 'purchase-by-supplier-' . date('Ymd-His'));
    }

    public function exportItemsExcel(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');
        $this->service->ensureSchema();
        $data = $this->service->items(trim((string) Request::get('from', '')), trim((string) Request::get('to', '')), (int) Request::get('party_id', 0), (int) Request::get('warehouse_id', 0), (int) Request::get('item_id', 0));
        $rows = [];
        $i = 0;
        foreach (($data['rows'] ?? []) as $r) {
            $i++;
            $rows[] = [$i, (string)($r['item_name'] ?? ''), format_qty($r['qty'] ?? 0), format_money($r['avg_price'] ?? 0), format_money($r['total'] ?? 0)];
        }
        $totals = is_array($data['totals'] ?? null) ? $data['totals'] : [];
        (new ReportFileExportService())->sendExcel('purchase-items-' . date('Ymd-His'), 'تقرير الأصناف المشتراة', [
            'الفترة' => (string)$data['date_from'] . ' - ' . (string)$data['date_to'],
            'المورد' => (string)($data['supplier_name'] ?? ''),
            'المخزن' => (string)($data['warehouse_name'] ?? ''),
            'الصنف' => (string)($data['item_name'] ?? ''),
            'إجمالي الكمية' => format_qty($totals['qty'] ?? 0),
            'الإجمالي' => format_money($totals['total'] ?? 0),
        ], ['#','الصنف','الكمية','متوسط السعر','الإجمالي'], $rows);
    }

    public function exportItemsPdf(): void
    {
        Auth::requireLogin();
        require_permission('purchases.reports.view');
        $_GET['format'] = 'a4';
        ob_start();
        $this->printItems();
        $html = (string)ob_get_clean();
        (new ReportFileExportService())->sendPdfFromHtml($html, 'purchase-items-' . date('Ymd-His'));
    }

    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);
    }
}
