<?php

declare(strict_types=1);

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

use App\Repositories\InpatientDailyRevenueRepository;
use App\Repositories\InpatientDailyRevenueRuleSettingsRepository;
use App\Services\InpatientDailyRevenueService;

$branchArg = trim((string)($argv[1] ?? env('DDB_QA_HOSPITALS', 'njch,mnh')));
$branches = array_values(array_unique(array_filter(array_map(
    static fn(string $value): string => normalize_hospital_code(trim($value)),
    preg_split('/\s*,\s*/', $branchArg) ?: []
), static fn(string $value): bool => $value !== '')));
if ($branches === []) {
    $branches = ['njch', 'mnh'];
}

$started = microtime(true);
$result = [
    'phase' => 'H11.0-P11.1-R5',
    'release' => '11.0.11.5',
    'title' => 'Daily Inpatient Revenue R5 Continuous LOS Multi-Branch Live Oracle Read-Only Proof',
    'mode' => 'LIVE_READ_ONLY_SCHEMA_AND_CURRENT_INPATIENT_QUERY_MULTI_BRANCH',
    'oracle_writes' => 'NONE',
    'expected_branches' => $branches,
    'status' => 'FAIL',
    'pass_branches' => 0,
    'fail_branches' => 0,
    'branches' => [],
    'elapsed_ms' => 0,
];

foreach ($branches as $hospitalCode) {
    $branchStarted = microtime(true);
    $branchResult = [
        'hospital' => $hospitalCode,
        'status' => 'FAIL',
        'schema_contract' => 'NOT_RUN',
        'live_current_inpatient_query' => 'NOT_RUN',
        'branch_resolution' => null,
        'rows_read' => 0,
        'patients_calculated' => 0,
        'configured_payer_presence' => [],
        'icu_rows_read' => 0,
        'continuous_los_rows_validated' => 0,
        'continuous_chain_extended_rows' => 0,
        'max_continuous_los' => 0,
        'query_elapsed_ms' => 0,
        'requires_nonzero_rows' => in_array($hospitalCode, ['njch', 'mnh'], true),
        'elapsed_ms' => 0,
        'message' => '',
    ];

    try {
        $rules = (new InpatientDailyRevenueRuleSettingsRepository($hospitalCode))->load();
        $repository = new InpatientDailyRevenueRepository($hospitalCode);
        $branchResult['branch_resolution'] = $repository->branchResolution();

        $repository->validateOracleContract();
        $branchResult['schema_contract'] = 'PASS';

        $queryStarted = microtime(true);
        $rows = $repository->currentInpatientsWithRevenue();
        $branchResult['query_elapsed_ms'] = (int)round((microtime(true) - $queryStarted) * 1000);
        $branchResult['live_current_inpatient_query'] = 'PASS';
        $branchResult['rows_read'] = count($rows);

        $report = (new InpatientDailyRevenueService($hospitalCode, $rules))->build($rows);
        $branchResult['patients_calculated'] = count((array)($report['patients'] ?? []));

        $payerIds = [
            'national_payer' => (int)($rules['national_payer']['company_id'] ?? 0),
            'tcs' => (int)($rules['tiered_payers']['tcs']['company_id'] ?? 0),
            'gosi' => (int)($rules['tiered_payers']['gosi']['company_id'] ?? 0),
        ];
        foreach ($payerIds as $name => $payerId) {
            $count = 0;
            foreach ($rows as $row) {
                if ((int)($row['financlassid'] ?? 0) === $payerId) {
                    $count++;
                }
            }
            $branchResult['configured_payer_presence'][$name] = [
                'company_id' => $payerId,
                'rows' => $count,
            ];
        }

        $icuTypes = array_map('strtolower', array_map('trim', array_map('strval', (array)($rules['national_payer']['icu_types'] ?? []))));
        foreach ($rows as $row) {
            $type = strtolower(trim((string)($row['nursing_unit_type'] ?? '')));
            if ($type !== '' && in_array($type, $icuTypes, true)) {
                $branchResult['icu_rows_read']++;
            }

            $los = (int)($row['los'] ?? 0);
            $totalLos = (int)($row['total_los'] ?? 0);
            $losStart = trim((string)($row['los_start_date'] ?? ''));
            if ($los < 1 || $totalLos < 1 || $los !== $totalLos || $losStart === '') {
                throw new RuntimeException('Continuous LOS contract failed for a live current-inpatient row.');
            }
            $branchResult['continuous_los_rows_validated']++;
            $branchResult['max_continuous_los'] = max((int)$branchResult['max_continuous_los'], $los);

            $admissionDate = trim((string)($row['admission_date'] ?? ''));
            if ($admissionDate !== '' && strtotime($losStart) !== false && strtotime($admissionDate) !== false && strtotime($losStart) < strtotime($admissionDate)) {
                $branchResult['continuous_chain_extended_rows']++;
            }
        }

        if ($branchResult['patients_calculated'] !== $branchResult['rows_read']) {
            throw new RuntimeException('Calculated patient count does not match the live Oracle row count.');
        }
        if ($branchResult['requires_nonzero_rows'] && $branchResult['rows_read'] <= 0) {
            throw new RuntimeException('Ready branch returned zero active inpatient rows; live data recovery is not proven.');
        }

        if ($branchResult['continuous_los_rows_validated'] !== $branchResult['rows_read']) {
            throw new RuntimeException('Continuous LOS live validation count does not match Oracle row count.');
        }

        $branchResult['status'] = 'PASS';
        $branchResult['message'] = 'Oracle schema contract, continuous inpatient LOS validation and live current-inpatient read completed without any Oracle write operation.';
        $result['pass_branches']++;
    } catch (Throwable $e) {
        $branchResult['status'] = 'FAIL';
        $branchResult['message'] = $e->getMessage();
        $branchResult['exception'] = get_class($e);
        $result['fail_branches']++;
    }

    $branchResult['elapsed_ms'] = (int)round((microtime(true) - $branchStarted) * 1000);
    $result['branches'][$hospitalCode] = $branchResult;
}

$result['status'] = ($result['fail_branches'] === 0 && $result['pass_branches'] === count($branches)) ? 'PASS' : 'FAIL';
$result['elapsed_ms'] = (int)round((microtime(true) - $started) * 1000);

echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
exit($result['status'] === 'PASS' ? 0 : 1);
