<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Auth;
use App\Core\Request;
use App\Core\View;
use App\Repositories\BedsRepository;
use Throwable;

final class BedsController
{
    public function index(): void
    {
        Auth::requireLogin();
        $hospitalCode = Auth::hospital();
        $hospital = \config('hospitals.' . $hospitalCode, []);
        $currentYear = (int)date('Y');
        $mode = strtolower(trim((string)Request::get('mode', 'year')));
        if (!in_array($mode, ['year','range'], true)) { $mode = 'year'; }
        $year = \safe_int(Request::get('year'), $currentYear - 1);
        $fromDate = trim((string)Request::get('from_date', sprintf('%04d-01-01', $year)));
        $toDate = trim((string)Request::get('to_date', sprintf('%04d-03-31', $year)));
        $unitId = \safe_int(Request::get('unit_id'), 0);
        $filterError = '';

        if ($mode === 'range') {
            try {
                $from = new \DateTimeImmutable($fromDate);
                $to = new \DateTimeImmutable($toDate);
                if ($from > $to || $from->format('Y') !== $to->format('Y')) {
                    throw new \RuntimeException('Invalid range');
                }
                $year = (int)$from->format('Y');
            } catch (Throwable $e) {
                $filterError = current_lang() === 'ar' ? 'يجب أن تكون فترة التاريخ صحيحة وداخل سنة واحدة.' : 'The date range must be valid and remain within one year.';
                $mode = 'year';
            }
        }

        $data = null;
        $dataError = null;
        try {
            $repo = new BedsRepository($hospitalCode);
            $years = $repo->availableYears(20);
            if (Request::get('year') === null && $mode === 'year' && !empty($years)) {
                $year = (int)$years[0];
            }
            $rangeFrom = $mode === 'range' ? $fromDate : null;
            $rangeTo = $mode === 'range' ? $toDate : null;
            $snapshotRows = $repo->legacyCompatibleCurrentOccupancyRows();
            $units = $repo->legacyCompatibleUnitEfficiencyRows($year, $rangeFrom, $rangeTo, 0);
            if ($unitId <= 0 && !empty($units)) {
                $unitId = (int)($units[0]['unit_id'] ?? 0);
            }
            $beds = $repo->legacyCompatibleBedEfficiencyRows($year, $unitId, $rangeFrom, $rangeTo);
            $snapshot = $this->snapshotSummary($snapshotRows);
            $data = [
                'years' => $years,
                'snapshot_rows' => $snapshotRows,
                'snapshot' => $snapshot,
                'units' => $units,
                'beds' => $beds,
                'selected_unit_id' => $unitId,
                'selected_unit' => $this->selectedUnit($units, $unitId),
                'unit_payload' => $this->chartPayload($units, 'bed_floor', 'bed_efficiency_percentage', current_lang() === 'ar' ? 'كفاءة الوحدات' : 'Unit efficiency', current_lang() === 'ar' ? 'نسبة الإشغال' : 'Occupancy %'),
                'bed_payload' => $this->chartPayload($beds, 'bed_name', 'bed_efficiency_percentage', current_lang() === 'ar' ? 'كفاءة الأسرة' : 'Bed efficiency', current_lang() === 'ar' ? 'نسبة الإشغال' : 'Occupancy %'),
            ];
        } catch (Throwable $e) {
            $dataError = $e->getMessage();
            @file_put_contents(\base_path('storage/logs/app.log'), '[' . date('c') . '] Beds workspace error: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
        }

        View::render('beds/index', [
            'title' => current_lang() === 'ar' ? 'الأسرة والسعة' : 'Beds & Unit Capacity',
            'activePage' => 'beds',
            'hospital' => $hospital,
            'hospitalCode' => $hospitalCode,
            'mode' => $mode,
            'year' => $year,
            'fromDate' => $fromDate,
            'toDate' => $toDate,
            'unitId' => $unitId,
            'filterError' => $filterError,
            'bedsData' => $data,
            'dataError' => $dataError,
        ]);
    }

    /** @param array<int,array{status:string,rate:float}> $rows @return array<string,float> */
    private function snapshotSummary(array $rows): array
    {
        $busy = 0.0; $empty = 0.0;
        foreach ($rows as $row) {
            if (strtolower((string)$row['status']) === 'busy') { $busy = (float)$row['rate']; }
            if (strtolower((string)$row['status']) === 'empty') { $empty = (float)$row['rate']; }
        }
        $total = max(0.0, $busy + $empty);
        return [
            'busy' => $busy,
            'empty' => $empty,
            'total' => $total,
            'occupancy_rate' => $total > 0 ? ($busy / $total) * 100 : 0.0,
        ];
    }

    /** @param array<int,array<string,mixed>> $units @return array<string,mixed>|null */
    private function selectedUnit(array $units, int $unitId): ?array
    {
        foreach ($units as $row) {
            if ((int)($row['unit_id'] ?? 0) === $unitId) { return $row; }
        }
        return null;
    }

    /** @param array<int,array<string,mixed>> $rows @return array<string,mixed> */
    private function chartPayload(array $rows, string $labelKey, string $valueKey, string $title, string $seriesLabel): array
    {
        return [
            'title' => $title,
            'labels' => array_map(static function (array $row) use ($labelKey): string { return (string)($row[$labelKey] ?? ''); }, $rows),
            'series' => [[
                'label' => $seriesLabel,
                'values' => array_map(static function (array $row) use ($valueKey): float { return (float)($row[$valueKey] ?? 0); }, $rows),
            ]],
        ];
    }
}
