<?php

declare(strict_types=1);

namespace App\Core;

final class BranchReadiness
{
    /**
     * @return array<string, mixed>
     */
    public static function policy(): array
    {
        $policy = \config('branch_readiness', []);
        return is_array($policy) ? $policy : [];
    }

    /**
     * @return array<string, array<string, mixed>>
     */
    public static function branches(): array
    {
        $branches = \config('branch_readiness.branches', []);
        return is_array($branches) ? $branches : [];
    }

    public static function isConfigured(string $hospitalCode): bool
    {
        $hospitalCode = \normalize_hospital_code($hospitalCode);
        $hospitals = \config('hospitals', []);

        return is_array($hospitals) && array_key_exists($hospitalCode, $hospitals);
    }

    public static function isLive(string $hospitalCode): bool
    {
        $hospitalCode = \normalize_hospital_code($hospitalCode);

        if (!self::isConfigured($hospitalCode)) {
            return false;
        }

        $branch = self::branches()[$hospitalCode] ?? null;
        if (!is_array($branch)) {
            return false;
        }

        $state = strtoupper(trim((string)($branch['state'] ?? '')));
        $included = filter_var(
            $branch['include_in_live_views'] ?? false,
            FILTER_VALIDATE_BOOLEAN,
            FILTER_NULL_ON_FAILURE
        );

        return $state === 'READY' && $included === true;
    }

    /**
     * @return array<int, string>
     */
    public static function liveCodes(): array
    {
        $hospitals = \config('hospitals', []);
        if (!is_array($hospitals)) {
            return [];
        }

        $codes = [];
        foreach (array_keys($hospitals) as $code) {
            $normalized = \normalize_hospital_code((string)$code);
            if (self::isLive($normalized)) {
                $codes[] = $normalized;
            }
        }

        return $codes;
    }

    /**
     * @param array<string, mixed>|null $hospitals
     * @return array<string, mixed>
     */
    public static function liveHospitals(?array $hospitals = null): array
    {
        $hospitals = $hospitals ?? \config('hospitals', []);
        if (!is_array($hospitals)) {
            return [];
        }

        $live = [];
        foreach ($hospitals as $code => $hospital) {
            $normalized = \normalize_hospital_code((string)$code);
            if (self::isLive($normalized)) {
                $live[$normalized] = $hospital;
            }
        }

        return $live;
    }

    public static function fallback(?string $preferred = null): string
    {
        if ($preferred !== null) {
            $preferred = \normalize_hospital_code($preferred);
            if (self::isLive($preferred)) {
                return $preferred;
            }
        }

        $configuredDefault = \normalize_hospital_code((string)\env('DEFAULT_HOSPITAL', 'njch'));
        if (self::isLive($configuredDefault)) {
            return $configuredDefault;
        }

        $liveCodes = self::liveCodes();
        if ($liveCodes !== []) {
            return $liveCodes[0];
        }

        throw new \RuntimeException('No branch is approved for live dashboard access.');
    }

    public static function reasonCode(string $hospitalCode): string
    {
        $hospitalCode = \normalize_hospital_code($hospitalCode);
        $branch = self::branches()[$hospitalCode] ?? [];

        return is_array($branch)
            ? (string)($branch['reason_code'] ?? 'BRANCH_NOT_APPROVED_FOR_LIVE_VIEWS')
            : 'UNKNOWN_BRANCH';
    }
}
