<?php

declare(strict_types=1);

require dirname(__DIR__) . '/app/bootstrap.php';

use App\Core\Database;
use App\Repositories\AccessControlRepository;

$branch = strtolower(trim((string)($argv[1] ?? 'njch')));
$siteAdmin = trim((string)($argv[2] ?? '7124'));

try {
    $repository = new AccessControlRepository($branch);
    $roles = $repository->listRoles();
    $counts = $repository->accessCounts();
    $context = $repository->contextForUser($siteAdmin);

    $roleMap = [];

    foreach ($roles as $role) {
        $roleMap[(string)($role['role_code'] ?? '')] = $role;
    }

    $siteAdminRoles = array_values(array_filter(array_map(
        static function (array $role): string {
            return (string)($role['role_code'] ?? '');
        },
        (array)($context['roles'] ?? [])
    )));

    $duplicates = Database::fetchAll($branch, "
        SELECT
            UPPER(USERNAME) username,
            COUNT(*) role_count
        FROM DASH_ACL_USER_ROLES
        GROUP BY UPPER(USERNAME)
        HAVING COUNT(*) > 1
    ");

    $invalidBranchScopes = Database::fetchAll($branch, "
        SELECT
            USERNAME username,
            HOSPITAL_CODE hospital_code
        FROM DASH_ACL_USER_BRANCHES
        WHERE NVL(IS_ACTIVE, 1) = 1
          AND LOWER(HOSPITAL_CODE)
              NOT IN ('*', 'njch', 'mnh')
    ");

    $checks = [
        'schema_ready' => $repository->schemaReady(),
        'role_management_ready' => $repository->roleManagementReady(),
        'site_admin_ready' => isset($roleMap['SITE_ADMIN']),
        'general_manager_ready' => isset($roleMap['GENERAL_MANAGER']),
        'site_admin_policy_all' =>
            (string)($roleMap['SITE_ADMIN']['policy_mode'] ?? '') === 'ALL',
        'general_manager_policy_business' =>
            (string)($roleMap['GENERAL_MANAGER']['policy_mode'] ?? '')
            === 'ALL_BUSINESS',
        'requested_site_admin_assigned' =>
            in_array('SITE_ADMIN', $siteAdminRoles, true),
        'one_role_per_user' => $duplicates === [],
        'branch_scopes_valid' => $invalidBranchScopes === [],
        'active_roles_present' =>
            (int)($counts['active_roles'] ?? 0) >= 2,
    ];

    $failed = [];

    foreach ($checks as $name => $passed) {
        if (!$passed) {
            $failed[] = $name;
        }
    }

    $result = [
        'schema' => 'DDB_ACCESS_CONTROL_P14_2_LIVE_ACCEPTANCE',
        'captured_at' => date(DATE_ATOM),
        'branch' => strtoupper($branch),
        'site_admin' => $siteAdmin,
        'counts' => $counts,
        'roles' => array_map(
            static function (array $role): array {
                return [
                    'role_code' => (string)($role['role_code'] ?? ''),
                    'role_name_en' => (string)($role['role_name_en'] ?? ''),
                    'policy_mode' => (string)($role['policy_mode'] ?? ''),
                    'is_protected' => (int)($role['is_protected'] ?? 0),
                    'is_active' => (int)($role['is_active'] ?? 0),
                    'user_count' => (int)($role['user_count'] ?? 0),
                ];
            },
            $roles
        ),
        'duplicate_role_users' => $duplicates,
        'invalid_branch_scopes' => $invalidBranchScopes,
        'checks' => $checks,
        'failed' => $failed,
        'status' => $failed === [] ? 'PASS' : 'FAIL',
        'oracle_writes' => 'NONE',
    ];
} catch (Throwable $error) {
    $result = [
        'schema' => 'DDB_ACCESS_CONTROL_P14_2_LIVE_ACCEPTANCE',
        'captured_at' => date(DATE_ATOM),
        'branch' => strtoupper($branch),
        'site_admin' => $siteAdmin,
        'status' => 'FAIL',
        'failed' => ['live_execution'],
        'error' => preg_replace('/\s+/', ' ', (string)$error->getMessage()),
        'oracle_writes' => 'NONE',
    ];
}

$dir = dirname(__DIR__) . '/storage/evidence/access_control';

if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($dir)) {
    throw new RuntimeException(
        'Cannot create access-control evidence directory.'
    );
}

$file = $dir
    . '/ACCESS_CONTROL_R45_P14_2_LIVE_ACCEPTANCE_'
    . date('Ymd_His')
    . '.json';

file_put_contents(
    $file,
    json_encode(
        $result,
        JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
    ),
    LOCK_EX
);

echo json_encode(
    $result + ['evidence_file' => $file],
    JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
), PHP_EOL;

exit(($result['status'] ?? 'FAIL') === 'PASS' ? 0 : 1);
