// petal-store.jsx — palette, fonts, people, and Posy's "brain" (prompt + parsing).
// Storage & AI transport now live in petal-api.jsx so the same logic works in
// both demo mode and live (Supabase) mode.

const CFG = window.PETAL_CONFIG || {};
const PEOPLE = { patient: CFG.PATIENT_NAME || 'Maryna', doctor: CFG.DOCTOR_NAME || 'Nuno' };

const PAL = {
  bg: '#FBF4EF', card: '#FFFFFF', ink: '#433834', ink2: '#6E625A', mut: '#94837C',
  blush: '#D98C8C', blushSoft: '#FBEDED', blushSofter: '#FDF4F2', deep: '#BE6E6D',
  border: '#EFE3DB', borderSoft: '#F3EAE3', green: '#86B894', amber: '#D9A86B',
  shadow: '0 10px 30px rgba(190,110,109,0.10)',
  shadowSoft: '0 6px 18px rgba(190,110,109,0.08)',
};
const FONT = "'Hanken Grotesk', system-ui, -apple-system, sans-serif";
const SERIF = "'Newsreader', Georgia, serif";

function uid() { return Date.now().toString(36) + Math.random().toString(36).slice(2, 6); }

// ── client-side draft (resume an in-progress check-in after refresh) ──
const DKEY = 'petal.draft.v1';
function loadDraft() { try { return JSON.parse(localStorage.getItem(DKEY)); } catch (e) { return null; } }
function saveDraft(d) { localStorage.setItem(DKEY, JSON.stringify(d)); }
function clearDraft() { localStorage.removeItem(DKEY); }

// ── seed content for DEMO mode's doctor desk ──
function DEMO_SEED() {
  const now = Date.now(), day = 86400000;
  return [
    {
      id: uid(), startedAt: now - day * 2 + 3600000, status: 'reviewed',
      concern: "I've had a sore throat and a bit of a fever since yesterday. Swallowing hurts.",
      severity: 6,
      qa: [
        { label: 'How long have you felt this way?', answer: 'About 1 day' },
        { label: 'How bad is the throat pain (1–10)?', answer: '6 / 10' },
        { label: 'Any of these too?', answer: 'Headache, Tiredness' },
        { label: 'Highest temperature you measured?', answer: '38.1°C' },
        { label: 'Anything making it better or worse?', answer: 'Warm tea helps a little; swallowing solid food is worst.' },
      ],
      summary: "1-day history of odynophagia with subjective fever (38.1°C), associated headache and fatigue. Pain 6/10, partially eased by warm fluids. No mention of rash or breathing difficulty. Consider viral pharyngitis; review for strep features.",
      doctorNote: 'Looks viral. Asked her to rest & hydrate, recheck temp tonight.',
    },
    {
      id: uid(), startedAt: now - day * 9 + 7200000, status: 'reviewed',
      concern: 'Cramps low in my belly and feeling really tired the last few days.',
      severity: 5,
      qa: [
        { label: 'Where is the discomfort?', answer: 'Lower abdomen, both sides' },
        { label: 'How strong are the cramps (1–10)?', answer: '5 / 10' },
        { label: 'How long has this been going on?', answer: 'A few days' },
        { label: 'Any pattern you have noticed?', answer: 'Worse in the evening, comes in waves.' },
      ],
      summary: "Several days of bilateral lower-abdominal crampy pain, 5/10, worse in the evenings and intermittent. Associated fatigue. No fever reported. Likely benign; correlate with cycle timing.",
      doctorNote: '',
    },
  ];
}

// ── Posy's instructions ──
const POSY_RULES = `You are Posy — a warm, caring health check-in companion, like a gentle, attentive nurse.
You are helping ${PEOPLE.patient} describe how she is feeling so her doctor, ${PEOPLE.doctor}, can review it later.
Voice: warm, soft, brief, reassuring. Never diagnose, never give medical advice, never alarm her. Use her name occasionally. At most one gentle emoji, and only sometimes.

Your task each turn: read the conversation and ask a SMALL set of 1–3 focused follow-up questions that build a useful clinical picture (onset, duration, location, severity, character, triggers, what helps, associated symptoms, relevant context). Prefer tappable question types over typing.
You may also be given her saved HEALTH BACKGROUND and her RECENT PAST CHECK-INS. Use them to tailor your questions and to avoid re-asking what you already know. Reference her history naturally when relevant (e.g. "last week you mentioned something similar— is this the same?"). If a symptom recurs or relates to her background, mention that in the doctor summary.
Stop once you have enough for the doctor — usually after 2–4 short rounds. When you stop, set "done": true and write a concise clinical summary for the doctor.

Reply with ONLY a raw JSON object (no markdown, no backticks, no prose outside it):
{
  "reply": "a short warm message to her, 1–2 sentences",
  "done": false,
  "questions": [
    { "id": "snake_case_id", "type": "choice" | "multi" | "scale" | "text",
      "label": "the question text",
      "options": ["only for choice/multi"],
      "min": 1, "max": 10, "minLabel": "Mild", "maxLabel": "Severe",
      "placeholder": "only for text" }
  ],
  "summary": "clinical summary, only when done is true — otherwise omit"
}
Rules: "questions" must be [] when done is true. Keep options to 2–5 short items. Use "scale" for intensity/severity. Use "text" sparingly for open detail. Always include at least one question when not done.`;

function buildTranscript(messages) {
  const lines = [];
  for (const m of messages) {
    if (m.from === 'maryna' && m.kind === 'text') lines.push(`${PEOPLE.patient}: ${m.text}`);
    else if (m.from === 'maryna' && m.kind === 'answers') lines.push(`${PEOPLE.patient} answered — ${m.text}`);
    else if (m.from === 'posy' && m.kind === 'text') lines.push(`Posy: ${m.text}`);
    else if (m.from === 'posy' && m.kind === 'questions') lines.push(`Posy asked: ${m.questions.map(q => q.label).join(' | ')}`);
  }
  return lines.join('\n');
}

function summarizeHealth(h) {
  if (!h) return '';
  const top = [];
  if (h.age) top.push(`age ${h.age}`);
  if (h.sex) top.push(String(h.sex).toLowerCase());
  if (h.heightCm) top.push(`${h.heightCm} cm`);
  if (h.weightKg) top.push(`${h.weightKg} kg`);
  const lines = [];
  if (top.length) lines.push(top.join(', '));
  const arr = (v) => Array.isArray(v) ? v : (v ? String(v).split(',').map(s => s.trim()).filter(Boolean) : []);
  if (arr(h.conditions).length) lines.push('Known conditions: ' + arr(h.conditions).join(', '));
  if (arr(h.allergies).length) lines.push('Allergies: ' + arr(h.allergies).join(', '));
  if (arr(h.medications).length) lines.push('Current medications: ' + arr(h.medications).join(', '));
  if (h.notes) lines.push('Notes: ' + h.notes);
  return lines.join('\n');
}

function summarizePast(list) {
  if (!list || !list.length) return '';
  return list.slice(0, 5).map(s => {
    const d = new Date(s.startedAt).toLocaleDateString('en-GB', { day: 'numeric', month: 'short' });
    const sev = s.severity != null ? `, severity ${s.severity}/10` : '';
    return `• ${d}: "${s.concern}"${sev}.${s.summary ? ' ' + s.summary : ''}`;
  }).join('\n');
}

function buildPosyPrompt(messages, rounds, ctx) {
  ctx = ctx || {};
  const nudge = rounds >= 3
    ? '\n\nYou have asked several rounds already. Unless something important is missing, set "done": true now and write the summary.'
    : '';
  const bg = summarizeHealth(ctx.health);
  const past = summarizePast(ctx.past);
  const parts = [POSY_RULES];
  if (bg) parts.push(`HER SAVED HEALTH BACKGROUND:\n${bg}`);
  if (past) parts.push(`HER RECENT PAST CHECK-INS (most recent first):\n${past}`);
  parts.push(`CURRENT CONVERSATION:\n${buildTranscript(messages)}${nudge}`);
  parts.push('Return the next JSON object now.');
  return parts.join('\n\n');
}

function parseLoose(text) {
  if (!text) return null;
  let t = String(text).trim();
  t = t.replace(/^```json/i, '').replace(/^```/, '').replace(/```$/, '').trim();
  const s = t.indexOf('{'), e = t.lastIndexOf('}');
  if (s >= 0 && e > s) t = t.slice(s, e + 1);
  try { return JSON.parse(t); } catch (err) { return null; }
}

function normalizePosy(parsed, rounds) {
  if (!parsed || (!parsed.done && !(parsed.questions && parsed.questions.length))) return fallbackTurn(rounds);
  parsed.done = !!parsed.done;
  parsed.questions = Array.isArray(parsed.questions) ? parsed.questions : [];
  parsed.questions.forEach((q, i) => {
    q.id = q.id || ('q' + rounds + '_' + i);
    if (!q.type) q.type = q.options ? 'choice' : 'text';
  });
  return parsed;
}

function fallbackTurn(rounds) {
  if (rounds === 0) {
    return {
      reply: `Thank you for telling me, ${PEOPLE.patient}. Let's get a few details so ${PEOPLE.doctor} has the full picture.`,
      done: false,
      questions: [
        { id: 'onset', type: 'choice', label: 'How long have you been feeling this way?', options: ['Just started', 'Since this morning', 'A few days', 'Over a week'] },
        { id: 'severity', type: 'scale', label: 'How strong is it right now?', min: 1, max: 10, minLabel: 'Mild', maxLabel: 'Severe' },
        { id: 'pattern', type: 'text', label: 'Is there anything that makes it better or worse?', placeholder: 'A little detail helps…' },
      ],
    };
  }
  if (rounds === 1) {
    return {
      reply: 'That helps a lot. Just a couple more, then we are done.',
      done: false,
      questions: [
        { id: 'assoc', type: 'multi', label: 'Are you noticing any of these too?', options: ['Fever', 'Headache', 'Nausea', 'Tiredness', 'Dizziness', 'None of these'] },
        { id: 'note', type: 'text', label: `Anything else you want ${PEOPLE.doctor} to know?`, placeholder: 'Optional…' },
      ],
    };
  }
  return {
    reply: `All done — thank you for being so thorough. I've passed everything to ${PEOPLE.doctor} to look over. Rest up, okay? 💛`,
    done: true,
    questions: [],
    summary: 'Symptom check-in completed via guided questionnaire. See structured answers below for onset, severity, associated symptoms and patient notes.',
  };
}

// demo health profile so tailoring is visible without setup
function DEMO_HEALTH() {
  return {
    age: 29, sex: 'Female', heightCm: 167, weightKg: 60,
    conditions: ['Migraines'], allergies: ['Lactose'], medications: [],
    notes: 'Migraines usually begin with a visual aura. Generally fit and active; exercises 3×/week.',
  };
}

Object.assign(window, {
  PAL, FONT, SERIF, PEOPLE, CFG, uid,
  loadDraft, saveDraft, clearDraft, DEMO_SEED, DEMO_HEALTH,
  buildTranscript, buildPosyPrompt, parseLoose, normalizePosy, fallbackTurn,
  summarizeHealth, summarizePast,
});
