<?php

declare(strict_types=1);

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

use App\Repositories\DiagnosticsRepository;
use App\Services\ChartDataService;
use App\Services\DiagnosticsParityService;

$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.12 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/LabRadiologyController.php') ? (string)file_get_contents($root . '/app/Controllers/LabRadiologyController.php') : '';
$currentSource = is_file($root . '/app/Repositories/DiagnosticsRepository.php') ? (string)file_get_contents($root . '/app/Repositories/DiagnosticsRepository.php') : '';
$legacySource = is_file($root . '/app/Repositories/LegacyDiagnosticsRepository.php') ? (string)file_get_contents($root . '/app/Repositories/LegacyDiagnosticsRepository.php') : '';
$serviceSource = is_file($root . '/app/Services/DiagnosticsParityService.php') ? (string)file_get_contents($root . '/app/Services/DiagnosticsParityService.php') : '';
$viewSource = is_file($root . '/app/Views/lab_radiology/index.php') ? (string)file_get_contents($root . '/app/Views/lab_radiology/index.php') : '';
$layoutSource = is_file($root . '/app/Views/layouts/main.php') ? (string)file_get_contents($root . '/app/Views/layouts/main.php') : '';
$indexSource = is_file($root . '/public/index.php') ? (string)file_get_contents($root . '/public/index.php') : '';
$cssSource = is_file($root . '/public/assets/css/diagnostics-executive-parity.css') ? (string)file_get_contents($root . '/public/assets/css/diagnostics-executive-parity.css') : '';

$installedRelease = (string)($version['release'] ?? '');
$add('release_version_compatible', $installedRelease !== '' && version_compare($installedRelease, '10.12.0', '>='), $installedRelease !== '' ? $installedRelease : 'missing');
$add('legacy_selected_branch_contracts_mapped',
    strpos($legacySource, 'monthlyLabTests(') !== false
    && strpos($legacySource, 'monthlyRadiologyTests(') !== false
    && stripos($legacySource, 'Rcp_Lab_Service_Reservation') !== false
    && stripos($legacySource, 'RCP_RAD_SERVICE_RESERVATION') !== false,
    'plts_s + prts_s selected-branch contracts');
$add('legacy_sysdate_cutoff_preserved',
    substr_count(strtoupper($legacySource), '<= SYSDATE') >= 1
    && stripos($legacySource, 'expecteddonedate') !== false
    && stripos($legacySource, 'machine_sch_from') !== false,
    'lab/radiology historical cutoff');
$add('independent_legacy_execution_path',
    strpos($legacySource, 'Database::fetchAll') !== false
    && strpos($legacySource, 'new DiagnosticsRepository') === false
    && strpos($legacySource, 'DiagnosticsRepository::') === false,
    'LegacyDiagnosticsRepository independent path');
$add('current_oracle_sources_preserved',
    stripos($currentSource, 'rcp_lab_service_reservation') !== false
    && stripos($currentSource, 'rcp_rad_service_reservation') !== false
    && stripos($currentSource, 'expecteddonedate') !== false
    && stripos($currentSource, 'machine_sch_from') !== false
    && stripos($currentSource, 'SYSDATE') !== false,
    'lab and radiology source contracts');
$add('year_and_range_modes_supported',
    strpos($viewSource, 'value="year"') !== false
    && strpos($viewSource, 'value="range"') !== false
    && strpos($controllerSource, "['year', 'range']") !== false,
    'year + custom date range');
$add('same_year_range_guard', strpos($controllerSource, "\$from->format('Y') !== \$to->format('Y')") !== false, 'same-year 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('lab_route_is_live',
    strpos($indexSource, "case 'lab':") !== false
    && preg_match("/\['page'\s*=>\s*'lab'[^\]]*'live'\s*=>\s*true/", $layoutSource) === 1,
    'route + navigation');
$add('executive_ui_standard',
    strpos($cssSource, '--diagnostics1012-body: 16px') !== false
    && strpos($cssSource, '--diagnostics1012-body-ar: 17px') !== false
    && strpos($cssSource, '--diagnostics1012-section: clamp(24px, 2vw, 28px)') !== false,
    '16px EN / 17px AR / 24-28px sections');
$add('executive_no_raw_technical_error',
    strpos($viewSource, '<pre>') === false
    && strpos($viewSource, 'Oracle returned an error') === false
    && strpos($viewSource, '$dataError') !== false,
    'friendly executive state');
$add('two_chart_render_contract',
    strpos($viewSource, '__DDB_DIAGNOSTICS_CHART_GATE__') !== false
    && strpos($viewSource, 'gate.expected === 2') !== false
    && strpos($viewSource, "['lab', 'radiology']") !== false
    && strpos($layoutSource, 'diagnostics-executive-parity.css') !== false,
    'lab + radiology charts');
$add('parity_service_four_checks',
    substr_count($serviceSource, "'plts_s'") >= 2
    && substr_count($serviceSource, "'prts_s'") >= 2
    && strpos($serviceSource, "'functions_checked' => 4") !== false,
    '2 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 DiagnosticsParityService($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) === 2 && $yearFailures === 0, count($yearFunctions) . '/2 functions; failures=' . $yearFailures);
        $add('live_date_range_parity', count($rangeFunctions) === 2 && $rangeFailures === 0, count($rangeFunctions) . '/2 functions; failures=' . $rangeFailures);
        $add('live_parity_total_checks', (int)($parity['functions_checked'] ?? 0) === 4, (string)($parity['functions_checked'] ?? 0) . ' / 4');
        $add('live_parity_max_difference_zero', (float)($parity['max_difference'] ?? -1) === 0.0, (string)($parity['max_difference'] ?? 'missing'));
        $add('live_parity_write_operations_none', ($parity['write_operations'] ?? '') === 'NONE', (string)($parity['write_operations'] ?? 'unknown'));

        $repo = new DiagnosticsRepository($hospital);
        $chartService = new ChartDataService();
        $chartPayloads = [
            'lab' => $chartService->comparePayload($repo->monthlyLabTests($year, $compareYear), 'Monthly laboratory tests', (string)$year, (string)$compareYear),
            'radiology' => $chartService->comparePayload($repo->monthlyRadiologyTests($year, $compareYear), 'Monthly radiology tests', (string)$year, (string)$compareYear),
        ];
        $add('live_two_chart_payloads_available', count($chartPayloads) === 2, count($chartPayloads) . ' / 2');
    } 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 / 4');
        $add('live_parity_max_difference_zero', false, 'Execution error');
        $add('live_parity_write_operations_none', true, 'NONE');
        $add('live_two_chart_payloads_available', false, '0 / 2');
    }
}

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);
    if (!is_string($safePayloads)) {
        $safePayloads = '{}';
    }
    ?>
<!doctype html>
<html lang="en" data-browser-expected="2" data-browser-rendered="0" data-browser-empty="0" data-browser-failed="0" data-browser-gate="PENDING">
<head>
    <meta charset="utf-8">
    <title>Phase 10.12 Diagnostics Browser Gate</title>
    <script src="assets/js/charts.js?v=phase10-12-lab-radiology-recovery"></script>
</head>
<body>
    <canvas id="diagnostics_browser_lab" width="900" height="320"></canvas>
    <canvas id="diagnostics_browser_radiology" width="900" height="320"></canvas>
    <script>
    (function () {
        var payloads = <?= $safePayloads ?>;
        var gate = { expected: 2, rendered: 0, empty: 0, failed: 0, status: 'PENDING' };
        ['lab', 'radiology'].forEach(function (key) {
            try {
                var payload = payloads[key] || {};
                var values = [];
                (payload.series || []).forEach(function (series) {
                    (series.values || []).forEach(function (value) { values.push(Number(value || 0)); });
                });
                var hasData = values.some(function (value) { return value !== 0; });
                if (!hasData) {
                    gate.empty += 1;
                    return;
                }
                var result = window.renderBarCompareChart('diagnostics_browser_' + key, payload);
                if (result && result.rendered) {
                    gate.rendered += 1;
                } else {
                    gate.failed += 1;
                }
            } catch (error) {
                gate.failed += 1;
            }
        });
        gate.status = gate.failed === 0 && (gate.rendered + gate.empty) === gate.expected ? 'PASS' : 'FAIL';
        window.__DDB_DIAGNOSTICS_BROWSER_GATE__ = gate;
        document.documentElement.setAttribute('data-browser-rendered', String(gate.rendered));
        document.documentElement.setAttribute('data-browser-empty', String(gate.empty));
        document.documentElement.setAttribute('data-browser-failed', String(gate.failed));
        document.documentElement.setAttribute('data-browser-gate', gate.status);
        document.body.setAttribute('data-gate-complete', 'true');
    })();
    </script>
</body>
</html>
    <?php
    exit;
}

$failures = count(array_filter($checks, static function (array $row): bool { return ($row['status'] ?? '') === 'FAIL'; }));
$result = [
    'schema_version' => '1.0',
    'phase' => '10.12',
    'target_release' => '10.12.0',
    'status' => $failures === 0 ? 'PASS' : 'FAIL',
    'generated_at' => gmdate('c'),
    'hospital' => strtoupper($hospital),
    'year' => $year,
    'compare_year' => $compareYear,
    'from_date' => $fromDate,
    'to_date' => $toDate,
    'run_live' => $runLive,
    'checks' => $checks,
    'pass_gates' => count($checks) - $failures,
    'fail_gates' => $failures,
    'functions_checked' => is_array($parity) ? (int)($parity['functions_checked'] ?? 0) : 0,
    'max_difference' => is_array($parity) ? (float)($parity['max_difference'] ?? 0) : 0,
    'write_operations' => 'NONE',
    'parity' => $parity,
    'chart_payload_count' => count($chartPayloads),
    'live_error' => $liveError !== '' ? 'Execution error recorded; see server log.' : '',
];

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 "Phase 10.12 — Lab & Radiology Recovery QA\n";
echo 'Result: ' . $result['status'] . "\n";
echo 'Hospital: ' . $result['hospital'] . "\n";
echo 'Functions checked: ' . $result['functions_checked'] . "\n";
echo 'Max difference: ' . $result['max_difference'] . "\n";
echo 'Write operations: NONE' . "\n\n";
foreach ($checks as $check) {
    echo '[' . $check['status'] . '] ' . $check['name'] . ' | ' . $check['detail'] . "\n";
}
