<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\AccessControl;
use App\Core\Auth;
use App\Core\Request;
use App\Core\View;
use App\Repositories\DiarCasesRepository;
use Throwable;

final class DiarCasesController
{
    public function index(): void
    {
        Auth::requireLogin();
        $this->requireView();
        $filters = $this->filters();
        $page = max(1, (int)Request::get('p', '1'));
        $perPage = (int)Request::get('per_page', '25');
        $data = $this->emptyData($filters, $page, $perPage);
        $loadError = '';
        try {
            $data = (new DiarCasesRepository())->search($this->allowedSites(), $filters, $page, $perPage);
        } catch (Throwable $e) {
            error_log('[DIAR-6B.2-R2.1][Cases] ' . $e->getMessage());
            $loadError = $this->tr(
                'The monthly medication-risk case list is temporarily unavailable.',
                'تعذر تحميل قائمة حالات مخاطر مخزون الأدوية الشهرية مؤقتًا.'
            );
        }
        View::render('diar_command_center/cases', [
            'title' => $this->tr('Medication Risk Cases', 'حالات مخاطر مخزون الأدوية'),
            'activePage' => 'diar-cases',
            'hospitalCode' => Auth::hospital(),
            'hospital' => \config('hospitals.' . Auth::hospital(), []),
            'casesData' => $data,
            'filters' => $filters,
            'allowedSites' => $this->allowedSites(),
            'loadError' => $loadError,
            'capabilities' => $this->capabilities(),
        ]);
    }


    /** @return array<string,string> */
    private function filters(): array
    {
        return [
            'site' => strtoupper(trim((string)Request::get('site', 'ALL'))),
            'month' => trim((string)Request::get('month', '')),
            'q' => trim((string)Request::get('q', '')),
            'severity' => strtoupper(trim((string)Request::get('severity', ''))),
            'branch' => trim((string)Request::get('branch', '')),
            'store' => trim((string)Request::get('store', '')),
            'item' => trim((string)Request::get('item', '')),
            'unit' => trim((string)Request::get('unit', '')),
            'trans_code' => trim((string)Request::get('trans_code', '')),
            'trans_effect' => trim((string)Request::get('trans_effect', '')),
            'date_from' => trim((string)Request::get('date_from', '')),
            'date_to' => trim((string)Request::get('date_to', '')),
            'min_score' => trim((string)Request::get('min_score', '')),
            'sort' => strtolower(trim((string)Request::get('sort', 'priority'))),
        ];
    }

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

    /** @return array<string,bool> */
    private function capabilities(): array
    {
        return [
            'portal' => AccessControl::allows('diar.portal.view'),
            'cases' => AccessControl::allows('diar.cases.view'),
            'command' => AccessControl::allows('diar.command.view'),
            'runs' => AccessControl::allows('diar.engine_runs.view'),
            'movements' => AccessControl::allows('diar.movement_dictionary.view'),
            'facts' => AccessControl::allows('diar.daily_fact.view'),
            'investigations' => AccessControl::allows('diar.investigation.view'),
            'rules' => AccessControl::allows('diar.rules.view'),
        ];
    }

    private function requireView(): void
    {
        if (
            !AccessControl::allows('diar.cases.view')
            && !AccessControl::allows('diar.investigation.view')
            && !AccessControl::allows('diar.command.view')
        ) {
            AccessControl::forbidden();
        }
    }

    /** @param array<string,string> $filters @return array<string,mixed> */
    private function emptyData(array $filters, int $page, int $perPage): array
    {
        return [
            'rows' => [],
            'total' => 0,
            'summary' => [],
            'filters' => $filters,
            'page' => $page,
            'per_page' => $perPage,
            'total_pages' => 1,
            'from_row' => 0,
            'to_row' => 0,
            'requested_sites' => [],
            'available_sites' => [],
            'unavailable_sites' => [],
            'site_status' => [],
            'partial_coverage' => true,
            'selected_month' => '',
            'month_options' => [],
            'filter_options' => ['branches' => [], 'trans_codes' => [], 'trans_effects' => []],
            'snapshot_refs' => [],
            'contract' => [],
        ];
    }

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