<?php

declare(strict_types=1);

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

use App\Repositories\ExecutiveActionRepository;
use App\Repositories\ExecutiveActionReviewRepository;

$hospital = strtolower(trim((string)($_GET['hospital'] ?? 'njch'))) ?: 'njch';
$requestedAction = strtolower(trim((string)($_GET['action'] ?? '')));
$writeTest = (string)($_GET['write_test'] ?? '') === '1';
$token = (string)($_GET['token'] ?? '');
$expectedToken = trim((string)(env('EXEC_ACTION_REVIEW_QA_TOKEN', '') ?: env('EXECUTIVE_REFRESH_TOKEN', '')));

header('Content-Type: text/plain; charset=utf-8');

echo "Executive Action Review Management QA\n";
echo "Phase: 10.6.4 — Review Workflow Completion & Management Integration\n";
echo "Hospital: " . strtoupper($hospital) . "\n";
echo "Write test requested: " . ($writeTest ? 'YES' : 'NO') . "\n\n";

try {
    $repo = new ExecutiveActionReviewRepository($hospital);
    $center = (new ExecutiveActionRepository($hospital))->center();
    $op = is_array($center['operational'] ?? null) ? $center['operational'] : [];
    $operationalDate = (string)($op['operational_date'] ?? date('Y-m-d'));
    $actions = is_array($center['actions'] ?? null) ? $center['actions'] : [];

    $selectAction = function (array $items) use ($requestedAction): ?array {
        $first = null;
        foreach ($items as $candidate) {
            if (!is_array($candidate)) { continue; }
            if ($first === null) { $first = $candidate; }
            $rule = strtolower((string)($candidate['rule_id'] ?? ''));
            if ($requestedAction !== '' && $rule === $requestedAction) { return $candidate; }
        }
        return $requestedAction === '' ? $first : null;
    };

    $selected = $selectAction($actions);
    $beforeDiag = $repo->diagnostics($operationalDate);
    $writeProof = [];

    if ($writeTest) {
        if ($expectedToken === '' || !hash_equals($expectedToken, $token)) {
            http_response_code(403);
            echo "FORBIDDEN: set EXEC_ACTION_REVIEW_QA_TOKEN or EXECUTIVE_REFRESH_TOKEN in .env and pass ?token=YOUR_TOKEN.\n";
            exit;
        }

        if (!$selected) {
            $writeProof = ['ok' => false, 'detail' => 'No active action is available for a controlled transition test.'];
        } else {
            $ruleId = (string)($selected['rule_id'] ?? '');
            $originalReview = is_array($selected['review'] ?? null) ? $selected['review'] : [];
            $originalStatus = strtolower((string)($originalReview['status'] ?? 'open'));
            if (!in_array($originalStatus, ['open', 'reviewed', 'deferred'], true)) { $originalStatus = 'open'; }
            $originalNote = (string)($originalReview['note'] ?? '');
            $testStatus = $originalStatus === 'open' ? 'reviewed' : ($originalStatus === 'reviewed' ? 'open' : 'reviewed');
            $testNote = 'Phase 10.6.4 reversible QA transition proof at ' . date('Y-m-d H:i:s');

            $savedTest = $repo->save($ruleId, $operationalDate, $testStatus, $testNote, 'phase10_6_4_qa', $selected);
            $afterTest = $repo->find($ruleId, $operationalDate);
            $transitionSaved = is_array($afterTest) && (string)($afterTest['status'] ?? '') === $testStatus;

            $restoreSteps = [];
            if ($originalStatus === 'open') {
                $repo->save($ruleId, $operationalDate, 'open', $originalNote, 'phase10_6_4_qa_restore', $selected);
                $restoreSteps[] = 'reviewed -> open';
            } elseif ($originalStatus === 'reviewed') {
                $repo->save($ruleId, $operationalDate, 'reviewed', $originalNote, 'phase10_6_4_qa_restore', $selected);
                $restoreSteps[] = 'open -> reviewed';
            } else {
                $repo->save($ruleId, $operationalDate, 'open', $originalNote, 'phase10_6_4_qa_restore', $selected);
                $restoreSteps[] = 'reviewed -> open';
                $repo->save($ruleId, $operationalDate, 'deferred', $originalNote, 'phase10_6_4_qa_restore', $selected);
                $restoreSteps[] = 'open -> deferred';
            }

            $restored = $repo->find($ruleId, $operationalDate);
            $restoreOk = is_array($restored)
                && (string)($restored['status'] ?? '') === $originalStatus
                && (string)($restored['note'] ?? '') === $originalNote;

            $afterDiag = $repo->diagnostics($operationalDate);
            $writeProof = [
                'ok' => $transitionSaved && $restoreOk,
                'rule_id' => $ruleId,
                'original_status' => $originalStatus,
                'test_status' => $testStatus,
                'transition_saved' => $transitionSaved,
                'restore_ok' => $restoreOk,
                'restore_steps' => $restoreSteps,
                'audit_rows_added' => max(0, (int)($afterDiag['lifetime_audit_count'] ?? 0) - (int)($beforeDiag['lifetime_audit_count'] ?? 0)),
                'saved_review_count' => (int)($savedTest['review_count'] ?? 0),
            ];

            $center = (new ExecutiveActionRepository($hospital))->center();
            $actions = is_array($center['actions'] ?? null) ? $center['actions'] : [];
            $selected = $selectAction($actions);
        }
    }

    $workflow = is_array($center['review_workflow'] ?? null) ? $center['review_workflow'] : [];
    $management = is_array($workflow['management'] ?? null) ? $workflow['management'] : [];
    $counts = is_array($workflow['counts'] ?? null) ? $workflow['counts'] : [];
    $filters = is_array($workflow['filters'] ?? null) ? $workflow['filters'] : [];
    $matrix = is_array($workflow['transition_matrix'] ?? null) ? $workflow['transition_matrix'] : [];
    $diag = $repo->diagnostics($operationalDate);
    $selectedRule = $selected ? (string)($selected['rule_id'] ?? '') : '';
    $allDateHistory = $selectedRule !== '' ? $repo->auditHistoryAllDates($selectedRule, 30) : [];
    $previousReview = $selectedRule !== '' ? $repo->latestReviewAcrossDates($selectedRule, $operationalDate) : null;
    $historicalAction = $selectedRule !== '' ? $repo->historicalAction($selectedRule) : null;

    $pass = function (bool $ok, string $label, string $detail = ''): void {
        echo ($ok ? '[PASS] ' : '[FAIL] ') . str_pad($label, 36) . ($detail !== '' ? ' | ' . $detail : '') . "\n";
    };
    $pending = function (string $label, string $detail = ''): void {
        echo '[PENDING] ' . str_pad($label, 33) . ($detail !== '' ? ' | ' . $detail : '') . "\n";
    };

    $worklistMetadataOk = count($actions) > 0;
    foreach ($actions as $action) {
        if (!is_array($action)
            || !array_key_exists('review', $action)
            || !array_key_exists('review_status', $action)
            || !array_key_exists('previous_review', $action)
            || !array_key_exists('review_history_available', $action)) {
            $worklistMetadataOk = false;
            break;
        }
    }

    $transitionMatrixOk = isset($matrix['open'], $matrix['reviewed'], $matrix['deferred'])
        && in_array('reviewed', (array)$matrix['open'], true)
        && in_array('deferred', (array)$matrix['open'], true)
        && in_array('open', (array)$matrix['reviewed'], true)
        && in_array('reviewed', (array)$matrix['deferred'], true)
        && in_array('open', (array)$matrix['deferred'], true);

    $managementKeys = ['total_actions', 'open', 'reviewed', 'deferred', 'pending_attention', 'completion_percent', 'lifetime_audit_count', 'last_activity', 'history_scope'];
    $managementOk = true;
    foreach ($managementKeys as $key) {
        if (!array_key_exists($key, $management)) { $managementOk = false; break; }
    }

    echo "QA Gates:\n";
    $pass(!empty($center['summary_available']), 'summary_available', !empty($center['summary_available']) ? 'YES' : 'NO');
    $pass((string)($diag['storage_mode'] ?? '') === 'oracle', 'active_storage_is_oracle', (string)($diag['storage_mode'] ?? '-'));
    $pass(!empty($diag['main_table_exists']) && !empty($diag['audit_table_exists']), 'oracle_review_tables_ready', (string)($diag['main_table'] ?? '-') . ' + ' . (string)($diag['audit_table'] ?? '-'));
    $pass(isset($counts['open'], $counts['reviewed'], $counts['deferred']), 'review_counts_integrated', 'open=' . (string)($counts['open'] ?? 0) . ', reviewed=' . (string)($counts['reviewed'] ?? 0) . ', deferred=' . (string)($counts['deferred'] ?? 0));
    $pass($managementOk, 'management_summary_integrated', 'completion=' . (string)($management['completion_percent'] ?? '-') . '%');
    $pass($worklistMetadataOk, 'worklist_review_metadata', (string)count($actions) . ' actions');
    $pass(in_array('critical', $filters, true), 'critical_filter_available', implode(',', $filters));
    $pass($transitionMatrixOk, 'controlled_transition_matrix', 'Open->Reviewed/Deferred; Reviewed->Reopen; Deferred->Reviewed/Open');
    $pass((string)($workflow['history_scope'] ?? '') === 'all_operational_days', 'cross_day_history_scope', (string)($workflow['history_scope'] ?? '-'));
    $pass(is_array($allDateHistory), 'selected_action_history_readable', $selectedRule !== '' ? $selectedRule . ' rows=' . count($allDateHistory) : 'no selected action');
    $pass(is_array($previousReview) || $previousReview === null, 'previous_day_context_readable', is_array($previousReview) ? (string)($previousReview['operational_date'] ?? '-') : 'none yet');
    if ((int)($diag['lifetime_audit_count'] ?? 0) > 0) {
        $pass(is_array($historicalAction), 'historical_action_recoverable', is_array($historicalAction) ? (string)($historicalAction['rule_id'] ?? '-') : 'not found');
    } else {
        $pending('historical_action_recoverable', 'No saved review exists yet to recover.');
    }

    if ((int)($diag['lifetime_audit_count'] ?? 0) > 0) {
        $pass(true, 'lifetime_audit_rows_exist', (string)$diag['lifetime_audit_count']);
        $lastActivity = is_array($management['last_activity'] ?? null) ? $management['last_activity'] : [];
        $pass(!empty($lastActivity), 'latest_review_activity_exposed', (string)($lastActivity['changed_at'] ?? '-'));
    } else {
        $pending('lifetime_audit_rows_exist', 'Run one UI save or write_test=1 after the Phase 10.6.3.1 bind guard is installed.');
        $pending('latest_review_activity_exposed', 'No audit activity exists yet.');
    }

    if ($writeTest) {
        $pass(!empty($writeProof['transition_saved']), 'write_transition_saved', (string)($writeProof['original_status'] ?? '-') . ' -> ' . (string)($writeProof['test_status'] ?? '-'));
        $pass(!empty($writeProof['restore_ok']), 'write_state_restored', implode(', ', (array)($writeProof['restore_steps'] ?? [])));
        $pass((int)($writeProof['audit_rows_added'] ?? 0) >= 2, 'write_audit_rows_added', (string)($writeProof['audit_rows_added'] ?? 0));
    }

    if (!empty($diag['last_storage_error'])) {
        echo "\nStorage error:\n" . (string)$diag['last_storage_error'] . "\n";
    }

    echo "\nManagement Summary:\n";
    echo "operational_day     | " . $operationalDate . "\n";
    echo "storage             | " . (string)($workflow['storage'] ?? $repo->storageMode()) . "\n";
    echo "total_actions       | " . (string)($management['total_actions'] ?? count($actions)) . "\n";
    echo "open                | " . (string)($management['open'] ?? 0) . "\n";
    echo "reviewed            | " . (string)($management['reviewed'] ?? 0) . "\n";
    echo "deferred            | " . (string)($management['deferred'] ?? 0) . "\n";
    echo "pending_attention   | " . (string)($management['pending_attention'] ?? 0) . "\n";
    echo "completion_percent  | " . (string)($management['completion_percent'] ?? 0) . "%\n";
    echo "lifetime_audit_rows | " . (string)($diag['lifetime_audit_count'] ?? 0) . "\n";
    echo "history_scope       | " . (string)($workflow['history_scope'] ?? '-') . "\n";

    echo "\nSelected Action:\n";
    if ($selected) {
        $review = is_array($selected['review'] ?? null) ? $selected['review'] : [];
        echo "rule_id             | " . (string)($selected['rule_id'] ?? '-') . "\n";
        echo "severity            | " . (string)($selected['severity'] ?? '-') . "\n";
        echo "status              | " . (string)($review['status'] ?? 'open') . "\n";
        echo "last_review_at      | " . (string)($review['updated_at'] ?? '-') . "\n";
        echo "last_review_by      | " . (string)($review['updated_by'] ?? '-') . "\n";
        echo "review_count        | " . (string)($review['review_count'] ?? 0) . "\n";
        echo "all_date_history    | " . count($allDateHistory) . "\n";
        echo "review_page         | index.php?page=action-review&action=" . rawurlencode((string)($selected['rule_id'] ?? '')) . "&lang=en\n";
    } else {
        echo "No active action selected.\n";
    }

    if ($writeTest) {
        echo "\nControlled Write Proof:\n";
        echo "action_key          | " . (string)($writeProof['rule_id'] ?? '-') . "\n";
        echo "test_transition     | " . (string)($writeProof['original_status'] ?? '-') . ' -> ' . (string)($writeProof['test_status'] ?? '-') . "\n";
        echo "state_restored      | " . (!empty($writeProof['restore_ok']) ? 'YES' : 'NO') . "\n";
        echo "audit_rows_added    | " . (string)($writeProof['audit_rows_added'] ?? 0) . "\n";
    }

    echo "\nAutomated write proof:\n";
    if ($expectedToken === '') {
        echo "Set EXEC_ACTION_REVIEW_QA_TOKEN in .env first.\n";
    } else {
        echo "Open: executive-action-review-management-qa.php?hospital=" . rawurlencode($hospital) . "&write_test=1&token=YOUR_TOKEN\n";
        echo "The test performs a controlled status transition and restores the original status/note while keeping the audit evidence.\n";
    }
} catch (Throwable $e) {
    http_response_code(500);
    echo "ERROR: " . $e->getMessage() . "\n";
}
