<?php

/**
 * Centralised skill definitions for the form-based SBA question generator only.
 * Not used by the RISr variant generator.
 *
 * @return array<string, array{
 *   label: string,
 *   match: string,
 *   preferred_lead_ins: list<string>,
 *   allowed_option_types: list<string>,
 *   forbidden_option_types: list<string>,
 *   rules: list<string>
 * }>
 */
function sbaGeneratorSkillDefinitionCatalogue(): array
{
    return [
        'diagnosis' => [
            'label' => 'Diagnosis',
            'match' => '/^(?:diagnosis)$/i',
            'preferred_lead_ins' => [
                'What is the most likely diagnosis?',
                'Which diagnosis best explains these findings?',
                'What is the most probable diagnosis?',
            ],
            'allowed_option_types' => [
                'Diagnoses, disease entities, or clinical syndromes (e.g. asthma exacerbation, pulmonary embolism, acute coronary syndrome).',
                'Parallel grammatical form across all five options (each option is a diagnosis label).',
            ],
            'forbidden_option_types' => [
                'Investigations, imaging, blood tests, or monitoring plans.',
                'Treatments, drugs, procedures, referrals, or management steps.',
                'Mixed families (do not combine diagnoses with tests or treatments in one option set).',
            ],
            'rules' => [
                'The stem supplies symptoms, signs, and context; the lead-in asks which diagnosis is most likely.',
                'Do **not** name the form **Core condition** in the stem when Current skill is Diagnosis (use supporting cues instead).',
                'Avoid stacking every classic feature into one textbook giveaway; keep plausible differentials.',
                'The keyed answer must be the diagnosis best supported by the vignette, not the broadest label unless the stem supports it.',
                '**All five options** must be **diagnoses or diagnostic labels** at the **same level of specificity** — similar length where possible.',
                'Do **not** include investigations, management steps, or treatment options.',
                'Avoid unnecessary affect labels (e.g. “appears anxious”) unless they change which diagnosis is most likely.',
                'Avoid **“no significant past medical history”** — use **“has no other medical conditions”** or omit irrelevant negatives.',
            ],
        ],
        'investigation' => [
            'label' => 'Investigation',
            'match' => '/^investigation(?:\s+selection)?$/i',
            'preferred_lead_ins' => [
                'What is the most appropriate initial investigation?',
                'What is the most appropriate next investigation?',
                'Which investigation should be performed next?',
                'What is the most appropriate confirmatory investigation?',
            ],
            'allowed_option_types' => [
                'Investigations and diagnostic tests only (e.g. 12-lead ECG, chest X-ray, full blood count, cardiac troponin, CT scan).',
                'Homogeneous test names at a similar level of specificity.',
            ],
            'forbidden_option_types' => [
                'Diagnoses or disease labels as options.',
                'Management actions, drugs, fluids, oxygen, referrals, or treatment plans.',
                'The **result** of the investigation being chosen when the task is an **initial** investigation ask (reserve results for Interpretation).',
            ],
            'rules' => [
                'The lead-in must state whether the task is **initial**, **next**, **confirmatory**, or **monitoring** investigation — aligned with what the stem already shows.',
                'Do **not** put the exam question inside the stem (e.g. avoid “Which investigation …?” in the stem).',
                'For an **initial** investigation, the stem must not already report the result of that test (e.g. no peak-flow variability numbers if asking for initial testing).',
                'Avoid two options that are effectively the same step in one pathway unless Tutor comments make that contrast the teaching point.',
                '**Stem demographics and risk factors must be internally consistent** — do not introduce sex-specific details (oral contraceptives, pregnancy, oestrogen therapy) that mismatch stated sex unless explicitly explained.',
                'Condition-specific binding blocks (e.g. ACS Investigation Pattern A/B, PE investigation probability) override generic investigation layout when present elsewhere in this prompt.',
            ],
        ],
        'interpretation' => [
            'label' => 'Interpretation',
            'match' => '/^interpretation$/i',
            'preferred_lead_ins' => [
                'What is the best interpretation of these findings?',
                'How should these results be interpreted?',
                'What do these investigation results indicate?',
                'Which statement best describes these results?',
            ],
            'allowed_option_types' => [
                'Interpretation statements, pattern labels, severity or control classifications, and clinical meaning of **supplied data**.',
                'Parallel interpretation lines at one level (e.g. airflow pattern, control status, likelihood category).',
            ],
            'forbidden_option_types' => [
                'Management actions, treatments, drugs, fluids, oxygen, or escalation steps.',
                'Investigations or “order test X” lines.',
                'Diagnoses as the primary option family when the lead-in asks for interpretation of **results** (prefer interpretation labels).',
                'Follow-up plans, monitoring tasks, or “what should be done next” actions.',
            ],
            'rules' => [
                '**Mandatory:** interpret **only** findings already supplied in the stem (numbers, traces, report wording). Do **not** ask what should be done next.',
                'The lead-in must ask for **interpretation** only — do **not** use management, treatment, follow-up, monitoring, or **next step** wording.',
                'The stem must include **actual data** (values, thresholds, or quoted report text) — do **not** say a test was done without giving the result.',
                'Every option must be an **interpretation** or diagnostic label on the data — not an action. **Do not** start options with action verbs such as **start**, **administer**, **arrange**, **perform**, **initiate**, **prescribe**, **refer**, **increase**, **add**, **check**, **review**, or **monitor**.',
                'When a **definitive investigation result** is quoted (e.g. CTPA filling defect, positive troponin with pattern), key a **definitive** interpretation (e.g. **pulmonary embolism**, **NSTEMI**) — **not** only **“high probability”** or **“likely”** wording.',
                'The keyed answer must be the interpretation **most directly supported** by the supplied data; avoid vague labels such as “significant” without numeric support in the stem.',
                'Options must be **distinct** at one level; avoid overlapping lines where two options could both be correct. Distractors should be **plausible** on the stem — not obviously impossible.',
                'The title must reflect interpretation (e.g. “CTPA in suspected pulmonary embolism”) — **not** “management assessment” or management-style labelling.',
            ],
        ],
        'management' => [
            'label' => 'Management',
            'match' => '/^management$/i',
            'preferred_lead_ins' => [
                'What is the most appropriate management?',
                'What is the most appropriate next step in management?',
                'Which management step is most appropriate?',
                'What is the best management plan?',
            ],
            'allowed_option_types' => [
                'Standard treatment and management steps (drug classes, therapies, lifestyle measures, follow-up plans where appropriate).',
                'Homogeneous management actions parallel in form.',
            ],
            'forbidden_option_types' => [
                'Investigations, imaging, or diagnostic tests as options (unless Tutor comments explicitly require a mixed item).',
                'Diagnosis labels as options.',
                'Emergency-only escalation as the default family (e.g. primary PCI pathway, peri-arrest protocols) unless the vignette and lead-in clearly require it.',
                'Repeating the **same** correct-answer concept already used for **Emergency Management** in this batch (see batch block when present).',
            ],
            'rules' => [
                'Focus on **routine or standard treatment decisions** for the condition — not immediate resuscitation unless the scenario is clearly non-acute emergency care.',
                'Every option must be a **management** action at the **same level of specificity**; do **not** list investigations or diagnoses as distractors.',
                'Do **not** place a **broad class** option and a **specific example of that class** in the same set (e.g. **“initiate anticoagulation therapy”** and **“start low-molecular-weight heparin”**) unless the item explicitly tests that distinction.',
                'Avoid **overlapping correct answers** — only one option should be defensible as best management.',
                'When **Core condition** implies a chronic or clinic context, prefer stepwise care, prevention, and proportionate escalation — not ED-style reperfusion unless Tutor comments require it.',
                'Do **not** recast the item as **Prescribing**-only or **Emergency Management**; keep title and options aligned with Management.',
                'If a batch anti-repetition block lists a prior **Emergency Management** answer, choose a **different** management concept.',
            ],
        ],
        'emergency_management' => [
            'label' => 'Emergency Management',
            'match' => '/^emergency\s+management$/i',
            'preferred_lead_ins' => [
                'What is the most appropriate immediate management?',
                'What treatment should be given first?',
                'What is the most appropriate first action?',
                'What is the most appropriate immediate treatment?',
            ],
            'allowed_option_types' => [
                '**All five options (A–E)** must be **immediate emergency management actions** in the **same decision family** — urgent treatment, resuscitation, stabilisation, escalation, or time-critical intervention.',
                'Acceptable action types include: **IV fluid resuscitation**, **broad-spectrum IV antibiotics**, **combined sepsis resuscitation** (e.g. start IV fluids and broad-spectrum IV antibiotics / sepsis resuscitation bundle), **oxygen therapy** when hypoxic, **senior or critical care escalation**, **vasopressor support** when fluid-refractory shock is clearly established, **urgent reperfusion / cardiology pathway** when indicated, and plausible **unsafe sequencing** distractors (e.g. withhold antibiotics until cultures return) only when the vignette explicitly tests that error.',
                'The **keyed answer** may be a **combined** emergency line (e.g. “Start IV fluids and broad-spectrum IV antibiotics”) when clinically appropriate; **every distractor** must still be an emergency **management action**, not an investigation.',
                '**Distractor design:** clinically plausible **whole** emergency strategies — unsafe sequencing, incomplete resuscitation, wrong priority, or clearly lower-yield urgent actions — **not** isolated halves of the keyed combined answer.',
            ],
            'forbidden_option_types' => [
                '**Any** investigation, imaging, diagnostic test, laboratory request, or “wait for results” line — **none** of the five options may be investigations when the lead-in asks for immediate management or treatment.',
                'Forbidden wording in options (and close variants): **full blood count**, **FBC**, **blood test**, **wait for results**, **await results**, **CT scan**, **scan**, **imaging**, **X-ray**, **CXR**, **culture** (when the option is primarily taking/awaiting cultures or tests rather than treating), **investigation**, **test** (when used as order-a-test wording), **ECG**, **troponin**, **echocardiogram**, **ultrasound** (diagnostic), **MRI**, **request … and wait**.',
                'Diagnosis labels as options.',
                'Routine chronic management, outpatient review, or non-urgent follow-up unless clearly the best urgent discriminator for the lead-in.',
                'Repeating the **same** correct-answer concept or treatment family already keyed in **Management** in this batch (unless Tutor comments allow repetition).',
                '**Partial-component distractors** when the key is combined: do **not** use “IV fluids **only**” and “antibiotics **only**” (or other single-component fragments) as two or more distractors alongside a combined correct answer — the key must not look like “A + B” with B and C as A-only and B-only.',
            ],
            'rules' => [
                '**Mandatory:** when Current skill is **Emergency Management**, **every option A–E** is an **immediate emergency management action** — **never** mix in investigations, imaging, or “request test and wait for results” lines.',
                '**Avoid mirror-fragment option sets:** if the keyed answer combines two urgent actions (e.g. IV fluids **and** broad-spectrum IV antibiotics), distractors must **not** be mostly isolated components of that same combination. Use **distinct** plausible emergency strategies instead.',
                '**Combined correct answer — preferred distractor types (examples):** withhold antibiotics until culture results; oral antibiotics in an unstable patient; antipyretic-only treatment; oxygen when not hypoxic; vasopressor infusion before adequate fluid resuscitation; observation or monitoring alone without treatment; delayed senior or critical care escalation; wrong-route or under-treatment lines still in the **management-action** family.',
                'For **septic shock / unstable sepsis** with a **combined** key, acceptable distractors include those above — **not** “administer IV fluids only” and “administer antibiotics only” as parallel options to “fluids and antibiotics”.',
                'The stem must reflect an **acute** or **unstable** presentation appropriate for emergency decision-making.',
                'Do **not** put the exam question in the stem; the lead-in carries the task.',
                'Keep all options in one **emergency-management decision family** (parallel urgent actions); do **not** offer “Request a full blood count and wait for results” or “Arrange a CT scan” alongside resuscitation options.',
                '**Suspected sepsis with hypotension, shock, or raised lactate:** acceptable option families include **IV fluids**, **broad-spectrum IV antibiotics**, **combined sepsis resuscitation bundle**, **oxygen if hypoxic**, **senior / critical care escalation**, and **vasopressor support** if fluid-refractory shock is clearly established in the stem — not laboratory or imaging options.',
                'When **Management** already appears in the same batch, the emergency keyed answer must be a **different concept** (not the same drug, pathway, or treatment family) unless Tutor comments explicitly allow repetition; a **combined sepsis bundle** after Management keyed antibiotics-only is allowed (see batch rules).',
                'Condition-specific emergency binding blocks elsewhere in this prompt (ACS, sepsis, ectopic pregnancy) take precedence when applicable.',
            ],
        ],
    ];
}

/**
 * Normalise Current skill from the form to a catalogue key, or '' if unknown.
 */
function sbaGeneratorNormalizeSkillKey(string $skill): string
{
    $skill = trim(preg_replace('/\s+/u', ' ', $skill));
    if ($skill === '') {
        return '';
    }
    foreach (sbaGeneratorSkillDefinitionCatalogue() as $key => $def) {
        if (preg_match($def['match'], $skill)) {
            return $key;
        }
    }

    return '';
}

/**
 * @return array{label: string, match: string, preferred_lead_ins: list<string>, allowed_option_types: list<string>, forbidden_option_types: list<string>, rules: list<string>}|null
 */
function sbaGeneratorGetSkillDefinition(string $skill): ?array
{
    $key = sbaGeneratorNormalizeSkillKey($skill);
    if ($key === '') {
        return null;
    }
    $catalogue = sbaGeneratorSkillDefinitionCatalogue();

    return $catalogue[$key] ?? null;
}

/**
 * Batch-aware lines appended for Emergency Management (form generator only).
 *
 * @param array<string, mixed> $job
 * @return list<string>
 */
function sbaGeneratorSkillBatchContextLines(string $skill, array $job): array
{
    $lines = [];
    $priors = $job['_batch_prior_questions'] ?? null;
    if (!is_array($priors) || $priors === []) {
        return $lines;
    }

    if (sbaGeneratorNormalizeSkillKey($skill) === 'emergency_management') {
        foreach ($priors as $p) {
            if (!is_array($p)) {
                continue;
            }
            $pSkill = trim((string) ($p['skill'] ?? ''));
            if (!preg_match('/^management$/i', $pSkill)) {
                continue;
            }
            $pAnswer = trim((string) ($p['correct_answer'] ?? ''));
            if ($pAnswer !== '') {
                $lines[] = 'Earlier **Management** item in this batch keyed: “'
                    . $pAnswer
                    . '” — **Emergency Management** must use a **different** urgent concept (not the same treatment family or synonymous wording).';
            }
            break;
        }
    }

    if (sbaGeneratorNormalizeSkillKey($skill) === 'management') {
        foreach ($priors as $p) {
            if (!is_array($p)) {
                continue;
            }
            $pSkill = trim((string) ($p['skill'] ?? ''));
            if (!preg_match('/^emergency\s+management$/i', $pSkill)) {
                continue;
            }
            $pAnswer = trim((string) ($p['correct_answer'] ?? ''));
            if ($pAnswer !== '') {
                $lines[] = 'Earlier **Emergency Management** item in this batch keyed: “'
                    . $pAnswer
                    . '” — **Management** must use a **different** standard management concept.';
            }
            break;
        }
    }

    return $lines;
}

/**
 * Build the skill-definition block injected into the SBA generator LLM prompt.
 *
 * @param array<string, mixed> $job
 */
function buildSbaGeneratorSkillPromptBlock(string $skill, array $job = []): string
{
    $def = sbaGeneratorGetSkillDefinition($skill);
    if ($def === null) {
        return '';
    }

    $lines = [];
    $lines[] = 'BINDING — CURRENT SKILL DEFINITION (' . $def['label'] . ')';
    $lines[] = 'The rules below apply **in addition** to global MS AKT rules. Where a more specific condition binding block exists elsewhere in this prompt, follow that binding when it applies.';
    $lines[] = '';
    $lines[] = '**Preferred lead-in wording** (use one; vary wording naturally):';
    foreach ($def['preferred_lead_ins'] as $leadIn) {
        $lines[] = '- ' . $leadIn;
    }
    $lines[] = '';
    $lines[] = '**Allowed option types (all five options A–E):**';
    foreach ($def['allowed_option_types'] as $allowed) {
        $lines[] = '- ' . $allowed;
    }
    $lines[] = '';
    $lines[] = '**Forbidden option types:**';
    foreach ($def['forbidden_option_types'] as $forbidden) {
        $lines[] = '- ' . $forbidden;
    }
    $lines[] = '';
    $lines[] = '**Skill-specific generation rules:**';
    foreach ($def['rules'] as $rule) {
        $lines[] = '- ' . $rule;
    }

    $batchLines = sbaGeneratorSkillBatchContextLines($skill, $job);
    if ($batchLines !== []) {
        $lines[] = '';
        $lines[] = '**This batch (skill separation):**';
        foreach ($batchLines as $batchLine) {
            $lines[] = '- ' . $batchLine;
        }
    }

    $jobSkills = (string) ($job['_job_skills'] ?? $job['skills'] ?? '');
    if ($jobSkills !== '' && str_contains($jobSkills, ',')) {
        $lines[] = '';
        $lines[] = '**Mixed-skill batch (this job):**';
        $lines[] = '- **Current skill** is mandatory — do **not** drift into a different skill from the rotation list.';
        $lines[] = '- Match **options** to **Current skill** only (diagnoses / investigations / interpretations / management / emergency actions).';
        $lines[] = '- **Vary lead-ins** and **keyed concepts** from prior items in this job; do not reuse the same template or answer line.';
    }

    $block = implode("\n", $lines);

    return "\n" . embedPromptField($block, 6000) . "\n";
}
