// ─────────────────────────────────────────────────────────────────────────────
// HTML_TEMPLATES — the data model for the template library (Fix A, OQ-077 Opt C)
// ─────────────────────────────────────────────────────────────────────────────
// One entry per pre-rendered HTML sample under uploads/html-samples/. These are
// the "templates" an author picks for a Quiz · gaming question whose media kind
// is HTML, and the catalogue the Admin "Manage templates" sub-screen lists.
//
// Phase-2 (this pass): every template now also carries a `tooltipParams` array —
// the inline-tooltip slots the template HTML exposes via {{name}} placeholders.
// Authors fill in the per-use tooltip text (a LocalizedString per slot) in the
// Templates picker; translators see the strings in the Localisation surface's
// Quiz Gaming tab. The Player rentime needs NO change — tooltips live in the
// template HTML itself (the canonical `.tip` / `.tip-text` CSS pattern verified
// in Phase 1), substituted at export.
//
// `tooltipParams` is SEPARATE from `parameters`. `parameters` is the Profile-form
// runtime token-substitution feature (filled by the Player from the Profile form
// at runtime, no author input) and stays exactly as-is.
//
// Every sample file ships the `<div class="quiz">` wrapper the Player contract
// requires (see 2026-06-04 quiz-html-iframe-quiz-wrapper-contract). The 8
// starter templates are read-only; only "+ New template" writes a new file
// (to uploads/html-samples/custom/<slug>.html) and appends to this registry.
//
// Author-facing copy never says "DFTI" (CLAUDE.md §23.2) — these are HTML
// templates for the Gamified Quiz / Quiz · gaming layout.
//
// TooltipParam = {
//   name: string,                  // placeholder slot id → {{name}} in the HTML
//   label: LocalizedString,        // form-field label the Author sees
//   description: LocalizedString,  // helper text under the label
// }

const _HTML_SAMPLE_ROOT = 'uploads/html-samples/content/en/modules/';

const HTML_TEMPLATES = [
  {
    id: 'tpl-single-image',
    name: 'Single image',
    category: 'image',
    complexity: 'low',
    description: 'A single full-width image with a short caption — the simplest media slot. Good for "spot the problem" questions.',
    previewUrl: _HTML_SAMPLE_ROOT + 'module_4/05.html',
    renderedHtmlUrl: _HTML_SAMPLE_ROOT + 'module_4/05.html',
    parameters: [],
    tooltipParams: [
      { name: 'sender_domain',
        label: { en: 'Sender domain' },
        description: { en: 'Explain why the From address is a look-alike domain, not the real provider.' } },
      { name: 'generic_greeting',
        label: { en: 'Generic greeting' },
        description: { en: 'Explain why a vague "Dear user" instead of the recipient\'s name is a tell.' } },
      { name: 'reset_link',
        label: { en: 'Reset link' },
        description: { en: 'Explain why following a reset link in an unexpected email is risky.' } },
      { name: 'urgency_deadline',
        label: { en: 'Urgency deadline' },
        description: { en: 'Explain how the short expiry window pressures the reader to skip their usual checks.' } },
    ],
    stylesheet: 'sample',
  },
  {
    id: 'tpl-annotated-screenshot',
    name: 'Annotated screenshot',
    category: 'screenshot',
    complexity: 'low-med',
    description: 'A screenshot with callout pins the learner can hover to read. Use it to point out the tells in a chat or app view.',
    previewUrl: _HTML_SAMPLE_ROOT + 'module_3/05A/04.html',
    renderedHtmlUrl: _HTML_SAMPLE_ROOT + 'module_3/05A/04.html',
    parameters: [],
    tooltipParams: [
      { name: 'unknown_sender',
        label: { en: 'Unknown sender' },
        description: { en: 'Explain why an urgent request from an unknown or "new" number should not be trusted.' } },
      { name: 'gift_card_payment',
        label: { en: 'Gift-card payment' },
        description: { en: 'Explain why gift cards are an untraceable scam payment method, never a real expense.' } },
      { name: 'urgency_pressure',
        label: { en: 'Urgency pressure' },
        description: { en: 'Explain how a tight deadline stops the reader pausing to verify.' } },
      { name: 'secrecy_request',
        label: { en: 'Secrecy request' },
        description: { en: 'Explain why being told to keep a payment secret is a red flag, not a sign of importance.' } },
    ],
    stylesheet: 'sample',
  },
  {
    id: 'tpl-multi-image-mockup',
    name: 'Multi-image mockup',
    category: 'mockup',
    complexity: 'med',
    description: 'A composed mockup that stacks several images into one realistic interface for richer "what looks wrong here?" prompts.',
    previewUrl: _HTML_SAMPLE_ROOT + 'module_4/09.html',
    renderedHtmlUrl: _HTML_SAMPLE_ROOT + 'module_4/09.html',
    parameters: [],
    tooltipParams: [
      { name: 'bank_detail_request',
        label: { en: 'Bank-detail request' },
        description: { en: 'Explain why re-entering bank details via an emailed link is a major red flag.' } },
      { name: 'unfamiliar_portal',
        label: { en: 'Unfamiliar portal' },
        description: { en: 'Explain why an unknown portal link asking for financial details should be verified first.' } },
      { name: 'payday_urgency',
        label: { en: 'Payday urgency' },
        description: { en: 'Explain how a same-day cut-off around payday manufactures pressure.' } },
    ],
    stylesheet: 'sample',
  },
  {
    id: 'tpl-phishy-email-typical',
    name: 'Phishy email — typical',
    category: 'phishing-email',
    complexity: 'med',
    description: 'A realistic suspicious email with hover-to-reveal cues on the giveaway lines. The most typical phishing-awareness template.',
    previewUrl: _HTML_SAMPLE_ROOT + 'module_4/03.html',
    renderedHtmlUrl: _HTML_SAMPLE_ROOT + 'module_4/03.html',
    parameters: [],
    tooltipParams: [
      { name: 'sender_domain',
        label: { en: 'Sender domain' },
        description: { en: 'Explain why the real address is a free mailbox, not a company domain.' } },
      { name: 'personal_info_request',
        label: { en: 'Personal-info request' },
        description: { en: 'Explain why being asked to reply with your name, address and number is a classic phishing pattern.' } },
      { name: 'suspicious_link',
        label: { en: 'Suspicious link' },
        description: { en: 'Explain why the button label and its real destination don\'t match — hover before clicking.' } },
      { name: 'urgency_deadline',
        label: { en: 'Urgency deadline' },
        description: { en: 'Explain how a "within 24 hours" deadline is designed to make you act before you think.' } },
    ],
    stylesheet: 'sample',
  },
  {
    id: 'tpl-phishy-email-heavy-tooltips',
    name: 'Phishy email — heavy tooltips',
    category: 'phishing-email',
    complexity: 'med-high',
    description: 'A phishing email packed with annotated cues — more tooltips, denser tells. For learners ready to find every red flag.',
    previewUrl: _HTML_SAMPLE_ROOT + 'module_4/01.html',
    renderedHtmlUrl: _HTML_SAMPLE_ROOT + 'module_4/01.html',
    parameters: [],
    tooltipParams: [
      { name: 'sender_domain',
        label: { en: 'Sender domain' },
        description: { en: 'Explain why a prize email from an unrecognised domain is suspect.' } },
      { name: 'prize_bait',
        label: { en: 'Prize bait' },
        description: { en: 'Explain why a too-good-to-be-true reward you never entered for is the hook.' } },
      { name: 'upfront_fee',
        label: { en: 'Upfront fee' },
        description: { en: 'Explain why a "small fee" to release a prize is a scam — real prizes never ask for payment.' } },
      { name: 'urgency_deadline',
        label: { en: 'Urgency deadline' },
        description: { en: 'Explain how a short countdown pressures you to act before checking.' } },
    ],
    stylesheet: 'sample',
  },
  {
    id: 'tpl-fake-login',
    name: 'Fake login screen',
    category: 'phishing-email',
    complexity: 'high',
    description: 'A spoofed sign-in page on an unfamiliar domain. The tell is in the address bar — a credential-harvest scenario rather than an email.',
    previewUrl: _HTML_SAMPLE_ROOT + 'module_2/02A/01.html',
    renderedHtmlUrl: _HTML_SAMPLE_ROOT + 'module_2/02A/01.html',
    parameters: [],
    tooltipParams: [
      { name: 'spoofed_domain',
        label: { en: 'Spoofed domain' },
        description: { en: 'Explain why the address bar shows a look-alike domain with no padlock — not the real sign-in page.' } },
      { name: 'confirm_password',
        label: { en: 'Confirm-password trap' },
        description: { en: 'Explain why a genuine login never asks you to confirm your password a second time just to sign in.' } },
    ],
    stylesheet: 'sample',
  },
  {
    id: 'tpl-social-oversharing',
    name: 'Social post — oversharing',
    category: 'social-quiz',
    complexity: 'med',
    description: 'A public social post that overshares physical-security details (holiday dates, address, hidden key). A non-link awareness scenario.',
    previewUrl: _HTML_SAMPLE_ROOT + 'module_3/05A/01.html',
    renderedHtmlUrl: _HTML_SAMPLE_ROOT + 'module_3/05A/01.html',
    parameters: [],
    tooltipParams: [
      { name: 'empty_home_dates',
        label: { en: 'Empty-home dates' },
        description: { en: 'Explain why announcing the exact dates the home is empty tells a thief when to call.' } },
      { name: 'home_address',
        label: { en: 'Home address' },
        description: { en: 'Explain why posting a full home address publicly gives a stranger everything they need.' } },
      { name: 'spare_key',
        label: { en: 'Spare-key location' },
        description: { en: 'Explain why naming where a spare key is hidden defeats the point of locking the door.' } },
    ],
    stylesheet: 'sample',
  },
  {
    id: 'tpl-smishing-text',
    name: 'Smishing text — missed delivery',
    category: 'social-quiz',
    complexity: 'med-high',
    description: 'A text-message lure about a missed parcel demanding a small redelivery fee via a shortened link before a same-day deadline.',
    previewUrl: _HTML_SAMPLE_ROOT + 'module_2/02A/06.html',
    renderedHtmlUrl: _HTML_SAMPLE_ROOT + 'module_2/02A/06.html',
    parameters: [],
    tooltipParams: [
      { name: 'unknown_number',
        label: { en: 'Unknown number' },
        description: { en: 'Explain why a real courier texts from a recognised service ID, not a random mobile number.' } },
      { name: 'no_tracking',
        label: { en: 'No tracking detail' },
        description: { en: 'Explain why a genuine courier always references your specific order, never "no one was available".' } },
      { name: 'redelivery_fee',
        label: { en: 'Redelivery fee' },
        description: { en: 'Explain why legitimate redelivery is free — a small "fee" is bait for your card details.' } },
      { name: 'shortened_link',
        label: { en: 'Shortened link' },
        description: { en: 'Explain why a shortened link hides its real destination — never tap to "pay a fee" from a text.' } },
    ],
    stylesheet: 'sample',
  },
];

// ── Resolve the tooltipParams for a given HTML file URL ──────────────────────
// The live quiz HTML-media editor (HtmlMediaEditor) and the localisation surface
// bind by htmlUrl; both look up the template's slot definitions this way so the
// HTML_SAMPLES (data.jsx) and HTML_TEMPLATES (here) registries stay decoupled
// while still sharing one slot model per file.
function templateForHtmlUrl(url) {
  if (!url) return null;
  return (window.HTML_TEMPLATES || []).find(t => t.renderedHtmlUrl === url || t.previewUrl === url) || null;
}
function tooltipParamsForHtmlUrl(url) {
  const t = templateForHtmlUrl(url);
  return (t && t.tooltipParams) || [];
}

// Detect {{placeholder}} slot names in a blob of pasted template HTML — powers
// the "Detected in HTML" hint in the Admin tooltip-slot editor (Fix C).
function detectTooltipPlaceholders(html) {
  if (!html) return [];
  const out = [];
  const seen = new Set();
  const re = /\{\{\s*([a-z0-9_]+)\s*\}\}/gi;
  let m;
  while ((m = re.exec(html)) !== null) {
    const name = m[1];
    if (!seen.has(name)) { seen.add(name); out.push(name); }
  }
  return out;
}

window.HTML_TEMPLATES = HTML_TEMPLATES;
Object.assign(window, { templateForHtmlUrl, tooltipParamsForHtmlUrl, detectTooltipPlaceholders });
