<?php

declare(strict_types=1);

namespace App\Core;

use App\Repositories\AccessControlRepository;
use App\Repositories\UserRepository;
use Throwable;

final class Auth
{
    public static function check(): bool
    {
        $user = Session::get('user');
        return is_array($user) && !empty($user['name']);
    }

    public static function user(): ?array
    {
        $user = Session::get('user');
        return is_array($user) ? $user : null;
    }

    public static function name(): string
    {
        $user = self::user();
        return (string) ($user['name'] ?? '');
    }

    public static function hospital(): string
    {
        $user = self::user();
        $stored = \normalize_hospital_code((string)($user['hospital'] ?? ''));
        if ($stored !== '' && BranchReadiness::isLive($stored) && AccessControl::allowsBranch($stored)) {
            return $stored;
        }

        $fallback = AccessControl::firstAllowedBranch();

        // Recover sessions created before the readiness guard was installed.
        if (is_array($user) && $stored !== $fallback) {
            $user['hospital'] = $fallback;
            $user['hospital_recovered_at'] = date('c');
            $user['hospital_recovery_reason'] = $stored === ''
                ? 'MISSING_BRANCH_CONTEXT'
                : 'BRANCH_NOT_READY_FOR_LIVE_VIEWS';
            Session::put('user', $user);
        }

        return $fallback;
    }

    public static function attempt(string $username, string $password, string $hospitalCode = 'njch'): bool
    {
        $hospitalCode = \normalize_hospital_code($hospitalCode ?: \default_hospital());
        if (!BranchReadiness::isLive($hospitalCode)) {
            return false;
        }

        $repo = new UserRepository($hospitalCode);
        $user = $repo->findDashboardUserByLegacyPassword($username, $password);

        if (!$user) {
            return false;
        }

        $legacyDashboardAccess = (int)($user['dashboard_role'] ?? 0) === 1;
        $aclDashboardAccess = false;
        try {
            $aclDashboardAccess = (new AccessControlRepository())->userHasActiveRole(
                (string)($user['name'] ?? $username)
            );
        } catch (Throwable $e) {
            error_log('[Auth ACL] ' . $e->getMessage());
        }
        if (!$legacyDashboardAccess && !$aclDashboardAccess) {
            return false;
        }

        Session::regenerate();
        Session::put('user', [
            'name' => (string) ($user['name'] ?? $username),
            'username' => (string) ($user['name'] ?? $username),
            'hospital' => $hospitalCode,
            'dashboard_role' => (int) ($user['dashboard_role'] ?? 0),
            'dashboard_role_fin' => (int) ($user['dashboard_role_fin'] ?? 0),
            'dashboard_role_revenue' => (int) ($user['dashboard_role_revenue'] ?? $user['dashboard_role'] ?? 0),
            'login_at' => date('c'),
        ]);

        AccessControl::refresh();
        $allowedHospital = AccessControl::firstAllowedBranch();
        if (!AccessControl::allowsBranch($hospitalCode) && $allowedHospital !== '') {
            $sessionUser = self::user();
            if ($sessionUser) {
                $sessionUser['hospital'] = $allowedHospital;
                Session::put('user', $sessionUser);
            }
        }

        return self::check();
    }

    public static function setHospital(string $hospitalCode): bool
    {
        $hospitalCode = \normalize_hospital_code($hospitalCode);
        if (!BranchReadiness::isLive($hospitalCode) || !AccessControl::allowsBranch($hospitalCode)) {
            return false;
        }

        $user = self::user();
        if (!$user) {
            return false;
        }

        $user['hospital'] = $hospitalCode;
        $user['hospital_changed_at'] = date('c');
        Session::put('user', $user);
        return true;
    }

    public static function logout(): void
    {
        self::clearRememberedState();
        Session::destroy();
    }

    public static function requireLogin(): void
    {
        if (!self::check()) {
            \redirect('index.php?page=login');
        }
    }

    private static function clearRememberedState(): void
    {
        Session::forget('user');
    }
}
