// Brook Consultancy — Bring-your-own-AI prompt builders
//
// Pattern mirrors the Ofsted EYFS app:
//   1. Consultant pastes Meeting Summary and/or Transcript on the AI Assist screen
//   2. For each section (or "Master prompt"), they click → modal opens
//      Step 1: Copy prompt   — full prompt with criteria + transcript inlined
//      Step 2: Paste response — JSON is extracted (even from markdown/prose) and applied
//   3. Each section is independently re-runnable; cards show ✓ Applied / Re-do
//
// All prompts share the same preamble and rules; only the schema/criteria differ per section.

const BROOK_PREAMBLE = `You are an experienced business management consultant conducting a comprehensive operational review on behalf of Brook Consultancy Partners.

Analyse the meeting summary and/or transcript below. Extract evidence ONLY from what is actually documented — do NOT invent facts. Where there is no evidence, return an empty array — never make assumptions.

Confidence levels:
  high = direct evidence (verbatim quote or explicit statement)
  med  = reasonable inference from context
  low  = limited or indirect evidence

CRITICAL RULES:
- Skip any indicator or item that has NO supporting evidence in the source
- Better to omit than to invent
- Be specific and quote-like in evidence bullets so findings can be verified against source
- Only include what can be substantiated from the actual content provided`;

const BROOK_GRADE_SCALE = '"exceptional" | "strong" | "adequate" | "needs_improvement" | "critical" | "insufficient_evidence"';

// ---------------------------------------------------------------
// Per-area indicator definitions (used to build prompts)
// ---------------------------------------------------------------
const BROOK_AREAS = [
  {
    id: 'leadership', name: 'Leadership & Strategy',
    indicators: [
      { id: 'ls_vision', name: 'Strategic Vision', desc: 'Clear, documented strategic direction understood and embraced across the organisation' },
      { id: 'ls_goals', name: 'Goal Setting & KPIs', desc: 'SMART objectives set with measurable KPIs and regular progress tracking' },
      { id: 'ls_decision', name: 'Decision Making', desc: 'Timely, evidence-based decisions with clear accountability and communication' },
      { id: 'ls_change', name: 'Change Management', desc: 'Structured approach to implementing and embedding organisational change' }
    ]
  },
  {
    id: 'operations', name: 'Operations & Processes',
    indicators: [
      { id: 'op_efficiency', name: 'Operational Efficiency', desc: 'Streamlined processes that minimise waste and maximise productivity' },
      { id: 'op_quality', name: 'Quality Management', desc: 'Consistent quality standards with monitoring, review and continuous improvement' },
      { id: 'op_documentation', name: 'Process Documentation', desc: 'Procedures documented, accessible, current and followed in practice' },
      { id: 'op_compliance', name: 'Compliance & Controls', desc: 'Internal controls effective; regulatory and legal requirements met' }
    ]
  },
  {
    id: 'financial', name: 'Financial Management',
    indicators: [
      { id: 'fm_planning', name: 'Financial Planning', desc: 'Realistic budgets, forecasts and cash flow management' },
      { id: 'fm_reporting', name: 'Financial Reporting', desc: 'Accurate, timely reports that inform decision-making' },
      { id: 'fm_controls', name: 'Financial Controls', desc: 'Segregation of duties, authorisation levels, audit trails in place' },
      { id: 'fm_performance', name: 'Financial Performance', desc: 'Revenue, margins and cost management meet targets' }
    ]
  },
  {
    id: 'people', name: 'People & Culture',
    indicators: [
      { id: 'pc_talent', name: 'Talent Management', desc: 'Effective recruitment, onboarding, development and retention strategies' },
      { id: 'pc_performance', name: 'Performance Management', desc: 'Clear expectations, regular feedback, and documented reviews' },
      { id: 'pc_culture', name: 'Organisational Culture', desc: 'Positive, inclusive culture with high engagement and morale' },
      { id: 'pc_capacity', name: 'Capacity & Workload', desc: 'Adequate staffing levels with manageable, sustainable workloads' }
    ]
  },
  {
    id: 'risk', name: 'Risk & Governance',
    indicators: [
      { id: 'rg_identification', name: 'Risk Identification', desc: 'Systematic identification and assessment of business risks' },
      { id: 'rg_mitigation', name: 'Risk Mitigation', desc: 'Controls and contingency plans proportionate to risks' },
      { id: 'rg_governance', name: 'Governance Structure', desc: 'Clear roles, responsibilities and reporting lines; board and leadership oversight' },
      { id: 'rg_ethics', name: 'Ethics & Integrity', desc: 'Code of conduct, whistleblowing procedures, ethical business practices' }
    ]
  },
  {
    id: 'customer', name: 'Customer & Stakeholder Management',
    indicators: [
      { id: 'cs_satisfaction', name: 'Customer Satisfaction', desc: 'Systems to gather, analyse and act on customer feedback' },
      { id: 'cs_relationships', name: 'Stakeholder Relationships', desc: 'Strong relationships with key partners, suppliers, investors' },
      { id: 'cs_communication', name: 'Communication', desc: 'Clear, consistent messaging to internal and external stakeholders' },
      { id: 'cs_value', name: 'Value Delivery', desc: 'Products and services consistently meet or exceed customer expectations' }
    ]
  },
  {
    id: 'technology', name: 'Technology & Innovation',
    indicators: [
      { id: 'ti_systems', name: 'Technology Systems', desc: 'Fit-for-purpose systems that support business operations effectively' },
      { id: 'ti_data', name: 'Data Management', desc: 'Data accurate, secure, accessible and used to drive decisions' },
      { id: 'ti_innovation', name: 'Innovation & Improvement', desc: 'Culture of continuous improvement with idea generation and testing' },
      { id: 'ti_digital', name: 'Digital Maturity', desc: 'Appropriate use of digital tools and automation to enhance efficiency' }
    ]
  }
];

// ---------------------------------------------------------------
// Compliance section definitions
// ---------------------------------------------------------------
const BROOK_COMPLIANCE = [
  {
    id: 'legal', name: 'Legal & Regulatory',
    items: [
      { id: 'lr_registration', name: 'Business registration and licences current and displayed where required' },
      { id: 'lr_insurance', name: 'Appropriate insurance coverage (liability, professional indemnity, etc.) current' },
      { id: 'lr_contracts', name: 'Customer and supplier contracts documented with clear terms' },
      { id: 'lr_ip', name: 'Intellectual property protected (trademarks, patents, copyrights as applicable)' },
      { id: 'lr_data_protection', name: 'GDPR and data protection compliance (privacy policy, consent, data security)' },
      { id: 'lr_employment', name: 'Employment law compliance (contracts, right to work, health and safety)' }
    ]
  },
  {
    id: 'fc', name: 'Financial Controls',
    items: [
      { id: 'fc_accounts', name: 'Annual accounts filed on time; tax returns submitted' },
      { id: 'fc_reconciliation', name: 'Regular bank reconciliations performed and reviewed' },
      { id: 'fc_authorization', name: 'Spending authorisation limits defined and followed' },
      { id: 'fc_segregation', name: 'Segregation of duties in financial processes' },
      { id: 'fc_audit_trail', name: 'Complete audit trail for all transactions' }
    ]
  },
  {
    id: 'rd', name: 'Records & Documentation',
    items: [
      { id: 'rd_policies', name: 'Core policies documented (HR, H&S, data protection, complaints, etc.)' },
      { id: 'rd_records', name: 'Business records retained per legal requirements (7 years financial, etc.)' },
      { id: 'rd_meetings', name: 'Leadership meetings documented with decisions recorded' },
      { id: 'rd_contracts_filed', name: 'Contracts and agreements filed and accessible' }
    ]
  },
  {
    id: 'hs', name: 'Health, Safety & Premises',
    items: [
      { id: 'hs_risk_assessment', name: 'Workplace risk assessments completed and reviewed' },
      { id: 'hs_training', name: 'H&S training provided to all staff; records maintained' },
      { id: 'hs_accidents', name: 'Accident and incident reporting system in place; RIDDOR compliance' },
      { id: 'hs_fire', name: 'Fire risk assessment, equipment serviced, drills logged' },
      { id: 'hs_first_aid', name: 'Adequate first aid provision and trained first aiders' }
    ]
  },
  {
    id: 'is', name: 'Information Security',
    items: [
      { id: 'is_backup', name: 'Regular data backups with tested restore procedures' },
      { id: 'is_access', name: 'Access controls and password policies enforced' },
      { id: 'is_cyber', name: 'Cybersecurity measures (firewall, antivirus, encryption) appropriate' },
      { id: 'is_breach', name: 'Data breach response plan documented' }
    ]
  }
];

// ---------------------------------------------------------------
// Prompt builders
// ---------------------------------------------------------------

function _sourceBlock(summary, transcript) {
  return `\n==========\nMEETING SUMMARY:\n${(summary || '').trim() || '(no summary provided)'}\n\nMEETING TRANSCRIPT / DOCUMENT:\n${(transcript || '').trim() || '(no full transcript provided)'}\n==========\n`;
}

function _areaCriteriaBlock(area) {
  const lines = area.indicators.map(i => `    - id="${i.id}" — ${i.name}: ${i.desc}`).join('\n');
  return `AREA: ${area.name}\n  (grade scale: ${BROOK_GRADE_SCALE})\n${lines}`;
}

function buildAreaPrompt(areaId, summary, transcript) {
  const area = BROOK_AREAS.find(a => a.id === areaId);
  if (!area) throw new Error('Unknown area: ' + areaId);

  const schema = `{
  "indicators": [
    { "id": "<indicator id>", "evidence": ["<specific quote or fact>"], "confidence": "high|med|low" }
  ],
  "judgement": "<2-4 sentence narrative assessment>",
  "suggestedGrade": ${BROOK_GRADE_SCALE.split(' | ').map(s => s).join(' | ')},
  "gradeReasoning": "<one sentence explaining the grade>"
}`;

  return `${BROOK_PREAMBLE}

You are assessing ONE evaluation area:

${_areaCriteriaBlock(area)}
${_sourceBlock(summary, transcript)}

Return a SINGLE JSON object in EXACTLY this schema. Do not wrap in markdown. Do not add commentary before or after.

${schema}`;
}

function buildComplianceItemsBlock() {
  return BROOK_COMPLIANCE.map(sec => {
    const lines = sec.items.map(i => `    - id="${i.id}" — ${i.name}`).join('\n');
    return `  Section: ${sec.name}\n${lines}`;
  }).join('\n\n');
}

function buildCompliancePrompt(summary, transcript) {
  const schema = `{
  "findings": [
    { "id": "<compliance item id>", "status": "compliant|partial|non_compliant|na", "note": "<short evidence note from document>" }
  ]
}`;

  return `${BROOK_PREAMBLE}

You are assessing BUSINESS COMPLIANCE & BEST PRACTICE findings against the items below. Skip any item that has NO supporting evidence — return only items where the source mentions or strongly implies compliance status.

${buildComplianceItemsBlock()}
${_sourceBlock(summary, transcript)}

Return a SINGLE JSON object in EXACTLY this schema. Do not wrap in markdown.

${schema}`;
}

function buildFindingsPrompt(summary, transcript) {
  const schema = `{
  "executive_summary": {
    "overall_assessment": "<2-3 sentence high-level summary>",
    "key_risks": ["<top 3-5 risks identified>"],
    "immediate_priorities": ["<top 3-5 actions needed urgently>"]
  },
  "strengths": ["<3-6 specific strengths with evidence>"],
  "afd": ["<3-6 specific areas for development>"],
  "actions": [
    { "action": "<specific, actionable task>", "owner": "<role e.g. CEO / Finance Director>", "priority": "Critical|High|Medium|Low", "timeline": "<suggested completion timeframe>" }
  ]
}`;

  return `${BROOK_PREAMBLE}

You are drafting headline findings for this consultation:
  - Executive summary (overall assessment, key risks, immediate priorities)
  - Strengths
  - Areas for development (AFD)
  - Action plan

${_sourceBlock(summary, transcript)}

Return a SINGLE JSON object in EXACTLY this schema. Do not wrap in markdown.

${schema}`;
}

function buildAutofillPrompt(summary, transcript) {
  // Maps directly to the Brook consultation form fields.
  return `${BROOK_PREAMBLE}

You are extracting structured information from the consultation source to pre-populate the Brook Consultancy intake form.

Only fill fields where there is supporting evidence. Use empty strings or empty arrays if not stated.
${_sourceBlock(summary, transcript)}

Return a SINGLE JSON object in EXACTLY this schema. Do not wrap in markdown. Do not add commentary.

{
  "organisation_overview": "<narrative paragraph>",
  "client_request": "<what the client is asking for>",
  "support_type": ["Hands-on delivery|Strategic advisory|Capacity building|Interim management|One-off project|Ongoing retainer|Review and recommendations only|Training and development|Client is unsure|Mixed"],
  "stated_priorities": "<client priorities in their words>",
  "core_challenges": "<narrative summary of challenges>",
  "challenge_tags": ["Financial distress|Cash flow problems|Governance weakness|Leadership gap|Compliance failure|Regulatory risk|CQC risk|Staff retention|Rapid growth pains|Systems failure|Cultural issues|Strategic drift|Safeguarding concern|Contract loss risk|Stakeholder relationship issues|Other"],
  "urgency": "Critical|High|Moderate|Low",
  "trigger": "<what prompted them to seek support>",
  "previous_attempts": "<what has been tried before>",
  "regulatory_status": "<regulatory body and current standing>",
  "safeguarding_status": "<safeguarding arrangements summary>",
  "policy_status": "<documentation and policy state>",
  "finance_systems": ["Xero|QuickBooks|Sage|IRIS|FreeAgent|Excel only|No formal system|Other"],
  "hr_systems": ["BambooHR|Breathe HR|MHR iTrent|Spreadsheets only|No formal system|Other"],
  "operational_systems": "<narrative>",
  "data_maturity": "Strong|Moderate|Weak|Very limited",
  "financial_overview": "<narrative financial summary>",
  "budget_range": "Under £100k|£100k–£250k|£250k–£500k|£500k–£1M|£1M–£3M|£3M–£5M|Over £5M|Prefer not to say",
  "financial_position": "Healthy surplus|Breaking even|Small deficit|Significant deficit|Unknown — lack of visibility",
  "income_sources": ["Local Authority contract|NHS contract|Private client fees|Grant funding|Donations|Trading income|Investment|Property income|Other"],
  "cost_pressures": "<narrative>",
  "workforce_summary": "<people and culture narrative>",
  "short_term_priorities": "<6-12 month goals>",
  "long_term_vision": "<3-5 year ambition>",
  "partnership_expectations": "<what they want from Brook>",
  "budget_for_support": "Under £5k|£5k–£10k|£10k–£25k|£25k–£50k|£50k+|Not yet confirmed|Subject to proposal",
  "timeline_to_start": "Immediately|Within 1 month|1–3 months|3–6 months|Exploring options only",
  "situation_narrative": {
    "paragraph_1": "<who the organisation is and context>",
    "paragraph_2": "<core challenges and how they developed>",
    "paragraph_3": "<what the client is asking for>",
    "paragraph_4": "<professional assessment of real need>"
  },
  "key_quotes": [
    { "quote": "<verbatim or near-verbatim quote>", "context": "<what prompted this>", "tag": "Leadership|Finance|Compliance|People|Systems|Culture|Goals|Risk|Other" }
  ],
  "baseline_metrics": {
    "annual_budget": "<value if mentioned>",
    "financial_position_detail": "<surplus/deficit detail>",
    "staff_count": "<number if mentioned>",
    "service_users": "<number if mentioned>",
    "sites": "<number if mentioned>",
    "regulatory_rating": "<rating and date if mentioned>",
    "last_inspection_date": "<date if mentioned>",
    "staff_vacancy_detail": "<detail if mentioned>",
    "staff_turnover": "<detail if mentioned>",
    "other_metrics": "<any other figures mentioned>"
  },
  "recommended_services": ["Financial Management & CFO Support|Deficit Recovery|Budget Setting & Monitoring|Governance & Board Support|CQC Compliance & Registration|HR Strategy & Investigations|Safer Recruitment Audit|Operations & Process Improvement|Systems & Technology Integration|Strategic Growth & Business Development|New Business or Setting Launch|Turnaround & Rescue Support|Safeguarding Review & Training|Staff Training & Development|Partnership Brokering|Interim Management"],
  "proposed_workstreams": [
    { "title": "<workstream title>", "description": "<what this involves>", "timeframe": "1–4 weeks|1–3 months|3–6 months|6–12 months|Ongoing", "priority": "Immediate|Phase 2|Phase 3" }
  ],
  "overall_impression": "<consultant-facing assessment>",
  "key_risks": ["<risks to the organisation>"],
  "brook_risk_level": "Low|Medium|High|Do Not Engage",
  "lead_priority": "Hot|Warm|Cool|Long-term|Not suitable",
  "recommended_next_steps": "<immediate next steps>",
  "success_definition": "<what success looks like>"
}`;
}

function buildMasterPrompt(summary, transcript) {
  // One mega-prompt that returns EVERYTHING in one JSON. Useful for capable AIs (Claude, ChatGPT-4).
  const allAreas = BROOK_AREAS.map(_areaCriteriaBlock).join('\n\n');

  const schema = `{
  "areas": {
    "leadership": { "indicators": [{"id","evidence":[],"confidence":"high|med|low"}], "judgement": "...", "suggestedGrade": "...", "gradeReasoning": "..." },
    "operations": { ... same shape ... },
    "financial":  { ... same shape ... },
    "people":     { ... same shape ... },
    "risk":       { ... same shape ... },
    "customer":   { ... same shape ... },
    "technology": { ... same shape ... }
  },
  "compliance": {
    "findings": [
      { "id": "<compliance item id>", "status": "compliant|partial|non_compliant|na", "note": "<short evidence note>" }
    ]
  },
  "findings": {
    "strengths": ["<3-6 specific strengths>"],
    "afd": ["<3-6 development areas>"],
    "actions": [
      { "action": "...", "owner": "...", "priority": "Critical|High|Medium|Low", "timeline": "..." }
    ]
  },
  "executive_summary": {
    "overall_assessment": "<2-3 sentence summary>",
    "key_risks": ["..."],
    "immediate_priorities": ["..."]
  },
  "consultation_autofill": { /* the full autofill schema — see Autofill prompt for shape */ }
}`;

  return `${BROOK_PREAMBLE}

You will produce findings for ALL evaluation areas, compliance findings, headline findings, and the consultation autofill — in a SINGLE JSON object.

EVALUATION AREAS (each has indicators):

${allAreas}

BUSINESS COMPLIANCE & BEST PRACTICE items:

${buildComplianceItemsBlock()}

Use these area IDs in the "areas" object: "leadership", "operations", "financial", "people", "risk", "customer", "technology"
${_sourceBlock(summary, transcript)}

Return a SINGLE JSON object in EXACTLY this schema. Do not wrap in markdown. Do not add commentary before or after.

${schema}

For the "consultation_autofill" key, use the Brook autofill schema (organisation_overview, client_request, support_type, stated_priorities, core_challenges, challenge_tags, urgency, trigger, previous_attempts, regulatory_status, safeguarding_status, policy_status, finance_systems, hr_systems, operational_systems, data_maturity, financial_overview, budget_range, financial_position, income_sources, cost_pressures, workforce_summary, short_term_priorities, long_term_vision, partnership_expectations, budget_for_support, timeline_to_start, situation_narrative {paragraph_1..4}, key_quotes [{quote,context,tag}], baseline_metrics {annual_budget, financial_position_detail, staff_count, service_users, sites, regulatory_rating, last_inspection_date, staff_vacancy_detail, staff_turnover, other_metrics}, recommended_services, proposed_workstreams [{title,description,timeframe,priority}], overall_impression, key_risks, brook_risk_level, lead_priority, recommended_next_steps, success_definition).`;
}

// ---------------------------------------------------------------
// JSON extraction — robust to markdown fences, prose around it, etc.
// ---------------------------------------------------------------
function extractJson(text) {
  if (!text || typeof text !== 'string') throw new Error('No content provided.');
  let s = text.trim();

  // 1. Strip markdown code fences ```json ... ``` or ``` ... ```
  const fenceMatch = s.match(/```(?:json|JSON)?\s*\n?([\s\S]*?)\n?```/);
  if (fenceMatch) s = fenceMatch[1].trim();

  // 2. Try direct parse
  try { return JSON.parse(s); } catch {}

  // 3. Find the first { and try parsing balanced JSON to the matching close
  const start = s.indexOf('{');
  if (start === -1) throw new Error('No JSON object found in the response.');

  let depth = 0;
  let inString = false;
  let escape = false;
  for (let i = start; i < s.length; i++) {
    const ch = s[i];
    if (escape) { escape = false; continue; }
    if (ch === '\\') { escape = true; continue; }
    if (ch === '"') { inString = !inString; continue; }
    if (inString) continue;
    if (ch === '{') depth++;
    else if (ch === '}') {
      depth--;
      if (depth === 0) {
        const candidate = s.slice(start, i + 1);
        try { return JSON.parse(candidate); }
        catch (e) { throw new Error('Found a JSON-looking block but could not parse it: ' + e.message); }
      }
    }
  }
  throw new Error('JSON object did not close — response may be truncated.');
}

// ---------------------------------------------------------------
// Apply parsed JSON back into store
// ---------------------------------------------------------------
function applyAreaResponse(store, areaId, parsed) {
  if (!parsed || typeof parsed !== 'object') throw new Error('Empty response.');
  const ranAt = new Date().toISOString();
  const incoming = {
    indicators: Array.isArray(parsed.indicators) ? parsed.indicators : [],
    judgement: parsed.judgement || '',
    suggestedGrade: parsed.suggestedGrade || 'insufficient_evidence',
    gradeReasoning: parsed.gradeReasoning || '',
    ranAt,
    applied: true
  };
  store.setData(d => ({
    ...d,
    aiResults: { ...(d.aiResults || {}), [areaId]: incoming },
    _autofill_used: true
  }));
}

function applyComplianceResponse(store, parsed) {
  const findings = Array.isArray(parsed?.findings) ? parsed.findings : [];
  const ranAt = new Date().toISOString();
  store.setData(d => ({
    ...d,
    aiResults: {
      ...(d.aiResults || {}),
      statutory: { findings, ranAt, applied: true }
    },
    _autofill_used: true
  }));
}

function applyFindingsResponse(store, parsed) {
  const ranAt = new Date().toISOString();
  store.setData(d => ({
    ...d,
    aiResults: {
      ...(d.aiResults || {}),
      executive_summary: parsed.executive_summary || (d.aiResults?.executive_summary) || { overall_assessment: '', key_risks: [], immediate_priorities: [] },
      findings: {
        strengths: Array.isArray(parsed.strengths) ? parsed.strengths : [],
        afd: Array.isArray(parsed.afd) ? parsed.afd : (Array.isArray(parsed.areas_for_development) ? parsed.areas_for_development : []),
        actions: Array.isArray(parsed.actions) ? parsed.actions : [],
        ranAt, applied: true
      }
    },
    _autofill_used: true
  }));
}

function applyAutofillResponse(store, parsed) {
  // Same field-mapping as the legacy mapAutofillToFields, but applied directly
  const a = parsed || {};
  const baseline = a.baseline_metrics || {};
  const narrative = a.situation_narrative || {};
  const ranAt = new Date().toISOString();

  const fields = {};
  const set = (id, value, conf = 'med') => {
    if (value === undefined || value === null) return;
    if (typeof value === 'string' && !value.trim()) return;
    if (Array.isArray(value) && value.length === 0) return;
    fields[id] = { value, confidence: conf };
  };

  set('history_notes', a.organisation_overview, 'high');
  set('client_request', a.client_request, 'high');
  set('support_type', a.support_type, 'med');
  set('stated_priorities', a.stated_priorities, 'high');
  set('trigger_notes', a.trigger, 'high');
  set('core_challenges', a.core_challenges, 'high');
  set('challenge_tags', a.challenge_tags, 'med');
  set('urgency', a.urgency, 'med');
  set('previous_attempts', a.previous_attempts, 'med');
  set('regulatory_notes', a.regulatory_status, 'high');
  set('safeguarding_notes', a.safeguarding_status, 'med');
  set('policy_notes', a.policy_status, 'med');

  const regStatusMap = ['Outstanding','Good','Requires Improvement','Inadequate','Monitoring','Under Enforcement','Not yet inspected','Not applicable'];
  if (typeof a.regulatory_status === 'string') {
    const found = regStatusMap.find(s => a.regulatory_status.toLowerCase().includes(s.toLowerCase()));
    if (found) set('regulatory_status', found, 'med');
  }

  set('finance_systems', a.finance_systems, 'med');
  set('hr_systems', a.hr_systems, 'med');
  set('operational_systems', a.operational_systems, 'med');
  if (a.data_maturity) {
    const dm = a.data_maturity.toLowerCase();
    if (dm.startsWith('strong')) set('data_maturity', 'Strong — regular dashboards and data-driven decisions');
    else if (dm.startsWith('moderate')) set('data_maturity', 'Moderate — some reporting but inconsistent');
    else if (dm.startsWith('weak')) set('data_maturity', 'Weak — largely informal and reactive');
    else if (dm.startsWith('very')) set('data_maturity', 'Very limited — little to no data visibility');
  }

  set('financial_overview', a.financial_overview, 'high');
  set('budget_range', a.budget_range, 'med');
  set('financial_position', a.financial_position, 'med');
  set('income_sources', a.income_sources, 'med');
  set('cost_pressures', a.cost_pressures, 'med');
  if (a.workforce_summary) set('workforce_notes', a.workforce_summary, 'med');

  set('short_term_priorities', a.short_term_priorities, 'high');
  set('long_term_vision', a.long_term_vision, 'high');
  set('partnership_expectations', a.partnership_expectations, 'high');
  set('budget_for_support', a.budget_for_support, 'med');
  set('timeline_to_start', a.timeline_to_start, 'med');

  set('overall_impression', a.overall_impression, 'med');
  set('brook_risk_level', a.brook_risk_level, 'med');
  set('recommended_services', a.recommended_services, 'med');
  set('lead_priority', a.lead_priority, 'med');
  set('recommended_next_steps', a.recommended_next_steps, 'med');
  if (Array.isArray(a.key_risks) && a.key_risks.length) set('key_risks', a.key_risks.map(r => '• ' + r).join('\n'), 'high');

  set('annual_budget', baseline.annual_budget, 'high');
  set('financial_position_detail', baseline.financial_position_detail, 'high');
  set('staff_count_detail', baseline.staff_count, 'high');
  set('service_users_detail', baseline.service_users, 'high');
  set('staff_vacancy_detail', baseline.staff_vacancy_detail, 'med');
  set('staff_turnover', baseline.staff_turnover, 'med');
  set('regulatory_rating', baseline.regulatory_rating, 'high');
  set('last_inspection_date', baseline.last_inspection_date, 'high');
  set('other_metrics', baseline.other_metrics, 'med');
  if (baseline.staff_count) set('staff_count', baseline.staff_count, 'high');
  if (baseline.service_users) set('service_users', baseline.service_users, 'high');
  if (baseline.sites) set('sites', baseline.sites, 'high');

  set('narrative_p1', narrative.paragraph_1, 'high');
  set('narrative_p2', narrative.paragraph_2, 'high');
  set('narrative_p3', narrative.paragraph_3, 'high');
  set('narrative_p4', narrative.paragraph_4, 'med');
  set('success_definition', a.success_definition, 'med');

  // Repeaters
  const repeaters = {};
  if (Array.isArray(a.key_quotes) && a.key_quotes.length) {
    repeaters.quotes = a.key_quotes.map(q => ({
      id: window.brookUid(),
      quote: q.quote || '',
      context: q.context || '',
      tag: q.tag || ''
    }));
  }
  if (Array.isArray(a.proposed_workstreams) && a.proposed_workstreams.length) {
    repeaters.workstreams = a.proposed_workstreams.map(w => ({
      id: window.brookUid(),
      title: w.title || '',
      description: w.description || '',
      timeframe: w.timeframe || '',
      priority: w.priority || ''
    }));
  }

  store.setData(d => {
    const newFields = { ...d.fields };
    const newMeta = { ...d._autofill_meta };
    Object.entries(fields).forEach(([k, v]) => {
      newFields[k] = v.value;
      newMeta[k] = { confidence: v.confidence, accepted: false, ranAt };
    });
    return {
      ...d,
      fields: newFields,
      _autofill_meta: newMeta,
      _autofill_used: true,
      repeaters: { ...d.repeaters, ...repeaters },
      aiResults: { ...(d.aiResults || {}), autofill: { ranAt, applied: true } }
    };
  });
}

function applyMasterResponse(store, parsed) {
  // Master: areas + compliance + findings + executive_summary + consultation_autofill
  const ranAt = new Date().toISOString();

  // Apply each area
  Object.entries(parsed.areas || {}).forEach(([areaId, payload]) => {
    applyAreaResponse(store, areaId, payload);
  });

  // Compliance
  if (parsed.compliance) applyComplianceResponse(store, parsed.compliance);

  // Findings + executive summary
  if (parsed.findings || parsed.executive_summary) {
    applyFindingsResponse(store, {
      strengths: parsed.findings?.strengths,
      afd: parsed.findings?.afd || parsed.findings?.areas_for_development,
      actions: parsed.findings?.actions,
      executive_summary: parsed.executive_summary
    });
  }

  // Autofill
  if (parsed.consultation_autofill) {
    applyAutofillResponse(store, parsed.consultation_autofill);
  }
}

// ---------------------------------------------------------------
// Public registry of all prompts
// ---------------------------------------------------------------
function getBrookPromptDefs() {
  // Each def: { key, label, build(summary, transcript), apply(store, parsed) }
  const defs = [];

  // Per-area prompts
  BROOK_AREAS.forEach(a => {
    defs.push({
      key: 'area:' + a.id,
      kind: 'area',
      areaId: a.id,
      label: a.name,
      build: (s, t) => buildAreaPrompt(a.id, s, t),
      apply: (store, parsed) => applyAreaResponse(store, a.id, parsed),
      stateKey: ['aiResults', a.id]
    });
  });

  defs.push({
    key: 'compliance',
    kind: 'compliance',
    label: 'Compliance & Best Practice',
    build: buildCompliancePrompt,
    apply: applyComplianceResponse,
    stateKey: ['aiResults', 'statutory']
  });

  defs.push({
    key: 'findings',
    kind: 'findings',
    label: 'Strengths · AFD · Action plan',
    build: buildFindingsPrompt,
    apply: applyFindingsResponse,
    stateKey: ['aiResults', 'findings']
  });

  defs.push({
    key: 'autofill',
    kind: 'autofill',
    label: 'Consultation form autofill',
    build: buildAutofillPrompt,
    apply: applyAutofillResponse,
    stateKey: ['aiResults', 'autofill']
  });

  defs.push({
    key: 'master',
    kind: 'master',
    label: 'Master prompt — all sections',
    build: buildMasterPrompt,
    apply: applyMasterResponse,
    stateKey: null // master applies to many keys
  });

  return defs;
}

function isPromptApplied(store, def) {
  if (!def.stateKey) return false;
  const ai = store.data.aiResults || {};
  if (def.kind === 'area') return !!(ai[def.areaId] && ai[def.areaId].applied);
  if (def.kind === 'compliance') return !!(ai.statutory && ai.statutory.applied);
  if (def.kind === 'findings') return !!(ai.findings && ai.findings.applied);
  if (def.kind === 'autofill') return !!(ai.autofill && ai.autofill.applied);
  return false;
}

function getPromptRanAt(store, def) {
  const ai = store.data.aiResults || {};
  if (def.kind === 'area') return ai[def.areaId]?.ranAt;
  if (def.kind === 'compliance') return ai.statutory?.ranAt;
  if (def.kind === 'findings') return ai.findings?.ranAt;
  if (def.kind === 'autofill') return ai.autofill?.ranAt;
  return null;
}

Object.assign(window, {
  BROOK_AREAS,
  BROOK_COMPLIANCE,
  buildAreaPrompt,
  buildCompliancePrompt,
  buildFindingsPrompt,
  buildAutofillPrompt,
  buildMasterPrompt,
  extractJson,
  applyAreaResponse,
  applyComplianceResponse,
  applyFindingsResponse,
  applyAutofillResponse,
  applyMasterResponse,
  getBrookPromptDefs,
  isPromptApplied,
  getPromptRanAt
});
