<?php

/**
 * Community-acquired pneumonia — Prescribing bindings for the form-based SBA generator only.
 */

function sbaGeneratorConditionLooksCommunityAcquiredPneumonia(string $conditionName): bool
{
    $c = mb_strtolower(trim($conditionName));

    return (bool) preg_match(
        '/\bcommunity[\s-]*acquired\s+pneumonia\b|\bcommunity\s+acquired\s+pneumonia\b|\b(?:^|\s)cap(?:\s|$)/i',
        $c
    );
}

/**
 * @return list<string>
 */
function sbaCapPrescribingScenarioSlotKeys(): array
{
    return [
        'uncomplicated',
        'allergy',
        'atypical',
        'frailty_comorbidity',
        'aspiration',
        'severe_iv',
        'treatment_failure',
    ];
}

function sbaCapPrescribingTutorAllowsRepeatUncomplicatedCap(string $tutorComments): bool
{
    if ($tutorComments === '') {
        return false;
    }

    return (bool) preg_match(
        '/\b(?:repeat|same|each|every|all\s+five|all\s+items?).{0,60}(?:uncomplicated|amoxicillin|mild\s+cap|stable\s+mild)|(?:uncomplicated|amoxicillin|mild\s+cap|stable\s+mild).{0,60}(?:repeat|same|each|every|all\s+items?)\b/i',
        $tutorComments
    ) || (function_exists('sbaStyleTutorAllowsRepeatBatchAnswerConcept')
        && sbaStyleTutorAllowsRepeatBatchAnswerConcept(['_tutor_comments' => $tutorComments]));
}

/**
 * How many Prescribing items this job will contain (from skills list and/or prior rows).
 *
 * @param array<string, mixed> $question
 */
function sbaCapPrescribingCountPrescribingSlotsInJob(array $question): int
{
    $fromCsv = 0;
    $skillsCsv = trim((string) ($question['_job_skills'] ?? ''));
    if ($skillsCsv !== '') {
        $fromCsv = preg_match_all('/\bprescribing\b/i', $skillsCsv) ?: 0;
    }

    $fromRows = 0;
    $priors = $question['_batch_prior_questions'] ?? [];
    if (is_array($priors)) {
        foreach ($priors as $p) {
            if (is_array($p) && preg_match('/^prescribing$/i', trim((string) ($p['skill'] ?? '')))) {
                ++$fromRows;
            }
        }
    }
    if (preg_match('/^prescribing$/i', trim((string) ($question['_current_skill'] ?? '')))) {
        ++$fromRows;
    }

    return max($fromCsv, $fromRows);
}

/**
 * @param array<string, mixed> $question
 */
function sbaCapPrescribingShouldApplyBatchDiversityRules(array $question): bool
{
    if (sbaCapPrescribingCountPrescribingSlotsInJob($question) <= 1) {
        return false;
    }
    $priors = $question['_batch_prior_questions'] ?? [];
    $condition = trim((string) ($question['_condition_name'] ?? ''));
    if (!is_array($priors)) {
        return false;
    }
    foreach ($priors as $p) {
        if (is_array($p) && sbaCapPrescribingRowIsCapPrescribingItem($p, $condition)) {
            return true;
        }
    }

    return false;
}

/**
 * @param array<string, mixed> $row
 */
function sbaCapPrescribingRowIsCapPrescribingItem(array $row, string $conditionName = ''): bool
{
    $sk = trim((string) ($row['skill'] ?? $row['_current_skill'] ?? ''));
    if (!preg_match('/^prescribing$/i', $sk)) {
        return false;
    }
    if ($conditionName !== '' && sbaGeneratorConditionLooksCommunityAcquiredPneumonia($conditionName)) {
        return true;
    }
    $parts = [];
    foreach (['title', 'stem', 'lead_in'] as $k) {
        if (!empty($row[$k]) && is_string($row[$k])) {
            $parts[] = trim($row[$k]);
        }
    }

    return function_exists('sbaStyleBlobSuggestsCommunityAcquiredPneumonia')
        ? sbaStyleBlobSuggestsCommunityAcquiredPneumonia(implode(' ', $parts))
        : (bool) preg_match('/\bcommunity[\s-]*acquired\s+pneumonia\b|\bcap\b/i', implode(' ', $parts));
}

function sbaCapPrescribingStemSuggestsPenicillinAllergy(string $blob): bool
{
    return (bool) preg_match(
        '/\b(?:penicillin|beta[\s-]?lactam|amoxicillin)\s+allerg|\ballerg(?:y|ic)\s+to\s+(?:penicillin|amoxicillin|beta[\s-]?lactam)\b|\bknown\s+allerg.*\bpenicillin\b/i',
        $blob
    );
}

function sbaCapPrescribingStemSuggestsAtypicalPneumonia(string $blob): bool
{
    return (bool) preg_match(
        '/\b(?:atypical\s+pneumonia|mycoplasma|legionella|chlamydia\s+pneumoniae|dry\s+cough.{0,40}(?:systemic|fever)|patchy\s+(?:chest\s+)?signs|influenza\s+exposure|parrot\s+fever)\b/i',
        $blob
    );
}

function sbaCapPrescribingStemSuggestsAspirationRisk(string $blob): bool
{
    return (bool) preg_match(
        '/\b(?:aspiration\s+(?:risk|pneumonia)|aspirated|impaired\s+swallow|dysphagia|vomit(?:ing|ed)?\s+(?:into|with)|risk\s+of\s+aspiration)\b/i',
        $blob
    );
}

function sbaCapPrescribingStemSuggestsFrailtyOrSignificantComorbidity(string $blob): bool
{
    return (bool) preg_match(
        '/\b(?:frail(?:ty)?|nursing[\s-]home\s+resident|care\s+home\s+resident|immunosuppress|immunocompromis|severe\s+COPD|heart\s+failure|diabetes\s+with\s+complications)\b/i',
        $blob
    );
}

function sbaCapPrescribingBlobMentionsDiabetesMellitus(string $blob): bool
{
    if ($blob === '') {
        return false;
    }

    return (bool) preg_match(
        '/\b(?:type\s*[12]\s*)?diabetes(?:\s+mellitus)?\b|\bdiabetic\b/i',
        $blob
    );
}

function sbaCapPrescribingBlobMentionsDiabetesWithComplications(string $blob): bool
{
    return (bool) preg_match('/\bdiabetes\s+with\s+complications\b/i', $blob);
}

function sbaCapPrescribingJustificationClaimsDiabetesWarrantsBroaderCover(string $justification): bool
{
    $just = trim($justification);
    if ($just === '' || !sbaCapPrescribingBlobMentionsDiabetesMellitus($just)) {
        return false;
    }

    return (bool) preg_match(
        '/\b(?:broader\s+cover|broad[\s-]spectrum|co[\s-]?amoxiclav|co[\s-]?amox\b|amoxicillin[\s-]?(?:clavulanate|clavulanic)|augmentin|beta[\s-]?lactamase|β[\s-]?lactamase|clavulanate|anaerobic|organisms?\s+requiring|warrants?\s+(?:broader|co[\s-]?amox)|(?:given|because\s+of|due\s+to).{0,40}\bdiabetes)\b/i',
        $just
    );
}

/**
 * Non-diabetes co-amoxiclav indications stated in justification text.
 */
function sbaCapPrescribingJustificationMentionsClearCoAmoxIndication(string $justification): bool
{
    $just = trim($justification);
    if ($just === '') {
        return false;
    }

    return (bool) preg_match(
        '/\b(?:aspiration|dysphagia|frail(?:ty)?|nursing[\s-]home|care\s+home|immunosuppress|immunocompromis|severe\s+pneumonia|moderate[\s-]to[\s-]severe|curb[\s-]?65|crb[\s-]?65|treatment\s+failure|recent\s+antibiotic|failed\s+(?:a\s+)?(?:course\s+of\s+)?amoxicillin|hospital[\s-]acquired|unable\s+to\s+(?:take|tolerate)\s+oral|heart\s+failure|severe\s+COPD|diabetes\s+with\s+complications)\b/i',
        $just
    );
}

/**
 * Stem/tutor carries a clear co-amoxiclav indication (not type 2 diabetes mellitus alone).
 */
function sbaCapPrescribingBlobHasClearCoAmoxiclavIndication(string $blob, string $tutorComments = ''): bool
{
    return function_exists('sbaStyleBlobJustifiesCoAmoxiclavForCap')
        && sbaStyleBlobJustifiesCoAmoxiclavForCap($blob, $tutorComments);
}

/**
 * Diabetes is present but is the only broader-cover rationale (stem and/or justification).
 */
function sbaCapPrescribingDiabetesAloneIsOnlyBroaderCoverRationale(
    string $stemBlob,
    string $tutorComments,
    string $justification = ''
): bool {
    $full = trim($stemBlob . "\n" . $justification);
    if (!sbaCapPrescribingBlobMentionsDiabetesMellitus($full)) {
        return false;
    }
    if (sbaCapPrescribingBlobMentionsDiabetesWithComplications($full)) {
        return false;
    }

    $stemAndTutor = trim($stemBlob . "\n" . $tutorComments);
    if (sbaCapPrescribingBlobHasClearCoAmoxiclavIndication($stemAndTutor, $tutorComments)) {
        if ($justification !== ''
            && sbaCapPrescribingJustificationClaimsDiabetesWarrantsBroaderCover($justification)
            && !sbaCapPrescribingJustificationMentionsClearCoAmoxIndication($justification)) {
            return true;
        }

        return false;
    }

    if ($justification !== '' && sbaCapPrescribingJustificationClaimsDiabetesWarrantsBroaderCover($justification)) {
        return true;
    }

    return sbaCapPrescribingBlobMentionsDiabetesMellitus($stemBlob);
}

function sbaCapPrescribingStemSuggestsTreatmentFailureOrRecentAntibiotics(string $blob): bool
{
    return (bool) preg_match(
        '/\b(?:recent\s+antibiotic|previous\s+(?:course\s+of\s+)?antibiotic|already\s+(?:on|taking)\s+antibiotic|treatment\s+failure|failed\s+(?:a\s+)?(?:course\s+of\s+)?amoxicillin|no\s+improvement\s+(?:on|with|after)\s+amoxicillin)\b/i',
        $blob
    );
}

function sbaCapPrescribingStemSuggestsSevereOrIvContext(string $blob, string $keyed = ''): bool
{
    $combined = $blob . "\n" . $keyed;
    if (preg_match(
        '/\b(?:unable\s+to\s+(?:take|tolerate)\s+oral|cannot\s+swallow|nil\s+by\s+mouth|\bnpo\b|intravenous\s+antibiotic|iv\s+antibiotic|iv\s+(?:co[\s-]?amoxiclav|amoxicillin|benzylpenicillin|cef(?:triaxone|otaxime)|piperacillin|levofloxacin))\b/i',
        $combined
    )) {
        return true;
    }
    if (function_exists('sbaStyleBlobSuggestsSeverityOrReferralTriage')
        && sbaStyleBlobSuggestsSeverityOrReferralTriage($combined)) {
        return true;
    }

    return (bool) preg_match(
        '/\b(?:severe\s+pneumonia|moderate[\s-]to[\s-]severe\s+pneumonia|curb[\s-]?65\s*(?:score\s*)?(?:is|of|was|:)?\s*[4-5]|crb[\s-]?65\s*(?:score\s*)?(?:is|of|was|:)?\s*[4-5])\b/i',
        $combined
    );
}

/**
 * Clinical rationale slot for CAP Prescribing batch tracking.
 *
 * @return ''|'uncomplicated'|'allergy'|'atypical'|'frailty_comorbidity'|'aspiration'|'severe_iv'|'treatment_failure'
 */
function sbaCapPrescribingInferClinicalRationale(string $stem, string $title, string $lead, string $tutor, string $keyed = ''): string
{
    $blob = trim($title . "\n" . $stem . "\n" . $lead);
    $combined = trim($blob . "\n" . $tutor . "\n" . $keyed);
    if ($combined === '') {
        return '';
    }
    if (sbaCapPrescribingStemSuggestsTreatmentFailureOrRecentAntibiotics($combined)) {
        return 'treatment_failure';
    }
    if (sbaCapPrescribingStemSuggestsSevereOrIvContext($blob, $keyed)) {
        return 'severe_iv';
    }
    if (sbaCapPrescribingStemSuggestsPenicillinAllergy($combined)) {
        return 'allergy';
    }
    if (sbaCapPrescribingStemSuggestsAtypicalPneumonia($combined)) {
        return 'atypical';
    }
    if (sbaCapPrescribingStemSuggestsAspirationRisk($combined)) {
        return 'aspiration';
    }
    if (sbaCapPrescribingStemSuggestsFrailtyOrSignificantComorbidity($combined)) {
        return 'frailty_comorbidity';
    }

    return 'uncomplicated';
}

function sbaCapPrescribingRationaleDisplayLabel(string $rationale): string
{
    return match ($rationale) {
        'uncomplicated' => 'stable mild CAP, no allergy (amoxicillin slot)',
        'allergy' => 'penicillin allergy (doxycycline or clarithromycin)',
        'atypical' => 'atypical pneumonia features (doxycycline or clarithromycin)',
        'frailty_comorbidity' => 'frailty or high-risk comorbidity (co-amoxiclav if justified — not diabetes alone)',
        'aspiration' => 'aspiration risk (co-amoxiclav if justified)',
        'severe_iv' => 'severe CAP or unable to take oral (IV antibiotic if appropriate)',
        'treatment_failure' => 'recent antibiotics or treatment failure (broader/alternative regimen)',
        default => $rationale,
    };
}

/**
 * @param list<array<string, mixed>> $priors
 * @return list<array{rationale: string, family: string, keyed: string}>
 */
function sbaCapPrescribingCollectBatchTracking(array $priors, string $conditionName): array
{
    $tracked = [];
    foreach ($priors as $p) {
        if (!is_array($p) || !sbaCapPrescribingRowIsCapPrescribingItem($p, $conditionName)) {
            continue;
        }
        $stem = trim((string) ($p['stem'] ?? ''));
        $title = trim((string) ($p['title'] ?? ''));
        $lead = trim((string) ($p['lead_in'] ?? ''));
        $keyed = trim((string) ($p['correct_answer'] ?? ''));
        $family = function_exists('sbaStyleCapPrescribingKeyedAntibioticFamily')
            ? sbaStyleCapPrescribingKeyedAntibioticFamily($keyed)
            : '';
        $rationale = sbaCapPrescribingInferClinicalRationale($stem, $title, $lead, '', $keyed);
        $tracked[] = [
            'rationale' => $rationale,
            'family' => $family,
            'keyed' => $keyed,
        ];
    }

    return $tracked;
}

/**
 * @param list<array<string, mixed>> $priors
 */
function sbaCapPrescribingBatchAmoxicillinAlreadyKeyed(array $priors, string $conditionName): bool
{
    foreach ($priors as $p) {
        if (!is_array($p) || !sbaCapPrescribingRowIsCapPrescribingItem($p, $conditionName)) {
            continue;
        }
        $keyed = trim((string) ($p['correct_answer'] ?? ''));
        if ($keyed === '') {
            continue;
        }
        $family = function_exists('sbaStyleCapPrescribingKeyedAntibioticFamily')
            ? sbaStyleCapPrescribingKeyedAntibioticFamily($keyed)
            : (preg_match('/\bamoxicillin\b/i', $keyed) && !preg_match('/\bclavulanate\b/i', $keyed) ? 'amoxicillin' : '');

        if ($family === 'amoxicillin') {
            return true;
        }
    }

    return false;
}

/**
 * Mandatory regeneration guidance when co-amoxiclav overuse was flagged (form generator retry).
 *
 * @param list<string> $lines
 * @param list<array<string, mixed>> $priors
 */
function sbaCapPrescribingAppendCoAmoxOveruseRetryGuidance(
    array &$lines,
    array $priors,
    string $conditionName,
    string $tutorComments = ''
): void {
    $amoxUsed = sbaCapPrescribingBatchAmoxicillinAlreadyKeyed($priors, $conditionName);
    $allowRepeat = sbaCapPrescribingTutorAllowsRepeatUncomplicatedCap($tutorComments);

    $lines[] = '- **Do not use type 2 diabetes mellitus alone as the justification for co-amoxiclav in stable mild CAP.**';

    if ($amoxUsed && !$allowRepeat) {
        $lines[] = '- **Batch constraint (mandatory):** **Amoxicillin** is **already the keyed answer** on an earlier **CAP Prescribing** item in this batch — **do not** key **amoxicillin** again and **do not** regenerate another **stable mild uncomplicated CAP** vignette unless **Tutor comments** explicitly request repetition.';
        $tracked = sbaCapPrescribingCollectBatchTracking($priors, $conditionName);
        $unused = array_values(array_filter(
            sbaCapPrescribingUnusedScenarioSlots($tracked),
            static fn (string $slot): bool => $slot !== 'uncomplicated'
        ));
        if ($unused !== []) {
            $labels = array_map('sbaCapPrescribingRationaleDisplayLabel', $unused);
            $lines[] = '- **Choose one unused scenario slot for this regeneration:** ' . implode('; ', $labels) . '.';
        }
        $lines[] = '- **Slot-specific fixes (use an unused slot — align stem, key, and justification):**';
        $lines[] = '  - **Penicillin allergy** → state **penicillin / beta-lactam allergy** in the **stem**; key **Doxycycline** or **Clarithromycin** (drug names only in options).';
        $lines[] = '  - **Atypical features** → atypical cues in the **stem**; key **Doxycycline** or **Clarithromycin**.';
        $lines[] = '  - **Aspiration risk** → aspiration / dysphagia in the **stem**; key **Co-amoxiclav** only if the stem justifies broader cover.';
        $lines[] = '  - **Treatment failure / recent antibiotics** → failed course or recent antibiotics in the **stem**; broader or alternative regimen.';
        $lines[] = '  - **Severe CAP / unable to take oral** → severity or IV need in the **stem**; **IV antibiotic** if appropriate.';
    } else {
        $lines[] = '- Either **(a)** key **Amoxicillin** (drug name only) for **stable mild CAP** without penicillin allergy when **amoxicillin has not** already been used in this batch, **or** **(b)** revise the **stem** to justify **co-amoxiclav** (aspiration risk, frailty with significant concern, severe pneumonia, recent antibiotic exposure, treatment failure, immunosuppression, hospital-acquired context, or explicit tutor/local guidance).';
        $lines[] = '- If this is a **multi-item batch**, prefer an **unused scenario slot** over defaulting to uncomplicated amoxicillin.';
    }

    $lines[] = '- **Justification** must match the **stem** (no penicillin allergy in the justification if the stem states **no known drug allergies**).';
    $lines[] = '- Keep **all five options** as **prescribing / antimicrobial choices** only (drug names only when testing antibiotic selection).';
}

/**
 * @param list<array{rationale: string, family: string, keyed: string}> $tracked
 * @return list<string>
 */
function sbaCapPrescribingUnusedScenarioSlots(array $tracked): array
{
    $used = [];
    foreach ($tracked as $t) {
        $r = (string) ($t['rationale'] ?? '');
        if ($r !== '') {
            $used[$r] = true;
        }
    }
    $unused = [];
    foreach (sbaCapPrescribingScenarioSlotKeys() as $slot) {
        if (empty($used[$slot])) {
            $unused[] = $slot;
        }
    }

    return $unused;
}

/**
 * @param list<string> $lines
 * @param list<array<string, mixed>> $priorRows
 */
function sbaCapPrescribingAppendBatchAntiRepetitionLines(
    array &$lines,
    array $priorRows,
    string $currentSkill,
    string $conditionName,
    string $jobSkillsCsv,
    string $tutorComments = ''
): void {
    if (!sbaGeneratorConditionLooksCommunityAcquiredPneumonia($conditionName)) {
        return;
    }
    $jobHasPrescribing = $jobSkillsCsv !== '' && preg_match('/\bprescribing\b/i', $jobSkillsCsv);
    if (!$jobHasPrescribing && !preg_match('/^prescribing$/i', $currentSkill)) {
        return;
    }

    $slotCount = sbaCapPrescribingCountPrescribingSlotsInJob([
        '_job_skills' => $jobSkillsCsv,
        '_batch_prior_questions' => $priorRows,
        '_current_skill' => $currentSkill,
    ]);
    if ($slotCount < 2) {
        return;
    }

    $tracked = sbaCapPrescribingCollectBatchTracking($priorRows, $conditionName);
    $lines[] = '**Community-acquired pneumonia — Prescribing batch scenario map (mandatory for multi-item Prescribing batches):**';
    $lines[] = 'Use **one distinct scenario slot per Prescribing item**. Do **not** repeat the same **clinical rationale** with the same **keyed antibiotic family**. **Amoxicillin** may be keyed **at most once** in the batch unless **Tutor comments** explicitly request repeated uncomplicated CAP.';
    $lines[] = '';
    $lines[] = '**Scenario slots (rotate across the batch):**';
    $lines[] = '1. **uncomplicated** — stable mild CAP, no allergy, oral route → **amoxicillin**';
    $lines[] = '2. **allergy** — penicillin allergy documented → **doxycycline** or **clarithromycin**';
    $lines[] = '3. **atypical** — atypical pneumonia features → **doxycycline** or **clarithromycin**';
    $lines[] = '4. **frailty_comorbidity** — frailty, immunosuppression, heart failure, severe COPD, or care-home resident → **co-amoxiclav** if stem justifies broader cover (**not** type 2 diabetes mellitus alone)';
    $lines[] = '5. **aspiration** — aspiration risk → **co-amoxiclav** if justified';
    $lines[] = '6. **severe_iv** — unable to take oral or severe CAP → **IV antibiotic** option if appropriate (e.g. IV co-amoxiclav, benzylpenicillin, ceftriaxone per local practice)';
    $lines[] = '7. **treatment_failure** — recent antibiotic exposure or failure after amoxicillin → broader or alternative regimen';
    $lines[] = '';
    if ($tracked !== []) {
        $lines[] = '**Already used in this batch (do not repeat the same rationale + antibiotic pairing):**';
        foreach ($tracked as $i => $t) {
            $n = $i + 1;
            $fam = (string) ($t['family'] ?? '');
            $rat = (string) ($t['rationale'] ?? '');
            $keyed = (string) ($t['keyed'] ?? '');
            $lines[] = '- Prior CAP Prescribing #' . $n . ': rationale **' . sbaCapPrescribingRationaleDisplayLabel($rat)
                . '**; antibiotic family **' . ($fam !== '' ? $fam : '(unparsed)') . '**'
                . ($keyed !== '' ? '; keyed “' . $keyed . '”' : '') . '.';
        }
        $unused = sbaCapPrescribingUnusedScenarioSlots($tracked);
        if ($unused !== []) {
            $labels = array_map('sbaCapPrescribingRationaleDisplayLabel', $unused);
            $lines[] = '**Prefer an unused scenario slot for this new item:** ' . implode('; ', $labels) . '.';
        }
        $amoxUsed = false;
        foreach ($tracked as $t) {
            if (($t['family'] ?? '') === 'amoxicillin') {
                $amoxUsed = true;
                break;
            }
        }
        if ($amoxUsed && !sbaCapPrescribingTutorAllowsRepeatUncomplicatedCap($tutorComments)) {
            $lines[] = '**Amoxicillin already keyed in this batch** — choose a **different scenario slot** and **different antibiotic** (not amoxicillin again).';
        }
    }
    $lines[] = '- Vary **lead-in wording**, **age/frailty**, **observations**, and **distractor antibiotics** — not only the keyed line.';
    $lines[] = '- **Options:** prescribing / antimicrobial choices only.';
    $lines[] = '';
}

/**
 * @param array<string, mixed> $job
 */
function buildSbaGeneratorCapPrescribingPromptBlock(array $job): string
{
    $condition = (string) ($job['condition_name'] ?? '');
    $skill = trim((string) ($job['skill'] ?? ''));
    if (!sbaGeneratorConditionLooksCommunityAcquiredPneumonia($condition)
        || !preg_match('/^prescribing$/i', $skill)) {
        return '';
    }

    $tutor = trim((string) ($job['tutor_comments'] ?? ''));
    $priors = isset($job['_batch_prior_questions']) && is_array($job['_batch_prior_questions'])
        ? $job['_batch_prior_questions']
        : [];
    $jobSkills = (string) ($job['_job_skills'] ?? $job['skills'] ?? '');
    $multiPrescribingBatch = sbaCapPrescribingCountPrescribingSlotsInJob([
        '_job_skills' => $jobSkills,
        '_batch_prior_questions' => $priors,
        '_current_skill' => $skill,
    ]) >= 2;

    $lines = [];
    $lines[] = 'BINDING — COMMUNITY-ACQUIRED PNEUMONIA PRESCRIBING (Current skill = Prescribing)';
    $lines[] = '**All five options** must be **prescribing choices** only — **not** admission, referral, investigation, or severity-scoring options unless **Tutor comments** explicitly test triage.';
    if ($tutor === '') {
        $lines[] = '**Option format (default drug selection):** use **drug names only** in A–E (e.g. **Amoxicillin**, **Doxycycline**, **Clarithromycin**, **Co-amoxiclav**, **Ciprofloxacin**) — **do not** add dose, route, or frequency (mg, orally, TDS) on every line unless this item explicitly tests dose/route/frequency.';
    } else {
        $lines[] = '**Option format:** match the prescribing learning point in **Tutor comments** — for **drug selection**, prefer **drug names only**; include dose/frequency only when Tutor comments or the lead-in require it.';
    }
    $lines[] = '';

    if ($multiPrescribingBatch && !sbaCapPrescribingTutorAllowsRepeatUncomplicatedCap($tutor)) {
        $lines[] = '**Multi-item Prescribing batch (mandatory diversity):**';
        $lines[] = '- This job includes **more than one Prescribing item** for CAP — use a **different clinically meaningful scenario** from prior items (see batch anti-repetition block).';
        $lines[] = '- **Amoxicillin** may be the keyed answer **at most once** in the batch (typically one **uncomplicated** slot only).';
        $lines[] = '- Do **not** reuse the same **stable mild CAP / no allergy / oral** template, the same **lead-in**, or the same **five-option antibiotic list** across items.';
        $lines[] = '';
        $tracked = sbaCapPrescribingCollectBatchTracking($priors, $condition);
        $unused = sbaCapPrescribingUnusedScenarioSlots($tracked);
        if ($unused !== []) {
            $labels = array_map('sbaCapPrescribingRationaleDisplayLabel', $unused);
            $lines[] = '**Unused scenario slots to prioritise for this item:** ' . implode('; ', $labels) . '.';
        }
        $lines[] = '';
    }

    $lines[] = '**Scenario slots (single-item or batch):**';
    $lines[] = '| Slot | Stem should include | Likely keyed antibiotic |';
    $lines[] = '| **uncomplicated** | Stable mild CAP, no penicillin allergy, oral route, no major comorbidity | **Amoxicillin** |';
    $lines[] = '| **allergy** | Penicillin / beta-lactam allergy | **Doxycycline** or **clarithromycin** |';
    $lines[] = '| **atypical** | Atypical features (e.g. dry cough, patchy signs, exposure cues) | **Doxycycline** or **clarithromycin** |';
    $lines[] = '| **frailty_comorbidity** | Frailty, immunosuppression, heart failure, severe COPD, care-home resident, or diabetes **with complications** | **Co-amoxiclav** if broader cover justified |';
    $lines[] = '| **aspiration** | Aspiration risk / aspiration pneumonia context | **Co-amoxiclav** if justified |';
    $lines[] = '| **severe_iv** | Unable to take oral and/or severe CAP needing parenteral therapy | **IV antibiotic** (e.g. IV co-amoxiclav, benzylpenicillin, ceftriaxone) |';
    $lines[] = '| **treatment_failure** | Recent antibiotics or failure after amoxicillin | Broader or alternative regimen |';
    $lines[] = '';
    $lines[] = '**Stable, mild CAP (uncomplicated slot — also correct for a lone Prescribing item):**';
    $lines[] = '- **No penicillin allergy**, **no aspiration risk**, **no recent antibiotics**, **no hospital-acquired context**, **oral therapy appropriate** → usually key **amoxicillin**.';
    $lines[] = '- **Type 2 diabetes mellitus alone** (well-controlled, no complications) is **not** a reason for **co-amoxiclav** in stable mild CAP — key **amoxicillin** unless **penicillin allergy** or **atypical** features apply.';
    $lines[] = '- **Do not** default to **co-amoxiclav** for uncomplicated stable CAP.';
    $lines[] = '- **Do not** write in the **justification** that diabetes alone warrants broader cover or co-amoxiclav.';
    $lines[] = '';
    $lines[] = '**Doxycycline or clarithromycin** when the stem supports **allergy** or **atypical** slots (or **Tutor comments**).';
    $lines[] = '**Co-amoxiclav** only when the stem (or **Tutor comments**) justify broader cover: **aspiration risk**, **frailty with significant clinical concern**, **severe pneumonia**, **recent antibiotic exposure**, **treatment failure**, **immunosuppression**, **hospital-acquired context**, **diabetes with complications**, or **explicit local/hospital guidance** — **not** diabetes mellitus alone.';
    $lines[] = '';
    $lines[] = '**Vignette alignment:** match observations and context to the **chosen scenario slot**; do not label every item as identical “stable mild CAP” when the batch requires variety.';

    return "\n" . embedPromptField(implode("\n", $lines), 7000) . "\n";
}
