<?php

declare(strict_types=1);

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

use App\Repositories\VisitsRepository;
use App\Services\ChartDataService;
use App\Services\PatientActivityParityService;

$root = dirname(__DIR__);
$format = strtolower((string)($_GET['format'] ?? 'text'));
$browserMode = (string)($_GET['browser'] ?? '0') === '1';
$runLive = (string)($_GET['run_live'] ?? '1') !== '0';
if ($format === 'json' || $browserMode) {
    ini_set('display_errors', '0');
}

$hospital = strtolower(trim((string)($_GET['hospital'] ?? 'njch')));
$hospitals = config('hospitals', []);
if (!is_array($hospitals) || !array_key_exists($hospital, $hospitals)) {
    $hospital = 'njch';
}

$remote = (string)($_SERVER['REMOTE_ADDR'] ?? '');
$isLocal = in_array($remote, ['127.0.0.1', '::1', 'localhost', ''], true);
$providedToken = (string)($_GET['token'] ?? '');
$expectedToken = trim((string)env('DDB_QA_TOKEN', ''));
$tokenOk = $expectedToken !== '' && hash_equals($expectedToken, $providedToken);
if (!$isLocal && !$tokenOk) {
    http_response_code(403);
    header('Content-Type: text/plain; charset=UTF-8');
    echo "Forbidden. Phase 10.10 QA is local-only unless DDB_QA_TOKEN is configured.\n";
    exit;
}

$currentYear = (int)date('Y');
$year = filter_var($_GET['year'] ?? null, FILTER_VALIDATE_INT);
$year = $year !== false && $year !== null ? (int)$year : $currentYear - 1;
$compareYear = filter_var($_GET['compare_year'] ?? null, FILTER_VALIDATE_INT);
$compareYear = $compareYear !== false && $compareYear !== null ? (int)$compareYear : $year - 1;
$fromDate = (string)($_GET['from_date'] ?? sprintf('%04d-01-01', $year));
$toDate = (string)($_GET['to_date'] ?? sprintf('%04d-03-31', $year));

$checks = [];
$add = static function (string $name, bool $ok, string $detail = '') use (&$checks): void {
    $checks[] = ['name' => $name, 'status' => $ok ? 'PASS' : 'FAIL', 'detail' => $detail];
};

$version = [];
if (is_file($root . '/DDB_VERSION.json')) {
    $decoded = json_decode((string)file_get_contents($root . '/DDB_VERSION.json'), true);
    $version = is_array($decoded) ? $decoded : [];
}

$controllerSource = is_file($root . '/app/Controllers/OperationsController.php') ? (string)file_get_contents($root . '/app/Controllers/OperationsController.php') : '';
$currentSource = is_file($root . '/app/Repositories/VisitsRepository.php') ? (string)file_get_contents($root . '/app/Repositories/VisitsRepository.php') : '';
$legacySource = is_file($root . '/app/Repositories/LegacyPatientActivityRepository.php') ? (string)file_get_contents($root . '/app/Repositories/LegacyPatientActivityRepository.php') : '';
$serviceSource = is_file($root . '/app/Services/PatientActivityParityService.php') ? (string)file_get_contents($root . '/app/Services/PatientActivityParityService.php') : '';
$viewSource = is_file($root . '/app/Views/operations/module.php') ? (string)file_get_contents($root . '/app/Views/operations/module.php') : '';
$layoutSource = is_file($root . '/app/Views/layouts/main.php') ? (string)file_get_contents($root . '/app/Views/layouts/main.php') : '';
$cssSource = is_file($root . '/public/assets/css/patient-activity-executive-parity.css') ? (string)file_get_contents($root . '/public/assets/css/patient-activity-executive-parity.css') : '';

$installedRelease = (string)($version['release'] ?? '');
$releaseCompatible = $installedRelease !== '' && version_compare($installedRelease, '10.10.0', '>=');
$add('release_version_compatible', $releaseCompatible, $installedRelease !== '' ? $installedRelease : 'missing');
$add('legacy_selected_branch_contracts_mapped',
    strpos($legacySource, 'monthlyOutpatientVisits(') !== false
    && strpos($legacySource, 'monthlyEmergencyVisits(') !== false
    && strpos($legacySource, 'monthlyAdmissions(') !== false
    && strpos($legacySource, 'followupMix(') !== false,
    'gmov_s + perv_s + padm_s + vfr');
$add('independent_legacy_execution_path',
    strpos($legacySource, 'Database::fetchAll') !== false
    && strpos($legacySource, 'new VisitsRepository') === false
    && strpos($legacySource, 'VisitsRepository::') === false,
    'LegacyPatientActivityRepository');
$add('year_mode_supported', strpos($viewSource, 'value="year"') !== false && strpos($controllerSource, "['year', 'range']") !== false, 'year comparison');
$add('date_range_mode_supported', strpos($viewSource, 'value="range"') !== false && strpos($currentSource, 'current_from') !== false, 'from_date + to_date');
$add('same_year_range_guard', strpos($controllerSource, "\$from->format('Y') !== \$to->format('Y')") !== false, 'same-year current range');
$add('compare_year_supported', strpos($controllerSource, 'compare_year') !== false && strpos($currentSource, 'compareYear') !== false, 'compare_year');
$add('branch_context_preserved', strpos($controllerSource, 'Auth::hospital()') !== false, 'active hospital context');
$add('executive_ui_standard', strpos($cssSource, '--patient1010-body: 16px') !== false && strpos($cssSource, '--patient1010-body-ar: 17px') !== false, '16px EN / 17px AR');
$add('executive_period_strip', strpos($viewSource, 'patient1010-period-strip') !== false, 'mode + current + comparison + branch');
$visitsViewStart = strpos($viewSource, 'patient1010-control');
$visitsViewEnd = strpos($viewSource, '<?php elseif ($isDoctors): ?>', $visitsViewStart !== false ? $visitsViewStart : 0);
$visitsViewScope = ($visitsViewStart !== false && $visitsViewEnd !== false) ? substr($viewSource, $visitsViewStart, $visitsViewEnd - $visitsViewStart) : '';
$add('executive_no_raw_technical_error', $visitsViewScope !== '' && strpos($visitsViewScope, '<pre>') === false && strpos($visitsViewScope, 'Oracle returned an error') === false, 'no raw exception in Visits executive UI');
$add('three_chart_render_contract', strpos($viewSource, '__DDB_PATIENT_ACTIVITY_CHART_GATE__') !== false && strpos($layoutSource, 'patient-activity-executive-parity.css') !== false, 'OPD + ER + Admissions');
$add('parity_service_eight_checks', strpos($serviceSource, "'gmov_s'") !== false && strpos($serviceSource, "'perv_s'") !== false && strpos($serviceSource, "'padm_s'") !== false && strpos($serviceSource, "'vfr'") !== false, '4 functions x 2 modes');
$writeText = strtolower($currentSource . "\n" . $legacySource . "\n" . $serviceSource);
$hasWrite = preg_match('/\b(insert\s+into|update\s+[a-z0-9_]+\s+set|delete\s+from|create\s+table|alter\s+table)\b/i', $writeText) === 1;
$add('oracle_write_operations_none', !$hasWrite, 'SELECT only');

$parity = null;
$liveError = '';
$chartPayloads = [];
if ($runLive) {
    try {
        $parity = (new PatientActivityParityService($hospital))->run($year, $compareYear, $fromDate, $toDate);
        $yearFunctions = $parity['modes']['year']['functions'] ?? [];
        $rangeFunctions = $parity['modes']['date_range']['functions'] ?? [];
        $yearFailures = count(array_filter($yearFunctions, static function (array $r): bool { return ($r['status'] ?? '') !== 'PASS'; }));
        $rangeFailures = count(array_filter($rangeFunctions, static function (array $r): bool { return ($r['status'] ?? '') !== 'PASS'; }));
        $add('live_year_mode_parity', count($yearFunctions) === 4 && $yearFailures === 0, count($yearFunctions) . '/4 functions; failures=' . $yearFailures);
        $add('live_date_range_parity', count($rangeFunctions) === 4 && $rangeFailures === 0, count($rangeFunctions) . '/4 functions; failures=' . $rangeFailures);
        $add('live_parity_total_checks', (int)($parity['functions_checked'] ?? 0) === 8, (string)($parity['functions_checked'] ?? 0) . ' / 8');
        $add('live_parity_write_operations_none', ($parity['write_operations'] ?? '') === 'NONE', (string)($parity['write_operations'] ?? 'unknown'));

        $repo = new VisitsRepository($hospital);
        $chartService = new ChartDataService();
        $chartPayloads = [
            'opd' => $chartService->comparePayload($repo->monthlyOutpatientVisits($year, $compareYear), 'Monthly outpatient visits', $year, $compareYear),
            'er' => $chartService->comparePayload($repo->monthlyEmergencyVisits($year, $compareYear), 'Monthly emergency visits', $year, $compareYear),
            'admissions' => $chartService->comparePayload($repo->monthlyAdmissions($year, $compareYear), 'Monthly admissions', $year, $compareYear),
        ];
        $add('live_three_chart_payloads_available', count($chartPayloads) === 3, count($chartPayloads) . ' / 3');
    } catch (Throwable $e) {
        $liveError = $e->getMessage();
        $add('live_year_mode_parity', false, 'Execution error');
        $add('live_date_range_parity', false, 'Execution error');
        $add('live_parity_total_checks', false, '0 / 8');
        $add('live_parity_write_operations_none', true, 'NONE');
        $add('live_three_chart_payloads_available', false, '0 / 3');
    }
}

if ($browserMode) {
    header('Content-Type: text/html; charset=UTF-8');
    $safePayloads = json_encode($chartPayloads, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
    ?>
<!doctype html>
<html lang="en" data-browser-gate="PENDING" data-browser-expected="3" data-browser-rendered="0" data-browser-failed="0">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Phase 10.10 Patient Activity Browser Gate</title>
<style>body{font-family:Segoe UI,Tahoma,Arial;background:#f8fafc;margin:0;padding:20px}.grid{display:grid;gap:18px}.card{background:#fff;border:1px solid #e2e8f0;border-radius:18px;padding:16px}canvas{width:100%;min-height:280px}</style>
<script src="assets/js/charts.js?v=phase10-10-patient-activity-parity" defer></script>
</head>
<body>
<div class="grid">
<?php foreach ($chartPayloads as $key => $payload): ?>
    <div class="card"><canvas id="patient_qa_chart_<?= e($key) ?>" height="132" data-patient-qa-chart="<?= e($key) ?>" data-chart-rendered="false"></canvas></div>
<?php endforeach; ?>
</div>
<script id="patient_qa_payloads" type="application/json"><?= $safePayloads ?: '{}' ?></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
    var gate = { expected: 3, rendered: 0, failed: 0 };
    try {
        var payloads = JSON.parse(document.getElementById('patient_qa_payloads').textContent || '{}');
        ['opd', 'er', 'admissions'].forEach(function (key) {
            try {
                var result = window.renderBarCompareChart('patient_qa_chart_' + key, payloads[key] || {});
                if (result && result.rendered) gate.rendered += 1; else gate.failed += 1;
            } catch (e) { gate.failed += 1; }
        });
    } catch (e) { gate.failed = 3; }
    var ok = gate.expected === 3 && gate.rendered === 3 && gate.failed === 0;
    document.documentElement.setAttribute('data-browser-expected', String(gate.expected));
    document.documentElement.setAttribute('data-browser-rendered', String(gate.rendered));
    document.documentElement.setAttribute('data-browser-failed', String(gate.failed));
    document.documentElement.setAttribute('data-browser-gate', ok ? 'PASS' : 'FAIL');
});
</script>
</body>
</html>
<?php
    exit;
}

$failures = count(array_filter($checks, static function (array $c): bool { return $c['status'] === 'FAIL'; }));
$result = [
    'schema_version' => '1.0',
    'phase' => '10.10',
    'title' => 'Patient Activity Legacy Functional Parity',
    'hospital' => strtoupper($hospital),
    'year' => $year,
    'compare_year' => $compareYear,
    'range_from' => $fromDate,
    'range_to' => $toDate,
    'run_live' => $runLive,
    'write_operations' => 'NONE',
    'checks' => $checks,
    'parity' => $parity,
    'live_error' => $liveError,
    'pass_gates' => count($checks) - $failures,
    'fail_gates' => $failures,
    'status' => $failures === 0 ? 'PASS' : 'FAIL',
];

if ($format === 'json') {
    header('Content-Type: application/json; charset=UTF-8');
    echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

header('Content-Type: text/plain; charset=UTF-8');
echo "Patient Activity Legacy Functional Parity QA\n";
echo "Phase: 10.10 - Patient Activity Legacy Functional Parity\n";
echo 'Hospital: ' . strtoupper($hospital) . "\n";
echo "Executive standard: Executive Leadership UI Standard v1.0\n";
echo "Write operations: NONE\n\n";
echo "QA Gates:\n";
foreach ($checks as $check) {
    echo '[' . $check['status'] . '] ' . str_pad($check['name'], 48) . ' | ' . $check['detail'] . "\n";
}
if (is_array($parity)) {
    echo "\nParity Summary:\n";
    foreach (['year' => 'YEAR', 'date_range' => 'DATE RANGE'] as $modeKey => $modeLabel) {
        foreach (($parity['modes'][$modeKey]['functions'] ?? []) as $fn) {
            echo '[' . ($fn['status'] ?? 'FAIL') . '] ' . str_pad($modeLabel . ' / ' . (string)($fn['legacy_function'] ?? ''), 38)
                . ' | current diff=' . number_format((float)($fn['current_total_difference'] ?? 0), 0, '.', '')
                . ' | compare diff=' . number_format((float)($fn['compare_total_difference'] ?? 0), 0, '.', '')
                . "\n";
        }
    }
}
if ($liveError !== '') {
    echo "\nLive execution error: " . $liveError . "\n";
}
echo "\nQA result: " . $result['status'] . "\n";
echo 'PASS gates: ' . $result['pass_gates'] . "\n";
echo 'FAIL gates: ' . $result['fail_gates'] . "\n";
echo "QA is read-only. No Oracle, review, governance, or audit row is modified.\n";
