<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\AccessControl;
use App\Core\Auth;
use App\Core\View;
use App\Services\DiarWorkspaceNavigation;

final class DiarWorkspaceController
{
    public function portal(): void
    {
        Auth::requireLogin();
        if (!DiarWorkspaceNavigation::canOpenPortal()) {
            AccessControl::forbidden();
        }

        View::render('diar_workspace/portal', [
            'title' => $this->tr('DIAR Platform', 'منصة DIAR'),
            'activePage' => 'diar-portal',
            'modules' => DiarWorkspaceNavigation::modules('diar-portal'),
            'allModules' => DiarWorkspaceNavigation::definitions(),
            'accessMatrixRoles' => DiarWorkspaceNavigation::accessMatrixRoles(),
            'roleTemplates' => DiarWorkspaceNavigation::roleTemplates(),
            'showRoleMatrix' => AccessControl::allows('security.access_control.manage') || DiarWorkspaceNavigation::canView('governance'),
            'currentRole' => AccessControl::roleLabel(),
            'user' => Auth::user(),
            'hospitalCode' => Auth::hospital(),
            'hospital' => \config('hospitals.' . Auth::hospital(), []),
        ]);
    }

    public function statistics(): void
    {
        $this->renderModule('statistics', 'diar-statistics');
    }

    public function investigation(): void
    {
        $this->renderModule('investigation', 'diar-investigation-workspace');
    }

    public function reports(): void
    {
        // DIAR_6B_5_R2_5_EXECUTIVE_REPORT_CACHE
        Auth::requireLogin();
        if (!DiarWorkspaceNavigation::canView('reports')) {
            AccessControl::forbidden();
        }

        $filters = $this->diarReportFilters();
        $allowedSites = $this->diarReportsAllowedSites();
        $report = $this->diarReportsEmptyOverview($filters);
        $cacheMeta = [];
        $loadError = '';
        $cacheService = new \App\Services\DiarPrebuiltReportCacheService();

        try {
            $cached = $cacheService->load($allowedSites, $filters);
            $report = (array)($cached['report'] ?? $report);
            $cacheMeta = (array)($cached['manifest'] ?? []);
        } catch (\Throwable $cacheError) {
            try {
                $cached = $cacheService->build(
                    $allowedSites,
                    $filters,
                    false,
                    $this->diarReportUsername()
                );
                $report = (array)($cached['report'] ?? $report);
                $cacheMeta = (array)($cached['manifest'] ?? []);
            } catch (\Throwable $e) {
                error_log('[DIAR Reports R2.5] ' . $e->getMessage());
                $loadError = $this->tr(
                    'The executive report is being prepared. Please refresh the page shortly.',
                    'يتم تجهيز التقرير التنفيذي. يرجى تحديث الصفحة بعد قليل.'
                );
            }
        }

        $history = [];
        try {
            $history = array_values(array_filter(
                (new \App\Services\DiarExportManifestService())->history(30),
                function (array $manifest): bool { return $this->diarReportManifestAllowed($manifest); }
            ));
        } catch (\Throwable $e) {
            error_log('[DIAR Export History] ' . $e->getMessage());
        }

        View::render('diar_workspace/reports', [
            'title' => $this->tr('Inventory Risk Executive Report', 'التقرير التنفيذي لمخاطر المخزون'),
            'activePage' => 'diar-reports',
            'modules' => DiarWorkspaceNavigation::modules('diar-reports'),
            'catalog' => \App\Services\DiarReportCatalog::sheets(),
            'approvedContract' => \App\Services\DiarReportCatalog::approvedWorkbook(),
            'report' => $report,
            'overview' => $report,
            'filters' => $filters,
            'allowedSites' => $allowedSites,
            'exportHistory' => $history,
            'cacheMeta' => $cacheMeta,
            'currentRole' => AccessControl::roleLabel(),
            'hospitalCode' => Auth::hospital(),
            'hospital' => \config('hospitals.' . Auth::hospital(), []),
            'loadError' => $loadError,
        ]);
    }

    public function exportReportExcel(): void
    {
        Auth::requireLogin();
        if (!DiarWorkspaceNavigation::canView('reports')) {
            AccessControl::forbidden();
        }

        $download = (new \App\Services\DiarPrebuiltReportCacheService())->prepareDownload(
            'XLSX',
            $this->diarReportsAllowedSites(),
            $this->diarReportFilters(),
            $this->diarReportUsername()
        );
        $this->streamDiarExport(
            (string)$download['file_path'],
            (string)$download['filename'],
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        );
    }

    public function exportReportPowerPoint(): void
    {
        Auth::requireLogin();
        if (!DiarWorkspaceNavigation::canView('reports')) {
            AccessControl::forbidden();
        }

        $download = (new \App\Services\DiarPrebuiltReportCacheService())->prepareDownload(
            'PPTX',
            $this->diarReportsAllowedSites(),
            $this->diarReportFilters(),
            $this->diarReportUsername()
        );
        $this->streamDiarExport(
            (string)$download['file_path'],
            (string)$download['filename'],
            'application/vnd.openxmlformats-officedocument.presentationml.presentation'
        );
    }

    public function downloadReportExport(): void
    {
        Auth::requireLogin();
        if (!DiarWorkspaceNavigation::canView('reports')) {
            AccessControl::forbidden();
        }
        $token = trim((string)\App\Core\Request::get('token', ''));
        $manifest = (new \App\Services\DiarExportManifestService())->find($token);
        if (!$this->diarReportManifestAllowed($manifest)) {
            AccessControl::forbidden();
        }
        $type = strtoupper((string)($manifest['type'] ?? ''));
        $mime = $type === 'PPTX'
            ? 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
            : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
        $this->streamDiarExport((string)$manifest['file_path'], (string)$manifest['filename'], $mime);
    }


    public function governance(): void
    {
        $this->renderModule('governance', 'diar-governance');
    }

    private function renderModule(string $moduleKey, string $activePage): void
    {
        Auth::requireLogin();
        if (!DiarWorkspaceNavigation::canView($moduleKey)) {
            AccessControl::forbidden();
        }

        View::render('diar_workspace/module', [
            'title' => (string)(DiarWorkspaceNavigation::module($moduleKey)['label'] ?? $this->tr('DIAR Workspace', 'مساحة عمل DIAR')),
            'activePage' => $activePage,
            'moduleKey' => $moduleKey,
            'module' => DiarWorkspaceNavigation::module($moduleKey),
            'modules' => DiarWorkspaceNavigation::modules($activePage),
            'reportSheets' => DiarWorkspaceNavigation::reportSheets(),
            'roleTemplates' => DiarWorkspaceNavigation::roleTemplates(),
            'currentRole' => AccessControl::roleLabel(),
            'hospitalCode' => Auth::hospital(),
            'hospital' => \config('hospitals.' . Auth::hospital(), []),
        ]);
    }



    // DIAR_6B_5_R2_1_REPORTS_HELPERS
    /** @return array<int,string> */
    private function diarReportsAllowedSites(): array
    {
        $sites = [];
        if (AccessControl::allowsBranch('mnh')) {
            $sites[] = 'MNH';
        }
        if (AccessControl::allowsBranch('njch')) {
            $sites[] = 'NJCH';
        }
        return $sites;
    }

    /** @return array<string,string> */
    private function diarReportFilters(): array
    {
        $allowed = $this->diarReportsAllowedSites();
        $defaultSite = in_array('NJCH', $allowed, true)
            ? 'NJCH'
            : (string)($allowed[0] ?? '');
        $site = strtoupper(trim((string)\App\Core\Request::get('site', $defaultSite)));

        if (!in_array($site, ['ALL', 'MNH', 'NJCH'], true)) {
            $site = $defaultSite;
        }
        if ($site === 'ALL') {
            if (!(in_array('MNH', $allowed, true) && in_array('NJCH', $allowed, true))) {
                $site = $defaultSite;
            }
        } elseif (!in_array($site, $allowed, true)) {
            $site = $defaultSite;
        }

        return [
            'site' => $site,
            'period' => 'latest_closed',
            'month' => trim((string)\App\Core\Request::get('month', '')),
        ];
    }

    private function diarReportManifestAllowed(array $manifest): bool
    {
        $allowed = $this->diarReportsAllowedSites();
        $scope = strtoupper(trim((string)($manifest['scope_code'] ?? '')));
        if ($scope === 'ALL') {
            return in_array('MNH', $allowed, true) && in_array('NJCH', $allowed, true);
        }
        return in_array($scope, $allowed, true);
    }

    /** @param array<string,string> $filters @return array<string,mixed> */
    private function diarReportsEmptyOverview(array $filters): array
    {
        return [
            'filters' => $filters, 'scope_code' => $filters['site'], 'selected_month' => '',
            'month_status' => '', 'summary' => [], 'site_cards' => [], 'snapshot_refs' => [],
            'month_options' => [], 'cases' => [], 'critical_cases' => [], 'daily_distribution' => [],
            'store_analysis' => [], 'movement_analysis' => [], 'item_analysis' => [],
            'user_associations' => [], 'statistical_basis' => [], 'statistical_comparisons' => [],
            'top_stores' => [], 'top_items' => [], 'top_movements' => [], 'insights' => [],
            'recommendations' => [], 'snapshot_library' => [], 'cache' => [],
            'movement_detail_count' => 0, 'contract' => [
                'read_only' => true, 'database_link' => false,
            ],
        ];
    }

    private function diarReportUsername(): string
    {
        $user = Auth::user();
        if (is_array($user)) {
            foreach (['username', 'name', 'user_name', 'id'] as $key) {
                if (isset($user[$key]) && trim((string)$user[$key]) !== '') {
                    return trim((string)$user[$key]);
                }
            }
        }
        return 'authenticated-user';
    }

    private function streamDiarExport(string $path, string $filename, string $mime): void
    {
        if (!is_file($path)) {
            throw new \RuntimeException('DIAR_EXPORT_FILE_NOT_FOUND');
        }
        $safe = preg_replace('/[^A-Za-z0-9._-]/', '_', $filename);
        header('Content-Type: ' . $mime);
        header('Content-Disposition: attachment; filename="' . $safe . '"');
        header('Content-Length: ' . (string)filesize($path));
        header('Cache-Control: private, max-age=0, must-revalidate');
        header('X-Content-Type-Options: nosniff');
        readfile($path);
        exit;
    }

    private function tr(string $en, string $ar): string
    {
        return current_lang() === 'ar' ? $ar : $en;
    }
}
