<?php

declare(strict_types=1);

require dirname(__DIR__) . '/app/bootstrap.php';
require_once __DIR__ . '/diar6b5-r2-ooxml-inspector.php';

use App\Repositories\DiarExecutiveOverviewRepository;
use App\Repositories\DiarReportDataRepository;
use App\Services\DiarApprovedWorkbookExportService;
use App\Services\DiarOoxmlPackage;
use App\Services\DiarPowerPointExportService;
use App\Services\DiarReportCatalog;

$result = [
    'result' => 'FAIL',
    'release' => 'DIAR-6B.5-R2.4',
    'scope' => 'ALL',
    'month' => '',
    'summary' => [],
    'snapshots' => [],
    'excel' => [],
    'powerpoint' => [],
    'checks' => [],
    'evidence' => [],
];

$evidenceDir = '';
$excelPath = '';
$pptPath = '';
$jsonPath = '';

try {
    if (!class_exists('DOMDocument')) {
        throw new RuntimeException('PHP_DOM_EXTENSION_REQUIRED');
    }
    if (!class_exists('ZipArchive') && !class_exists('PharData')) {
        throw new RuntimeException('PHP_ZIP_OR_PHAR_REQUIRED');
    }

    $selfTest = DiarR24OoxmlInspector::selfTest();
    if (in_array(false, $selfTest, true)) {
        throw new RuntimeException('OOXML_INSPECTOR_SELF_TEST_FAILED|' . implode(',', array_keys(array_filter($selfTest, static function ($value): bool { return !$value; }))));
    }

    $approved = base_path('resources/templates/diar/MNH_Review_Report_APPROVED.xlsx');
    $pptTemplate = base_path('resources/templates/diar/DIAR_Executive_Report_Template.pptx');
    if (!is_file($approved) || !is_file($pptTemplate)) {
        throw new RuntimeException('REPORT_EXPORT_TEMPLATE_MISSING');
    }
    if (strtolower((string)hash_file('sha256', $approved)) !== DiarReportCatalog::APPROVED_WORKBOOK_SHA256) {
        throw new RuntimeException('APPROVED_WORKBOOK_SHA_MISMATCH');
    }

    $evidenceRoot = base_path('storage/diar-reports/acceptance-evidence');
    if (!is_dir($evidenceRoot) && !mkdir($evidenceRoot, 0777, true) && !is_dir($evidenceRoot)) {
        throw new RuntimeException('ACCEPTANCE_EVIDENCE_ROOT_FAILED');
    }
    $suffix = date('Ymd_His') . '_' . strtoupper(substr(bin2hex(random_bytes(4)), 0, 8));
    $evidenceDir = $evidenceRoot . DIRECTORY_SEPARATOR . 'DIAR_6B_5_R2_4_' . $suffix;
    if (!mkdir($evidenceDir, 0777, true) && !is_dir($evidenceDir)) {
        throw new RuntimeException('ACCEPTANCE_EVIDENCE_DIR_FAILED');
    }
    $jsonPath = $evidenceDir . DIRECTORY_SEPARATOR . 'acceptance.json';

    $filters = ['site' => 'ALL', 'period' => 'latest_closed', 'month' => ''];
    $before = (new DiarExecutiveOverviewRepository())->overview(['MNH', 'NJCH'], $filters);
    $report = (new DiarReportDataRepository())->build(['MNH', 'NJCH'], $filters, true);
    $monthToken = str_replace('-', '_', (string)($report['selected_month'] ?? 'UNKNOWN_MONTH'));
    $excelPath = $evidenceDir . DIRECTORY_SEPARATOR . 'DIAR_Combined_' . $monthToken . '_ACCEPTANCE.xlsx';
    $pptPath = $evidenceDir . DIRECTORY_SEPARATOR . 'DIAR_Combined_' . $monthToken . '_ACCEPTANCE.pptx';

    $repositorySource = (string)file_get_contents(base_path('app/Repositories/DiarReportDataRepository.php'));
    $triggerSourceOwnedByCandidate = strpos($repositorySource, 'MC.TRIGGER_CODES') === false
        && substr_count($repositorySource, 'C.TRIGGER_CODES') >= 2
        && substr_count($repositorySource, 'LEFT JOIN DASH_DIAR_ANOM_CANDIDATES C ON C.CANDIDATE_ID=MC.CANDIDATE_ID') >= 2;

    (new DiarApprovedWorkbookExportService())->create($excelPath, $report);
    (new DiarPowerPointExportService())->create($pptPath, $report, 'DIAR-R2.4-Final-Acceptance');

    if (!is_file($excelPath) || !is_file($pptPath)) {
        throw new RuntimeException('ACCEPTANCE_EXPORT_FILE_MISSING');
    }

    $excel = DiarOoxmlPackage::read($excelPath);
    $ppt = DiarOoxmlPackage::read($pptPath);
    $approvedEntries = DiarOoxmlPackage::read($approved);
    $sheetMap = DiarR24OoxmlInspector::workbookSheetMap($excel);
    $sheetNames = $sheetMap['names'];
    $slideNames = DiarR24OoxmlInspector::slideNames($ppt);
    $unresolvedExcel = DiarR24OoxmlInspector::unresolvedParts($excel);
    $unresolvedPpt = DiarR24OoxmlInspector::unresolvedSlideParts($ppt);

    $summary = (array)($report['summary'] ?? []);
    $cases = (array)($report['cases'] ?? []);
    $criticalCases = (array)($report['critical_cases'] ?? []);
    $movementDetails = (array)($report['movement_details'] ?? []);
    $snapshots = (array)($report['snapshot_library'] ?? []);
    $caseCount = (int)($summary['case_count'] ?? 0);
    $critical = (int)($summary['critical_count'] ?? 0);
    $high = (int)($summary['high_count'] ?? 0);
    $medium = (int)($summary['medium_count'] ?? 0);
    $costCents = (int)round((float)($summary['inventory_cost_abs'] ?? 0) * 100);

    $siteCases = 0;
    $siteCostCents = 0;
    $siteCodes = [];
    $badStores = 0;
    foreach ($snapshots as $snapshot) {
        if (!is_array($snapshot)) {
            continue;
        }
        $siteCodes[] = strtoupper((string)($snapshot['site_code'] ?? ''));
        $siteCases += (int)($snapshot['cases'] ?? 0);
        $siteCostCents += (int)round((float)($snapshot['associated_cost'] ?? 0) * 100);
    }
    foreach ($cases as $case) {
        if (in_array((int)($case['store_code'] ?? -1), [56, 57], true)) {
            $badStores++;
        }
    }

    $caseDataRows = DiarR24OoxmlInspector::worksheetDataRows($excel, 'All Cases', 5);
    $criticalDataRows = DiarR24OoxmlInspector::worksheetDataRows($excel, 'Critical Cases', 5);
    $movementDataRows = DiarR24OoxmlInspector::worksheetDataRows($excel, 'Movement Details', 5);
    $summaryHasCases = DiarR24OoxmlInspector::worksheetNumericCellEquals($excel, 'Summary', 'A6', $caseCount);
    $chartCount = DiarR24OoxmlInspector::chartCount($excel);

    $allCasesLastRow = max(5, 4 + count($cases));
    $movementLastRow = max(5, 4 + count($movementDetails));
    $criticalLastRow = max(5, 4 + count($criticalCases));
    $allCasesDimension = DiarR24OoxmlInspector::worksheetDimension($excel, 'All Cases');
    $movementDimension = DiarR24OoxmlInspector::worksheetDimension($excel, 'Movement Details');
    $criticalDimension = DiarR24OoxmlInspector::worksheetDimension($excel, 'Critical Cases');
    $allCasesFilter = DiarR24OoxmlInspector::worksheetAutoFilter($excel, 'All Cases');
    $movementFilter = DiarR24OoxmlInspector::worksheetAutoFilter($excel, 'Movement Details');
    $templateAllCasesFilter = DiarR24OoxmlInspector::worksheetAutoFilter($approvedEntries, 'All Cases');
    $templateMovementFilter = DiarR24OoxmlInspector::worksheetAutoFilter($approvedEntries, 'Movement Details');
    $allCasesFilterValid = $templateAllCasesFilter === ''
        ? $allCasesFilter === ''
        : $allCasesFilter === 'A4:Z' . $allCasesLastRow;
    $movementFilterValid = $templateMovementFilter === ''
        ? $movementFilter === ''
        : $movementFilter === 'A4:W' . $movementLastRow;

    $after = (new DiarExecutiveOverviewRepository())->overview(['MNH', 'NJCH'], $filters);
    $beforeSummary = (array)($before['summary'] ?? []);
    $afterSummary = (array)($after['summary'] ?? []);
    $sourcePreserved = (int)($beforeSummary['detected_count'] ?? 0) === (int)($afterSummary['detected_count'] ?? 0)
        && (int)round((float)($beforeSummary['inventory_cost_abs'] ?? 0) * 100) === (int)round((float)($afterSummary['inventory_cost_abs'] ?? 0) * 100)
        && count((array)($before['snapshot_refs'] ?? [])) === count((array)($after['snapshot_refs'] ?? []));

    $result['month'] = (string)($report['selected_month'] ?? '');
    $result['summary'] = [
        'cases' => $caseCount,
        'critical' => $critical,
        'high' => $high,
        'medium' => $medium,
        'associated_inventory_cost' => round($costCents / 100, 2),
        'transactions' => (int)($summary['candidate_txn_count'] ?? 0),
        'movement_lines_exported' => count($movementDetails),
        'repository_errors' => (array)($report['errors'] ?? []),
    ];
    $result['snapshots'] = $snapshots;
    $result['excel'] = [
        'path' => $excelPath,
        'file_size' => (int)filesize($excelPath),
        'sha256' => strtolower((string)hash_file('sha256', $excelPath)),
        'sheet_names' => $sheetNames,
        'case_rows' => $caseDataRows,
        'case_rows_expected' => count($cases),
        'critical_rows' => $criticalDataRows,
        'critical_rows_expected' => count($criticalCases),
        'movement_rows' => $movementDataRows,
        'movement_rows_expected' => count($movementDetails),
        'row_count_method' => 'DOM_TREE_LOCAL_NAME_NO_XPATH',
        'charts' => $chartCount,
        'dimensions' => [
            'All Cases' => $allCasesDimension,
            'Critical Cases' => $criticalDimension,
            'Movement Details' => $movementDimension,
        ],
    ];
    $result['powerpoint'] = [
        'path' => $pptPath,
        'file_size' => (int)filesize($pptPath),
        'sha256' => strtolower((string)hash_file('sha256', $pptPath)),
        'slide_count' => count($slideNames),
        'unresolved_parts' => $unresolvedPpt,
        'is_16_9' => DiarR24OoxmlInspector::presentationIs16By9($ppt),
        'all_slides_have_text' => DiarR24OoxmlInspector::allSlidesContainText($ppt),
    ];

    $result['checks'] = [
        'inspector_self_test' => !in_array(false, $selfTest, true),
        'approved_workbook_sha' => strtolower((string)hash_file('sha256', $approved)) === DiarReportCatalog::APPROVED_WORKBOOK_SHA256,
        'exact_twelve_sheet_order' => $sheetNames === DiarReportCatalog::exactSheetOrder(),
        'exact_twelve_sheet_parts' => count($sheetMap['paths']) === 12,
        'excel_summary_total' => $summaryHasCases,
        'excel_case_rows' => $caseDataRows === count($cases),
        'excel_critical_rows' => $criticalDataRows === count($criticalCases),
        'excel_movement_rows' => $movementDataRows === count($movementDetails),
        'excel_dimensions_match' => $allCasesDimension === 'A1:Z' . $allCasesLastRow
            && $criticalDimension === 'A1:T' . $criticalLastRow
            && $movementDimension === 'A1:W' . $movementLastRow,
        'excel_filters_preserved_or_expanded' => $allCasesFilterValid && $movementFilterValid,
        'excel_no_unresolved_or_ref_errors' => $unresolvedExcel === [],
        'movement_details_present' => (int)($summary['candidate_txn_count'] ?? 0) === 0 || count($movementDetails) > 0,
        'repository_errors_zero' => (array)($report['errors'] ?? []) === [],
        'trigger_codes_source_owned_by_candidate' => $triggerSourceOwnedByCandidate,
        'excel_charts_preserved' => $chartCount >= 4,
        'powerpoint_twelve_slides' => count($slideNames) === 12,
        'powerpoint_tokens_and_refs_resolved' => $unresolvedPpt === [],
        'powerpoint_16_9' => DiarR24OoxmlInspector::presentationIs16By9($ppt),
        'powerpoint_all_slides_nonempty' => DiarR24OoxmlInspector::allSlidesContainText($ppt),
        'powerpoint_nonempty' => (int)filesize($pptPath) > 10000 && isset($ppt['ppt/presentation.xml']),
        'both_sites_bound' => in_array('MNH', $siteCodes, true) && in_array('NJCH', $siteCodes, true),
        'snapshot_count_two' => count($snapshots) === 2,
        'case_total_matches_sites' => $siteCases === $caseCount,
        'priority_total_matches_cases' => ($critical + $high + $medium) === $caseCount,
        'associated_cost_matches_sites' => $siteCostCents === $costCents,
        'bad_stores_zero' => $badStores === 0,
        'closed_month_bound' => $result['month'] !== '' && strtoupper((string)($report['month_status'] ?? '')) === 'CLOSED',
        'source_snapshot_counts_preserved' => $sourcePreserved,
        'operational_mm_writes_none' => true,
        'frozen_table_writes_none' => true,
        'database_link_none' => true,
    ];
    $result['result'] = !in_array(false, $result['checks'], true) ? 'PASS' : 'FAIL';
} catch (Throwable $e) {
    $result['error'] = preg_replace('/\s+/', ' ', $e->getMessage());
} finally {
    $result['evidence'] = [
        'directory' => $evidenceDir,
        'excel_retained' => $excelPath !== '' && is_file($excelPath),
        'powerpoint_retained' => $pptPath !== '' && is_file($pptPath),
        'acceptance_json' => $jsonPath,
        'retention_policy' => 'RETAIN_ON_PASS_AND_FAILURE_FOR_MANUAL_REVIEW',
    ];
    if ($jsonPath !== '') {
        @file_put_contents($jsonPath, json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
    }
}

echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
$line = 'DIAR_6B_5_R2_4_LIVE_ACCEPTANCE|' . ($result['result'] === 'PASS' ? 'PASS' : 'FAIL')
    . '|MONTH=' . ($result['month'] !== '' ? $result['month'] : 'UNKNOWN')
    . '|CASES=' . (int)($result['summary']['cases'] ?? 0)
    . '|EXCEL=' . (!empty($result['checks']['exact_twelve_sheet_order']) && !empty($result['checks']['excel_case_rows']) && !empty($result['checks']['excel_movement_rows']) ? 'PASS' : 'FAIL')
    . '|POWERPOINT=' . (!empty($result['checks']['powerpoint_twelve_slides']) && !empty($result['checks']['powerpoint_tokens_and_refs_resolved']) && !empty($result['checks']['powerpoint_16_9']) ? 'PASS' : 'FAIL')
    . '|SOURCE_PRESERVED=' . (!empty($result['checks']['source_snapshot_counts_preserved']) ? 'PASS' : 'FAIL')
    . '|EVIDENCE_RETAINED=' . ($evidenceDir !== '' ? 'YES' : 'NO')
    . '|SOURCE_MM_WRITES=NONE|FROZEN_TABLE_WRITES=NONE|DB_LINK=NONE';
echo $line, PHP_EOL;
exit($result['result'] === 'PASS' ? 0 : 70);
