<?php

declare(strict_types=1);

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

use App\Services\InpatientDailyRevenueService;
use App\Services\XlsxExportService;

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

$rows = [
    [
        'financlassid' => 365,
        'financial_class' => 'CENTER FOR NATIONAL HEALTH INSURANCE',
        'los' => 10,
        'total_los' => 30,
        'patient_share_total' => 0,
        'company_share_total' => 0,
        'unit_name' => 'ICU',
        'bed_counts' => 10,
    ],
    [
        'financlassid' => 365,
        'financial_class' => 'CENTER FOR NATIONAL HEALTH INSURANCE',
        'los' => 10,
        'total_los' => 31,
        'patient_share_total' => 0,
        'company_share_total' => 0,
        'unit_name' => 'ICU',
        'bed_counts' => 10,
    ],
    [
        'financlassid' => 170,
        'financial_class' => 'TCS',
        'los' => 3,
        'total_los' => 3,
        'patient_share_total' => 0,
        'company_share_total' => 0,
        'unit_name' => 'Ward A',
        'bed_counts' => 20,
    ],
    [
        'financlassid' => 170,
        'financial_class' => 'TCS',
        'los' => 4,
        'total_los' => 4,
        'patient_share_total' => 0,
        'company_share_total' => 0,
        'unit_name' => 'Ward A',
        'bed_counts' => 20,
    ],
    [
        'financlassid' => 170,
        'financial_class' => 'TCS',
        'los' => 9,
        'total_los' => 9,
        'patient_share_total' => 0,
        'company_share_total' => 0,
        'unit_name' => 'Ward A',
        'bed_counts' => 20,
    ],
    [
        'financlassid' => 1,
        'financial_class' => 'CASH',
        'los' => 4,
        'total_los' => 4,
        'patient_share_total' => 7864.66,
        'company_share_total' => 0,
        'unit_name' => 'Ward B',
        'bed_counts' => 15,
    ],
    [
        'financlassid' => 777,
        'financial_class' => 'OTHER INSURANCE',
        'los' => 5,
        'total_los' => 5,
        'patient_share_total' => 0,
        'company_share_total' => 12836.52,
        'unit_name' => 'Ward B',
        'bed_counts' => 15,
    ],
];

$report = (new InpatientDailyRevenueService())->build($rows);
$patients = $report['patients'];

$add('nhic_total_los_30', abs((float)$patients[0]['daily_revenue'] - 4746.87) < 0.001, (string)$patients[0]['daily_revenue']);
$add('nhic_total_los_31', abs((float)$patients[1]['daily_revenue'] - 2373.00) < 0.001, (string)$patients[1]['daily_revenue']);
$add('tcs_los_3', abs((float)$patients[2]['daily_revenue'] - 2250.00) < 0.001, (string)$patients[2]['daily_revenue']);
$add('tcs_los_4', abs((float)$patients[3]['daily_revenue'] - 1950.00) < 0.001, (string)$patients[3]['daily_revenue']);
$add('tcs_los_9', abs((float)$patients[4]['daily_revenue'] - 1750.00) < 0.001, (string)$patients[4]['daily_revenue']);
$add('cash_patient_share_per_los', abs((float)$patients[5]['daily_revenue'] - 1966.17) < 0.001, (string)$patients[5]['daily_revenue']);
$add('insurance_company_share_per_los', abs((float)$patients[6]['daily_revenue'] - 2567.30) < 0.001, (string)$patients[6]['daily_revenue']);
$add('all_sample_rows_auto_calculated', (int)$report['summary']['review_count'] === 0, (string)$report['summary']['review_count']);

$root = dirname(__DIR__);
$repoSource = (string)file_get_contents($root . '/app/Repositories/InpatientDailyRevenueRepository.php');
$sqlSource = (string)file_get_contents($root . '/database/inpatient_daily_revenue_engine.sql');
$routeSource = (string)file_get_contents($root . '/public/index.php');
$layoutSource = (string)file_get_contents($root . '/app/Views/layouts/main.php');
$controllerSource = (string)file_get_contents($root . '/app/Controllers/InpatientDailyRevenueController.php');
$viewSource = (string)file_get_contents($root . '/app/Views/inpatient_daily_revenue/index.php');
$oracleContractTestSource = (string)file_get_contents($root . '/tools/test_inpatient_daily_revenue_oracle_contract.php');
$xlsxSource = (string)file_get_contents($root . '/app/Services/XlsxExportService.php');

$add(
    'no_direct_legacy_revenue_procedure_call',
    preg_match('/\bSP_IPD_OPD_VAT_REVENUE\s*\(/i', $repoSource) !== 1
        && preg_match('/\bSP_INPATIENT_REVENUE_DATA\s*\(/i', $repoSource) !== 1,
    'repository execution path'
);
$add('current_inpatients_only', stripos($sqlSource, 'bt.enddate IS NULL') !== false, 'RCP_BED_TRANS active bed condition');
$add(
    'los_rule_365_only_first_admission',
    stripos($sqlSource, 'WHEN a.financlassid = 365') !== false
        && stripos($sqlSource, 'ELSE TRUNC(SYSDATE) - TRUNC(a.visit_start_date) + 1') !== false,
    'conditional Total LOS'
);
$add('ten_revenue_source_categories', preg_match_all('/\/\*\s*(?:[1-9]|10)\)/', $sqlSource) === 10, '10 categories');
$add(
    'no_invalid_reg_packages_in_out_pkg_reference',
    stripos($repoSource, 'pkg.in_out_pkg') === false
        && stripos($sqlSource, 'pkg.in_out_pkg') === false
        && stripos($repoSource, 'LEFT JOIN reg_packages pkg') === false
        && stripos($sqlSource, 'LEFT JOIN reg_packages pkg') === false,
    'prevents NJCH ORA-00904 on REG_PACKAGES.IN_OUT_PKG'
);
$add(
    'residence_package_flag_uses_residence_transaction',
    stripos($repoSource, 'NVL(r.in_out_pkg, 0)') !== false
        && stripos($sqlSource, 'NVL(r.in_out_pkg, 0)') !== false,
    'legacy residence IN_OUT_PKG is read from PACC_PAT_RES_TRAN alias r'
);
$add(
    'live_oracle_contract_smoke_gate_present',
    strpos($repoSource, 'public function validateOracleContract(): void') !== false
        && strpos($repoSource, 'public function oracleContractValidationSql(): string') !== false
        && strpos($repoSource, 'WHERE 1 = 0') !== false,
    'read-only zero-row Oracle identifier validation gate'
);
$add(
    'live_oracle_contract_test_tool_present',
    strpos($oracleContractTestSource, "new InpatientDailyRevenueRepository('njch')") !== false
        && strpos($oracleContractTestSource, 'validateOracleContract();') !== false
        && strpos($oracleContractTestSource, "'oracle_writes' => 'NONE'") !== false,
    'target-environment smoke test catches ORA-00904 before page use'
);
$add('routes_registered', strpos($routeSource, "case 'inpatient-daily-revenue':") !== false && strpos($routeSource, "case 'inpatient-daily-revenue-export':") !== false, 'page + export');
$add('revenue_role_navigation', strpos($layoutSource, "'inpatient-daily-revenue'") !== false && strpos($layoutSource, "'visible' => \$canAccessRevenue") !== false, 'revenue permission');
$add(
    'controller_load_contract_no_typed_byref_output',
    strpos($controllerSource, 'string &$errorMessage') === false
        && strpos($controllerSource, "'report' =>") !== false
        && strpos($controllerSource, "'errorMessage' =>") !== false,
    'structured loadReport result prevents null-by-reference TypeError'
);
$add(
    'controller_index_and_export_use_structured_load_result',
    substr_count($controllerSource, '$loadResult = $this->loadReport($hospitalCode);') === 2
        && substr_count($controllerSource, '$errorMessage = $loadResult[\'errorMessage\'];') === 2,
    'index + export'
);

$add(
    'view_php74_compatible_no_match_expression',
    preg_match('/\bmatch\s*\(/', $viewSource) !== 1,
    'PHP 8 match syntax must not exist in the runtime view'
);
$add(
    'view_method_label_lookup_preserved',
    strpos($viewSource, '$methodLabelsAr = [') !== false
        && strpos($viewSource, "'nhic_over_30' =>") !== false
        && strpos($viewSource, "'cash_patient_share_per_los' =>") !== false
        && strpos($viewSource, '$methodLabelsAr[$methodCode] ?? \'حصة الشركة ÷ مدة الإقامة\'') !== false,
    'PHP 7.4-compatible payer method label mapping'
);


$add(
    'professional_export_dynamic_filename_pattern',
    strpos($controllerSource, 'strtoupper($hospitalCode) . \'_Daily_Revenue_\' . date(\'Y-m-d\') . \'.xlsx\'') !== false,
    'hospital + date filename'
);
$add(
    'professional_export_two_sheet_contract',
    strpos($xlsxSource, '<sheet name="Summary"') !== false
        && strpos($xlsxSource, '<sheet name="Daily Revenue"') !== false
        && strpos($xlsxSource, '<sheet name="Detailed Audit"') === false
        && strpos($xlsxSource, '<sheet name="Needs Review"') === false,
    'Summary + manual-style Daily Revenue only'
);
$add(
    'manual_style_daily_revenue_layout_preserved_and_improved',
    strpos($xlsxSource, "'Attending Doctor', 'Financial Class', 'LOS', 'Nationality', 'Patient Name', 'Patient ID'") !== false
        && strpos($xlsxSource, "'Time', 'Date', 'Daily Revenue', 'Bed', 'Room', 'Initial Admission', 'Total LOS'") !== false
        && strpos($xlsxSource, "'Unit Daily Revenue Total'") !== false
        && strpos($xlsxSource, "'Grand Total Daily Revenue'") !== false,
    '13 familiar columns + unit subtotal under Daily Revenue + grand total'
);
$add(
    'obsolete_export_sheets_removed_from_runtime_builder',
    strpos($xlsxSource, 'buildDetailedAuditSheet') === false
        && strpos($xlsxSource, 'buildNeedsReviewSheet') === false
        && strpos($xlsxSource, "'xl/worksheets/sheet3.xml'") === false
        && strpos($xlsxSource, "'xl/worksheets/sheet4.xml'") === false,
    'no Detailed Audit / Needs Review worksheet builders or package entries'
);
$add(
    'executive_summary_payer_chart_packaged',
    strpos($xlsxSource, "xl/charts/chart1.xml") !== false
        && strpos($xlsxSource, 'Top Payers by Daily Revenue') !== false,
    'native XLSX chart package'
);
$add(
    'xlsx_export_php74_compatibility_contract',
    preg_match('/\bmatch\s*\(/', $xlsxSource) !== 1
        && strpos($xlsxSource, '?->') === false
        && stripos($xlsxSource, 'str_contains(') === false
        && stripos($xlsxSource, 'str_starts_with(') === false
        && stripos($xlsxSource, 'str_ends_with(') === false
        && preg_match('/\breadonly\b|\benum\s+[A-Za-z_]/', $xlsxSource) !== 1,
    'no PHP 8-only syntax in XLSX runtime service'
);
$add(
    'view_advertises_professional_workbook',
    strpos($viewSource, 'Professional finance workbook') !== false
        && strpos($viewSource, 'Export Professional Excel') !== false
        && strpos($viewSource, 'summary + unit totals') !== false,
    'user-facing export contract'
);

$tmp = sys_get_temp_dir() . '/ddb_idr_qa_' . bin2hex(random_bytes(6)) . '.xlsx';
try {
    (new XlsxExportService())->createFinalWorkbookFile($tmp, $report);
    $signature = is_file($tmp) ? (string)file_get_contents($tmp, false, null, 0, 2) : '';
    $add('professional_xlsx_created', is_file($tmp) && filesize($tmp) > 5000 && $signature === 'PK', is_file($tmp) ? (string)filesize($tmp) : 'missing');

    $archive = new PharData($tmp);
    $workbookXml = isset($archive['xl/workbook.xml']) ? (string)$archive['xl/workbook.xml']->getContent() : '';
    $dailyXml = isset($archive['xl/worksheets/sheet2.xml']) ? (string)$archive['xl/worksheets/sheet2.xml']->getContent() : '';
    $chartExists = isset($archive['xl/charts/chart1.xml']);

    $add('xlsx_runtime_two_sheets', substr_count($workbookXml, '<sheet name=') === 2 && strpos($workbookXml, 'Detailed Audit') === false && strpos($workbookXml, 'Needs Review') === false, '2 worksheets only');
    $add('xlsx_runtime_manual_daily_sheet', strpos($dailyXml, 'Unit Daily Revenue Total') !== false && strpos($dailyXml, 'Grand Total Daily Revenue') !== false, 'manual-style grouped unit export');
    $unitSubtotalMatches = preg_match_all('/<row r="(\d+)"[^>]*>.*?<c r="A\1"[^>]*>.*?Unit Daily Revenue Total.*?<\/c>.*?<c r="I\1"[^>]*t="n"><v>[^<]+<\/v><\/c>.*?<\/row>/s', $dailyXml, $unitSubtotalRows);
    $add('xlsx_runtime_unit_subtotal_under_daily_revenue_column', $unitSubtotalMatches >= 1, (string)$unitSubtotalMatches . ' unit subtotal rows in column I');
    $add('xlsx_runtime_native_payer_chart', $chartExists, 'xl/charts/chart1.xml');
} catch (Throwable $e) {
    $add('professional_xlsx_created', false, $e->getMessage());
} finally {
    @unlink($tmp);
    @unlink($tmp . '.zip');
}

$failures = count(array_filter($checks, static fn(array $check): bool => $check['status'] === 'FAIL'));
$result = [
    'phase' => 'H11.0-P10.5-R1',
    'title' => 'Daily Revenue Workbook Simplification & Unit Subtotal Alignment',
    'checks' => $checks,
    'pass_gates' => count($checks) - $failures,
    'fail_gates' => $failures,
    'status' => $failures === 0 ? 'PASS' : 'FAIL',
];

echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
exit($failures === 0 ? 0 : 1);
