<?php

/**
 * PE Emergency Management scenario categories (main SBA generator only).
 */

function sbaPeEmergencyScenarioSlotKeys(): array
{
    return [
        'initial_massive_pe_shock',
        'unstable_pe_reperfusion_required',
        'thrombolysis_contraindicated',
        'peri_arrest_pe_resuscitation',
        'hypoxic_pe_oxygen_escalation',
    ];
}

function sbaPeNormalizeScenarioSlotKey(string $slot): string
{
    return strtolower(trim($slot));
}

function sbaPeEmergencyScenarioDisplayLabel(string $slot): string
{
    return match (sbaPeNormalizeScenarioSlotKey($slot)) {
        'initial_massive_pe_shock' => 'Massive pulmonary embolism with shock (initial reperfusion)',
        'unstable_pe_reperfusion_required' => 'Haemodynamically unstable PE (reperfusion not anticoagulation alone)',
        'thrombolysis_contraindicated' => 'Massive PE with contraindication to thrombolysis',
        'peri_arrest_pe_resuscitation' => 'Peri-arrest / cardiac arrest pulmonary embolism',
        'hypoxic_pe_oxygen_escalation' => 'Hypoxic unstable PE (oxygen plus escalation)',
        default => $slot,
    };
}

function sbaPeStemSuggestsThrombolysisContraindication(string $stem): bool
{
    return (bool) preg_match(
        '/\b(?:recent\s+(?:major\s+)?surgery|post[\s-]?operative|intracranial\s+haemorrhage|intracranial\s+hemorrhage|ich\b|haemorrhagic\s+stroke|hemorrhagic\s+stroke|active\s+bleeding|contraindication\s+to\s+thrombolysis|cannot\s+receive\s+thrombolysis)\b/i',
        $stem
    );
}

function sbaPeStemSuggestsPeriArrestOrCardiacArrest(string $stem): bool
{
    return (bool) preg_match(
        '/\b(?:cardiac\s+arrest|arrested|pulseless|peri[\s-]?arrest|collapsed|cpr|resuscitation\s+in\s+progress)\b/i',
        $stem
    );
}

function sbaPeStemSuggestsPeHaemodynamicInstability(string $stem): bool
{
    return sbaPeStemDocumentsHaemodynamicInstabilityForThrombolysis($stem);
}

/**
 * Documented haemodynamic instability required before keying thrombolysis / reperfusion for PE.
 * Hypoxia, breathlessness, or “high-risk PE” wording alone is insufficient.
 */
function sbaPeStemDocumentsHaemodynamicInstabilityForThrombolysis(string $stem): bool
{
    if ($stem === '') {
        return false;
    }
    if (preg_match(
        '/\b(?:shock|shocked|hypotension|hypotensive|cardiogenic\s+shock|obstructive\s+(?:shock|circulatory\s+collapse)|circulatory\s+collapse|cardiac\s+arrest|arrested|pulseless|peri[\s-]?arrest|haemodynamically\s+unstable|hemodynamically\s+unstable|haemodynamic(?:ally)?\s+instab|hemodynamic(?:ally)?\s+instab)\b/i',
        $stem
    )) {
        return true;
    }
    if (preg_match(
        '/\b(?:massive\s+(?:pulmonary\s+)?embol|high[\s-]?risk\s+pe)\b.{0,120}\b(?:shock|shocked|hypotension|hypotensive)\b/i',
        $stem
    ) || preg_match(
        '/\b(?:shock|shocked|hypotension|hypotensive)\b.{0,120}\b(?:massive\s+(?:pulmonary\s+)?embol|high[\s-]?risk\s+pe)\b/i',
        $stem
    )) {
        return true;
    }
    if (preg_match('/\b(?:BP|blood\s+pressure)\s+(?:is|was|of)\s*(\d{2,3})\s*\/\s*(\d{1,3})\b/i', $stem, $m)) {
        return (int) $m[1] > 0 && (int) $m[1] < 90;
    }
    if (preg_match('/\bsystolic\s+(?:BP|blood\s+pressure)\s+(?:is|was|of)?\s*(\d{2,3})\b/i', $stem, $m)) {
        return (int) $m[1] > 0 && (int) $m[1] < 90;
    }
    if (preg_match('/\bblood\s+pressure\s+(?:is|was|of)?\s*(\d{2,3})\s*(?:mmhg)?\b/i', $stem, $m)) {
        return (int) $m[1] > 0 && (int) $m[1] < 90;
    }

    return false;
}

function sbaPeKeyedAnswerSuggestsThrombolysisDrug(string $text): bool
{
    return $text !== '' && (bool) preg_match(
        '/\b(?:thrombolysis|thrombolytic|fibrinolysis|alteplase|streptokinase|tenecteplase|give\s+alteplase|administer\s+alteplase)\b/i',
        $text
    );
}

function sbaPeKeyedAnswerSuggestsGenericAlternativeReperfusionEscalation(string $text): bool
{
    return $text !== '' && (bool) preg_match(
        '/\b(?:alternative\s+reperfusion|urgent\s+(?:critical\s+care|senior|specialist)\s+(?:review|escalation)|critical\s+care\s+escalation|escalat(?:e|ion)\s+for\s+alternative|arrange\s+urgent\s+alternative)\b/i',
        $text
    );
}

function sbaPeOptionLineSuggestsOxygenPlusThrombolysis(string $line): bool
{
    return $line !== ''
        && preg_match('/\b(?:oxygen|supplemental\s+oxygen)\b/i', $line)
        && preg_match('/\b(?:thrombolysis|thrombolytic|alteplase|reperfusion)\b/i', $line);
}

function sbaPeStemHasClinicallySignificantHypoxia(string $stem): bool
{
    if (function_exists('sbaSepsisStemHasClinicallySignificantHypoxia')) {
        require_once __DIR__ . '/sba_sepsis_batch_concepts.php';

        return sbaSepsisStemHasClinicallySignificantHypoxia($stem);
    }
    if (preg_match_all('/(?:oxygen\s+saturation|spo2)[^\d%]{0,50}(\d{1,3})\s*%/i', $stem, $m)) {
        foreach ($m[1] as $v) {
            if ((int) $v >= 50 && (int) $v < 92) {
                return true;
            }
        }
    }

    return false;
}

function sbaPeStemIndicatesAnticoagulationAlreadyStarted(string $stem): bool
{
    return (bool) preg_match(
        '/\b(?:already\s+(?:on|receiving|started)|has\s+(?:been\s+)?(?:started|given)|receiving|on)\s+(?:therapeutic\s+)?(?:anticoagulation|lmwh|heparin|enoxaparin|dalteparin|treatment\s+with\s+heparin)\b/i',
        $stem
    );
}

function sbaPeInferEmergencyScenarioCategory(string $stem, string $lead, string $keyed): string
{
    $key = mb_strtolower(trim($keyed));
    if (sbaPeStemSuggestsThrombolysisContraindication($stem)) {
        return 'thrombolysis_contraindicated';
    }
    if (sbaPeStemSuggestsPeriArrestOrCardiacArrest($stem)) {
        return 'peri_arrest_pe_resuscitation';
    }
    if (sbaPeStemIndicatesAnticoagulationAlreadyStarted($stem)
        && sbaPeStemSuggestsPeHaemodynamicInstability($stem)
        && preg_match('/\b(?:thrombolysis|thrombolytic|reperfusion|embolectomy|critical\s+care|escalat)\b/i', $key)) {
        return 'unstable_pe_reperfusion_required';
    }
    if (preg_match('/\b(?:embolectomy|catheter[\s-]directed|surgical\s+reperfusion|alternative\s+reperfusion)\b/i', $key)
        && sbaPeStemSuggestsThrombolysisContraindication($stem)) {
        return 'thrombolysis_contraindicated';
    }
    if (preg_match('/\b(?:thrombolysis|thrombolytic|reperfusion|embolectomy)\b/i', $key)
        && sbaPeStemSuggestsPeHaemodynamicInstability($stem)) {
        return 'initial_massive_pe_shock';
    }
    if (sbaPeStemSuggestsPeHaemodynamicInstability($stem)
        && preg_match('/\b(?:anticoagulation\s+alone|lmwh\s+alone|heparin\s+alone)\b/i', $key)) {
        return 'unstable_pe_reperfusion_required';
    }
    if (sbaPeStemHasClinicallySignificantHypoxia($stem)
        && !sbaPeStemSuggestsPeHaemodynamicInstability($stem)) {
        return 'hypoxic_pe_oxygen_escalation';
    }
    if (sbaPeStemSuggestsPeHaemodynamicInstability($stem)) {
        return 'initial_massive_pe_shock';
    }

    return 'initial_massive_pe_shock';
}

function sbaPeEmergencyAnswerConceptBucket(string $keyed): string
{
    $k = mb_strtolower(trim($keyed));
    if ($k === '') {
        return '';
    }
    if (preg_match('/\b(?:thrombolysis|thrombolytic|alteplase|streptokinase|tenecteplase)\b/i', $k)) {
        return 'thrombolysis';
    }
    if (preg_match('/\b(?:embolectomy|catheter[\s-]directed|surgical\s+reperfusion)\b/i', $k)) {
        return 'alternative_reperfusion';
    }
    if (preg_match('/\b(?:cpr|cardiac\s+arrest|resuscitat)\b/i', $k)) {
        return 'arrest_resuscitation';
    }
    if (preg_match('/\b(?:lmwh|heparin|anticoagul|fondaparinux)\b/i', $k)
        && !preg_match('/\b(?:thrombolysis|reperfusion|embolectomy)\b/i', $k)) {
        return 'anticoagulation_alone';
    }
    if (preg_match('/\b(?:oxygen|supplemental\s+oxygen)\b/i', $k)
        && preg_match('/\b(?:thrombolysis|reperfusion|critical\s+care|escalat)\b/i', $k)) {
        return 'oxygen_plus_escalation';
    }

    return 'other';
}

function sbaPePickNextEmergencyScenarioSlot(array $usedSlots): string
{
    foreach (sbaPeEmergencyScenarioSlotKeys() as $slot) {
        if (empty($usedSlots[$slot])) {
            return $slot;
        }
    }

    return sbaPeEmergencyScenarioSlotKeys()[0];
}

/**
 * Deterministic category order for PE Emergency batches (before repeating).
 *
 * @return list<string>
 */
function sbaPePlannedBatchSlotSequence(int $emergencyTotal, string $presentation = '', string $tutorComments = ''): array
{
    $blob = mb_strtolower(trim($presentation . ' ' . $tutorComments));
    if ($emergencyTotal <= 0) {
        return [];
    }
    if ($emergencyTotal === 1) {
        if (preg_match('/\b(?:contraindication|recent\s+surgery|intracranial|cannot\s+receive\s+thrombolysis)\b/i', $blob)) {
            return ['thrombolysis_contraindicated'];
        }
        if (preg_match('/\b(?:arrest|peri[\s-]?arrest|pulseless|collapsed)\b/i', $blob)) {
            return ['peri_arrest_pe_resuscitation'];
        }

        return [sbaPeSlotsOrderedByPresentationAffinity($presentation, $tutorComments)[0]];
    }

    $coreThree = [
        'initial_massive_pe_shock',
        'unstable_pe_reperfusion_required',
        'thrombolysis_contraindicated',
    ];
    $extra = ['peri_arrest_pe_resuscitation', 'hypoxic_pe_oxygen_escalation'];

    if (preg_match('/\b(?:contraindication|recent\s+surgery|intracranial)\b/i', $blob)
        && !preg_match('/\b(?:massive|shock)\b/i', $blob)) {
        $coreThree = [
            'thrombolysis_contraindicated',
            'initial_massive_pe_shock',
            'unstable_pe_reperfusion_required',
        ];
    }

    if ($emergencyTotal <= 3) {
        return array_slice($coreThree, 0, $emergencyTotal);
    }

    if (!preg_match('/\b(?:massive|shock|unstable|hypotension)\b/i', $blob)) {
        $extra[] = 'hypoxic_pe_oxygen_escalation';
    }

    return array_merge($coreThree, array_slice($extra, 0, $emergencyTotal - 3));
}

/**
 * Slot from DB tags only (assigned plan), not stem inference.
 */
function sbaPeEmergencySlotFromPriorRow(array $row): ?string
{
    if (!is_array($row)) {
        return null;
    }
    $tags = (string) ($row['tags'] ?? '');
    if (preg_match('/\bpe_emergency_slot=([a-z_]+)/i', $tags, $m)) {
        return sbaPeNormalizeScenarioSlotKey($m[1]);
    }

    return null;
}

/**
 * @param array<string, mixed> $question
 */
function sbaPeAssignedEmergencyScenarioSlot(array $question): ?string
{
    $plan = $question['_pe_emergency_scenario_plan'] ?? null;
    if (is_array($plan) && !empty($plan['slot'])) {
        return sbaPeNormalizeScenarioSlotKey((string) $plan['slot']);
    }

    return null;
}
