const { useState, useEffect, useMemo, useRef } = React;

// ---------- Brand ----------
const BG = '#FBF4EC';
const BG_FOOTER = '#F1EAE1';
const INK = '#1F2330';
const INK_SOFT = '#6B6A66';
const INK_MUTED = '#9B9892';
const GOLD = '#E9B949';
const GOLD_DEEP = '#D9A82E';
const GOLD_SOFT = '#FCE9B4';
const CARD = '#FFFFFF';
const CARD_BORDER = '#EDE4D5';
const SELECTED_BG = '#FFFBF0';
const SELECTED_RING = '#F0C659';

// ---------- Logo ----------
function Logo({ withText = true, size = 28 }) {
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 10 }}>
      <img src="imgs/mark-dark-yellow.svg" height={size} width={Math.round(size * 1.56)} alt="" aria-hidden="true" style={{ display: 'block' }} />
      {withText && (
        <img src="imgs/finalwordmark.svg" height={size} alt="Daylight Health" style={{ display: 'block' }} />
      )}
    </div>
  );
}

// ---------- Top chrome ----------
function Header({ progress, showBack, onBack, stepLabel }) {
  return (
    <div style={{ position: 'relative', paddingTop: 28, paddingBottom: 14 }}>
      {showBack && (
        <button
          onClick={onBack}
          aria-label="Back"
          style={{
            position: 'absolute', left: 40, top: 30,
            width: 36, height: 36, borderRadius: 8, border: 'none',
            background: 'transparent', cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: INK,
          }}
        >
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
            <path d="M15 18l-6-6 6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
      )}
      <div style={{ display: 'flex', justifyContent: 'center' }}>
        <Logo />
      </div>
      {progress !== null && (
        <div style={{
          maxWidth: 720, margin: '18px auto 0', height: 3, background: '#EADFC9',
          borderRadius: 2, overflow: 'hidden',
        }}>
          <div style={{
            height: '100%', width: `${progress * 100}%`, background: GOLD,
            transition: 'width 420ms cubic-bezier(.2,.7,.3,1)',
          }} />
        </div>
      )}
      {stepLabel && (
        <div style={{
          textAlign: 'center', marginTop: 14, fontSize: 11, letterSpacing: 2,
          color: INK_MUTED, textTransform: 'uppercase', fontWeight: 500,
        }}>{stepLabel}</div>
      )}
    </div>
  );
}

// ---------- Debug footer ----------
function DebugFoot({ text }) {
  return (
    <div style={{
      position: 'fixed', left: 0, right: 0, bottom: 0,
      background: BG_FOOTER, padding: '14px 20px', textAlign: 'center',
      fontSize: 12, color: INK_SOFT, borderTop: `1px solid ${CARD_BORDER}`,
      fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
    }}>{text}</div>
  );
}

// ---------- Question scaffold ----------
function QuestionShell({ title, subtitle, children, onContinue, continueEnabled = true, continueText = 'Continue', wide = false }) {
  return (
    <div style={{ maxWidth: wide ? 780 : 640, margin: '0 auto', padding: '24px 24px 120px' }}>
      <h1 style={{
        fontSize: 30, lineHeight: 1.18, fontWeight: 700, color: INK,
        margin: '12px 0 12px', textAlign: 'center', letterSpacing: -0.4,
      }}>{title}</h1>
      {subtitle && (
        <p style={{
          textAlign: 'center', color: INK_SOFT, fontSize: 15, lineHeight: 1.5,
          margin: '0 auto 28px', maxWidth: 520,
        }}>{subtitle}</p>
      )}
      <div>{children}</div>
      {onContinue && (
        <div style={{ display: 'flex', justifyContent: 'center', marginTop: 24 }}>
          <button
            onClick={continueEnabled ? onContinue : undefined}
            disabled={!continueEnabled}
            style={{
              background: continueEnabled ? GOLD : '#EAD9A8',
              color: continueEnabled ? INK : '#8B7A4E',
              border: 'none', borderRadius: 999,
              padding: '14px 44px', fontSize: 15, fontWeight: 500,
              cursor: continueEnabled ? 'pointer' : 'not-allowed',
              boxShadow: continueEnabled ? '0 1px 0 rgba(0,0,0,0.04)' : 'none',
              transition: 'transform 120ms, background 200ms',
              fontFamily: 'inherit',
            }}
            onMouseDown={(e) => continueEnabled && (e.currentTarget.style.transform = 'scale(0.98)')}
            onMouseUp={(e) => (e.currentTarget.style.transform = 'scale(1)')}
            onMouseLeave={(e) => (e.currentTarget.style.transform = 'scale(1)')}
          >{continueText}</button>
        </div>
      )}
    </div>
  );
}

// ---------- Radio list option ----------
function RadioOption({ selected, onClick, children }) {
  return (
    <button
      onClick={onClick}
      style={{
        display: 'flex', alignItems: 'center', gap: 16,
        width: '100%', textAlign: 'left',
        background: selected ? SELECTED_BG : CARD,
        border: `1.5px solid ${selected ? SELECTED_RING : CARD_BORDER}`,
        borderRadius: 14, padding: '18px 20px',
        cursor: 'pointer', marginBottom: 12, color: INK,
        fontSize: 15, lineHeight: 1.4, fontFamily: 'inherit',
        transition: 'background 160ms, border-color 160ms, transform 120ms',
      }}
      onMouseEnter={(e) => !selected && (e.currentTarget.style.background = '#FFFCF6')}
      onMouseLeave={(e) => !selected && (e.currentTarget.style.background = CARD)}
    >
      <span style={{
        flexShrink: 0, width: 20, height: 20, borderRadius: '50%',
        border: `1.5px solid ${selected ? GOLD_DEEP : '#D8CFBD'}`,
        background: selected ? '#fff' : 'transparent',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        {selected && <span style={{ width: 9, height: 9, borderRadius: '50%', background: GOLD_DEEP }} />}
      </span>
      <span style={{ flex: 1 }}>{children}</span>
    </button>
  );
}

function RadioList({ options, value, onChange }) {
  return (
    <div>
      {options.map((o) => (
        <RadioOption key={o.value} selected={value === o.value} onClick={() => onChange(o.value)}>
          {o.label}
        </RadioOption>
      ))}
    </div>
  );
}

// ---------- Card grid (Step 1 style) ----------
function CardGrid({ options, value, onChange, columns = 2 }) {
  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: `repeat(${columns}, 1fr)`,
      gap: 12,
    }}>
      {options.map((o) => {
        const selected = value === o.value;
        return (
          <button
            key={o.value}
            onClick={() => onChange(o.value)}
            style={{
              textAlign: 'left', padding: '16px 18px',
              background: selected ? SELECTED_BG : CARD,
              border: `1.5px solid ${selected ? SELECTED_RING : CARD_BORDER}`,
              borderRadius: 14, cursor: 'pointer', color: INK,
              fontFamily: 'inherit', display: 'flex', flexDirection: 'row',
              alignItems: 'center', gap: 14, minHeight: 90,
              transition: 'background 160ms, border-color 160ms',
            }}
            onMouseEnter={(e) => !selected && (e.currentTarget.style.background = '#FFFCF6')}
            onMouseLeave={(e) => !selected && (e.currentTarget.style.background = CARD)}
          >
            {o.icon && (
              typeof o.icon === 'string'
                ? <img src={o.icon} width="40" height="40" alt="" style={{ display: 'block', flexShrink: 0 }} />
                : <span style={{
                    flexShrink: 0, width: 36, height: 36, borderRadius: 8, background: '#FDF1D9',
                    color: GOLD_DEEP, display: 'flex', alignItems: 'center', justifyContent: 'center',
                  }}>{o.icon}</span>
            )}
            <span style={{ fontSize: 14, lineHeight: 1.4, fontWeight: 400 }}>
              {o.title && <div style={{ fontWeight: 700, marginBottom: 4 }}>{o.title}</div>}
              {o.label}
            </span>
          </button>
        );
      })}
    </div>
  );
}

// ---------- Small icon set ----------
const Icon = {
  cloud: <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="4" stroke="currentColor" strokeWidth="1.6"/><circle cx="12" cy="12" r="1.5" fill="currentColor"/></svg>,
  star: <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M12 3l2.5 5.5L20 9.5l-4 4 1 5.5L12 16l-5 3 1-5.5-4-4 5.5-1z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/></svg>,
  leaf: <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="3" stroke="currentColor" strokeWidth="1.6"/><path d="M12 3v2M12 19v2M3 12h2M19 12h2" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>,
  heart: <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M12 20s-7-4.5-7-10a4 4 0 017-2.5A4 4 0 0119 10c0 5.5-7 10-7 10z" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"/></svg>,
  person: <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="8" r="3" stroke="currentColor" strokeWidth="1.6"/><path d="M5 20c0-3.5 3-6 7-6s7 2.5 7 6" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>,
  pin: <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M12 22s7-6.5 7-12a7 7 0 10-14 0c0 5.5 7 12 7 12z" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"/><circle cx="12" cy="10" r="2.4" stroke="currentColor" strokeWidth="1.6"/></svg>,
  smile: <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="8" stroke="currentColor" strokeWidth="1.6"/><path d="M9 14c1 1.2 2 1.7 3 1.7s2-.5 3-1.7" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/><circle cx="9.5" cy="10.5" r="0.9" fill="currentColor"/><circle cx="14.5" cy="10.5" r="0.9" fill="currentColor"/></svg>,
  triangle: <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M12 4l9 16H3z" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"/><path d="M12 10v5M12 17.5v.5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>,
  target: <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="8" stroke="currentColor" strokeWidth="1.6"/><circle cx="12" cy="12" r="3" stroke="currentColor" strokeWidth="1.6"/><circle cx="12" cy="12" r="0.8" fill="currentColor"/></svg>,
  arrow: <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M5 12h14M13 6l6 6-6 6" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>,
};

// ===============================================================
// FLOW ENGINE
// ===============================================================

const STATES = [
  'Alabama','Alaska','Arizona','Arkansas','California','Colorado',
  'Connecticut','Delaware','Florida','Georgia','Hawaii','Idaho',
  'Illinois','Indiana','Iowa','Kansas','Kentucky','Louisiana',
  'Maine','Maryland','Massachusetts','Michigan','Minnesota',
  'Mississippi','Missouri','Montana','Nebraska','Nevada',
  'New Hampshire','New Jersey','New Mexico','New York',
  'North Carolina','North Dakota','Ohio','Oklahoma','Oregon',
  'Pennsylvania','Rhode Island','South Carolina','South Dakota',
  'Tennessee','Texas','Utah','Vermont','Virginia','Washington',
  'West Virginia','Wisconsin','Wyoming',
];

const STATE_ABBR = {
  'Alabama':'AL','Alaska':'AK','Arizona':'AZ','Arkansas':'AR','California':'CA',
  'Colorado':'CO','Connecticut':'CT','Delaware':'DE','Florida':'FL','Georgia':'GA',
  'Hawaii':'HI','Idaho':'ID','Illinois':'IL','Indiana':'IN','Iowa':'IA','Kansas':'KS',
  'Kentucky':'KY','Louisiana':'LA','Maine':'ME','Maryland':'MD','Massachusetts':'MA',
  'Michigan':'MI','Minnesota':'MN','Mississippi':'MS','Missouri':'MO','Montana':'MT',
  'Nebraska':'NE','Nevada':'NV','New Hampshire':'NH','New Jersey':'NJ','New Mexico':'NM',
  'New York':'NY','North Carolina':'NC','North Dakota':'ND','Ohio':'OH','Oklahoma':'OK',
  'Oregon':'OR','Pennsylvania':'PA','Rhode Island':'RI','South Carolina':'SC',
  'South Dakota':'SD','Tennessee':'TN','Texas':'TX','Utah':'UT','Vermont':'VT',
  'Virginia':'VA','Washington':'WA','West Virginia':'WV','Wisconsin':'WI','Wyoming':'WY',
};

const SUPPORTED_STATES = new Set([
  'Connecticut','New York','Arizona','Nevada','Texas','Georgia','Florida',
]);

// ── Client-side scoring (mirrors server.py, used when API is unreachable) ─────
const _ISSUE_MAP = {
  'mood:anxious':'Anxiety','mood:down':'Depression','mood:stress':'Stress',
  'mood:anger':'Anger Management','mood:health-worry':'Health Anxiety',
  'mood:cancer':'Cancer (Living With Diagnosis)',
  'trauma:trauma':'Trauma / PTSD','trauma:grief':'Grief',
  'trauma:transition':'Life Transitions','trauma:cancer':'Cancer (Living With Diagnosis)',
  'behavioral:focus':'ADHD','behavioral:ocd':'OCD',
  'behavioral:substances':'Addiction / Substance Use',
  'behavioral:sleep':'Insomnia / Sleep Disturbances','behavioral:coping':'Coping Skills',
  'relationships:romantic':'Relationship Issues','relationships:family':'Family Conflict',
  'relationships:parenting':'Parenting','relationships:caregiver':'Caregiver Support',
  'relationships:child-health':'Parents of Children with Health Difficulties',
  'identity:body':'Body Image','identity:self-worth':'Self-Esteem',
  'identity:identity-nav':'LGBTQ+ Identity Affirmation','identity:growth':'Personal Growth',
  'reproductive:pregnant':'Pregnancy','reproductive:postpartum':'Postpartum',
  'reproductive:menopause':'Perimenopause / Menopause',
  'reproductive:intimacy':'Sexual Dysfunction','reproductive:fertility':'Fertility Challenges',
};
const _CAT = {
  mood:         new Set(['Anxiety','Depression','Stress','Anger Management','Health Anxiety','Cancer (Living With Diagnosis)']),
  trauma:       new Set(['Trauma / PTSD','Grief','Life Transitions','Cancer (Living With Diagnosis)']),
  behavioral:   new Set(['ADHD','OCD','Addiction / Substance Use','Insomnia / Sleep Disturbances','Coping Skills']),
  relationships:new Set(['Relationship Issues','Family Conflict','Parenting','Caregiver Support','Parents of Children with Health Difficulties']),
  identity:     new Set(['Body Image','Self-Esteem','LGBTQ+ Identity Affirmation','Personal Growth']),
  reproductive: new Set(['Pregnancy','Postpartum','Perimenopause / Menopause','Sexual Dysfunction','Fertility Challenges']),
};
const _P = { warm:'Warm & Nurturing', calm:'Calm & Steady', direct:'Direct & Candid' };
const _I = { listen:'Mostly listening', balance:'Balance of listening & feedback', active:'More active - guidance & direction', structured:'Very structured - worksheets / step-by-step' };
const _MAX = 7;

const _CDN = 'https://cdn.prod.website-files.com/68010ea49dd44e9c9b12d6e3';
const _COACHES = [
  {
    name:'Patrice Boyakins', credentials:'LMSW', role:'Coach', languages:['English'],
    headshot_url:`${_CDN}/68fbc4709564d4ef2570189e_Screenshot%202025-10-24%20at%202.10.36%E2%80%AFPM.png`,
    clinical_approaches:['ACT','Behavioral Activation','CBT','CBT-I'],
    bio:"Patrice brings one of the most extensive clinical toolkits on the Daylight team — including EMDR, Gottman, and trauma-focused CBT — adapting her approach to exactly what each client needs, whether that's processing trauma, building healthier habits, or navigating relationship conflict.",
    issues:new Set(['ADHD','Addiction / Substance Use','Anger Management','Anxiety','Body Image','Coping Skills','Depression','Family Conflict','Grief','Health Anxiety','Insomnia / Sleep Disturbances','LGBTQ+ Identity Affirmation','Life Transitions','OCD','Parenting','Relationship Issues','Self-Esteem','Sexual Dysfunction','Stress','Trauma / PTSD']),
    styles:new Set(['Calm & Steady','Direct & Candid','Warm & Nurturing']),
    involvements:new Set(['Balance of listening & feedback','More active - guidance & direction','Mostly listening','Very structured - worksheets / step-by-step']),
  },
  {
    name:'Janae Wright', credentials:'LMSW', role:'Coach', languages:['English'],
    headshot_url:null,
    clinical_approaches:['ABA','CBT','DBT','MBCT'],
    bio:'Janae is an LMSW who supports folks across the spectrum, and specializes in religion, spirituality, chronic illness, and autism support.',
    issues:new Set(['ADHD','Anger Management','Anxiety','Body Image','Cancer (Living With Diagnosis)','Coping Skills','Depression','Family Conflict','Grief','Health Anxiety','Life Transitions','Parenting','Postpartum','Pregnancy','Relationship Issues','Self-Esteem','Stress']),
    styles:new Set(['Direct & Candid','Warm & Nurturing']),
    involvements:new Set(['Balance of listening & feedback','More active - guidance & direction','Mostly listening','Very structured - worksheets / step-by-step']),
  },
  {
    name:'Alexandria Robinson', credentials:'LMSW, CADC-I', role:'Coach', languages:['English'],
    headshot_url:`${_CDN}/687f874a483ba0582c21d472_alexandria.jpg`,
    clinical_approaches:['CBT','CBT-I','DBT','Motivational Interviewing'],
    bio:'Alexandria is a coach trained in CBT and DBT who brings a calm, structured presence to helping clients manage anxiety, stress, and overwhelming life transitions. She has particular expertise in sleep difficulties (CBT-I) and is a strong fit for clients working through postpartum changes, self-esteem challenges, or building healthier daily habits.',
    issues:new Set(['ADHD','Addiction / Substance Use','Anxiety','Coping Skills','Depression','Family Conflict','Insomnia / Sleep Disturbances','Life Transitions','OCD','Parenting','Postpartum','Pregnancy','Relationship Issues','Self-Esteem','Stress']),
    styles:new Set(['Calm & Steady']),
    involvements:new Set(['Balance of listening & feedback','More active - guidance & direction','Mostly listening','Very structured - worksheets / step-by-step']),
  },
  {
    name:'Fredrica (Rica) Hendrix', credentials:'Ph.D', role:'Coach', languages:['English'],
    headshot_url:null,
    clinical_approaches:['Behavioral Activation','CBT','CBT-I','Cognitive Processing Therapy'],
    bio:'Rica is a psychologist and coach with a warm, adaptive style who helps clients build healthier habits and navigate anxiety, depression, and major life transitions with evidence-based tools.',
    issues:new Set(['ADHD','Anxiety','Coping Skills','Depression','Family Conflict','Insomnia / Sleep Disturbances','Life Transitions','Postpartum','Relationship Issues','Self-Esteem','Stress']),
    styles:new Set(['Calm & Steady','Direct & Candid','Warm & Nurturing']),
    involvements:new Set(['Balance of listening & feedback','More active - guidance & direction']),
  },
  {
    name:'Hisani Brewer', credentials:'LMSW', role:'Coach', languages:['English'],
    headshot_url:`${_CDN}/687f7fead7fe71fac5adf572_Hisani.jpg`,
    clinical_approaches:['Behavioral Activation','CBT','Cognitive Processing Therapy'],
    bio:'Hisani is a coach with a broad clinical toolkit — including trauma-focused CBT and behavioral activation — who helps clients build sustainable coping strategies and move through depression, grief, and life transitions with grounded support.',
    issues:new Set(['Depression']),
    styles:new Set(['Calm & Steady','Direct & Candid','Warm & Nurturing']),
    involvements:new Set(['Balance of listening & feedback','More active - guidance & direction','Mostly listening']),
  },
];

function scoreAndRankCoaches(userState) {
  const { presenting, sub, personality, involvement } = userState;
  const targetIssue = presenting && sub ? _ISSUE_MAP[`${presenting}:${sub}`] : null;
  const catIssues = _CAT[presenting] || new Set();

  const scored = _COACHES.map((c) => {
    let score = 0, exact = false;
    if (targetIssue && c.issues.has(targetIssue)) { score += 3; exact = true; }
    else if ([...catIssues].some(i => c.issues.has(i))) { score += 1; }
    if (_P[personality] && c.styles.has(_P[personality])) score += 2;
    if (_I[involvement] && c.involvements.has(_I[involvement])) score += 2;
    return { c, score, exact };
  });
  scored.sort((a, b) => b.score - a.score || (b.exact ? 1 : 0) - (a.exact ? 1 : 0));

  const pool = scored.filter(x => x.score > 0).length > 0
    ? scored.filter(x => x.score > 0)
    : scored.slice(0, 3);

  return pool.map(({ c, score }) => {
    const display = [];
    if (targetIssue && c.issues.has(targetIssue)) display.push(targetIssue);
    for (const i of catIssues) { if (c.issues.has(i) && !display.includes(i)) display.push(i); }
    return {
      name: c.name, credentials: c.credentials, role: c.role, languages: c.languages,
      headshot_url: c.headshot_url, clinical_approaches: c.clinical_approaches, bio: c.bio,
      matched_issues: display.slice(0, 3),
      fit_pct: score > 0 ? Math.round((score / _MAX) * 100) : null,
    };
  });
}

// Step 1 high-level categories
const PRESENTING = [
  { value: 'mood', icon: 'daylight-icons/anxiety.svg', label: 'Feelings like anxiety, sadness, stress, or anger affecting your day-to-day' },
  { value: 'trauma', icon: 'daylight-icons/flower-grief.svg', label: 'Difficult experiences with grief, or major life changes you\'re navigating' },
  { value: 'behavioral', icon: 'daylight-icons/sun-light%20yellow.svg', label: 'Patterns or habits that feel hard to manage, like focus, sleep, or substance use' },
  { value: 'relationships', icon: 'daylight-icons/chat-cope.svg', label: 'Challenges with a partner, family, parenting, or caring for a loved one' },
  { value: 'identity', icon: 'daylight-icons/behaviors.svg', label: 'Questions about who you are, how you see yourself, or who you want to become' },
  { value: 'reproductive', icon: 'daylight-icons/plants.svg', label: 'Experiences related to pregnancy, postpartum, menopause, fertility, or sexual health' },
];

const SUBSCREENS = {
  mood: {
    title: 'Tell us a little more about what\'s going on.',
    subtitle: 'Select the option that fits best.',
    footer: '1b MOOD → "Cancer diagnosis" triggers Cancer Context · All others → Step 2',
    options: [
      { value: 'anxious', label: 'I feel anxious, overwhelmed, or stuck in worry' },
      { value: 'down', label: 'I feel down, unmotivated, or emotionally drained' },
      { value: 'stress', label: 'I\'m dealing with stress from work, burnout, or life responsibilities' },
      { value: 'anger', label: 'I struggle with anger or emotional reactions that feel hard to manage' },
      { value: 'health-worry', label: 'I have intense or persistent worry about my health or a medical condition' },
      { value: 'cancer', label: 'I\'m living with a cancer diagnosis and navigating the emotional weight of it' },
    ],
  },
  trauma: {
    title: 'Tell us a little more about what\'s going on.',
    subtitle: 'Select the option that fits best.',
    footer: '1b TRAUMA → "Trauma" triggers Trauma Follow-up · "Cancer" triggers Cancer Context · Others → Step 2',
    options: [
      { value: 'trauma', label: 'I\'m dealing with difficult past experiences or trauma' },
      { value: 'grief', label: 'I\'m experiencing grief or loss' },
      { value: 'transition', label: 'I\'m navigating a major life change or transition' },
      { value: 'cancer', label: 'I\'m living with a cancer diagnosis and navigating the emotional weight of it' },
    ],
  },
  behavioral: {
    title: 'Tell us a little more about what\'s going on.',
    subtitle: 'Select the option that fits best.',
    footer: '1b BEHAVIORAL → "Substances" triggers Substance Gate · "OCD" triggers OCD Severity · Others → Step 2',
    options: [
      { value: 'focus', label: 'I have trouble with focus, attention, or feeling scattered' },
      { value: 'ocd', label: 'I\'m dealing with intrusive thoughts or compulsive behaviors I can\'t control' },
      { value: 'substances', label: 'I want to build a healthier relationship with alcohol or substances' },
      { value: 'sleep', label: 'I\'m having trouble sleeping or my sleep feels out of control' },
      { value: 'coping', label: 'I want to build better coping skills or healthier habits' },
    ],
  },
  relationships: {
    title: 'Tell us a little more about what\'s going on.',
    subtitle: 'Select the option that fits best.',
    footer: '1b RELATIONSHIPS → All options route to Step 2',
    options: [
      { value: 'romantic', label: 'I\'m struggling in a romantic relationship or partnership' },
      { value: 'family', label: 'I\'m navigating conflict or tension within my family' },
      { value: 'parenting', label: 'I\'m finding parenting challenging or overwhelming' },
      { value: 'caregiver', label: 'I\'m supporting someone I love through a health or life challenge' },
      { value: 'child-health', label: 'My child is facing health challenges and I need support as a parent' },
    ],
  },
  identity: {
    title: 'Tell us a little more about what\'s going on.',
    subtitle: 'Select the option that fits best.',
    footer: '1b IDENTITY → All options route to Step 2',
    options: [
      { value: 'body', label: 'I have a complicated relationship with my body or how I see myself' },
      { value: 'self-worth', label: 'I struggle with my confidence, self-worth, or how I feel about myself' },
      { value: 'identity-nav', label: 'I\'m navigating my identity, sexuality, or gender' },
      { value: 'growth', label: 'I\'m looking for personal growth or more direction in life' },
    ],
  },
  reproductive: {
    title: 'Tell us a little more about what\'s going on.',
    subtitle: 'Select the option that fits best.',
    footer: '1b REPRODUCTIVE → All options route to Step 2',
    options: [
      { value: 'pregnant', label: 'I\'m pregnant and looking for emotional support during this time' },
      { value: 'postpartum', label: 'I\'m adjusting to life after having a baby and need support' },
      { value: 'menopause', label: 'I\'m going through perimenopause or menopause and it\'s affecting my wellbeing' },
      { value: 'intimacy', label: 'I\'m experiencing challenges with intimacy or sexual wellbeing' },
      { value: 'fertility', label: 'I\'m experiencing challenges with becoming pregnant' },
    ],
  },
};

// Flow keys (routing)
const F = {
  LOCATION: 'location',
  UNSUPPORTED: 'unsupported',
  PRESENTING: 'presenting',
  SUB: 'sub',
  TRAUMA_FU: 'trauma_fu',
  CANCER: 'cancer',
  OCD: 'ocd',
  SUB_GATE: 'sub_gate',
  ESCALATION: 'escalation',
  RELATIONSHIPS_SUB: 'relationships_sub', // sub triggered by cancer-loved-one
  MODALITY: 'modality',
  PERSONALITY: 'personality',
  INVOLVEMENT: 'involvement',
  RESULTS: 'results',
};

// Progress weights for the top bar (0..1)
const PROGRESS = {
  [F.LOCATION]: 0.05,
  [F.UNSUPPORTED]: null,
  [F.PRESENTING]: 0.15,
  [F.SUB]: 0.25,
  [F.TRAUMA_FU]: 0.35,
  [F.CANCER]: 0.35,
  [F.OCD]: 0.35,
  [F.SUB_GATE]: 0.35,
  [F.ESCALATION]: 0.35,
  [F.RELATIONSHIPS_SUB]: 0.35,
  [F.MODALITY]: 0.45,
  [F.PERSONALITY]: 0.62,
  [F.INVOLVEMENT]: 0.80,
  [F.RESULTS]: 1.0,
};

const STEP_LABEL = {
  [F.LOCATION]: 'Getting started',
  [F.UNSUPPORTED]: null,
  [F.PRESENTING]: 'Step 1 of 4',
  [F.SUB]: 'Step 1 of 4',
  [F.TRAUMA_FU]: 'Step 1 of 4',
  [F.CANCER]: 'Step 1 of 4',
  [F.OCD]: 'Step 1 of 4',
  [F.SUB_GATE]: 'Step 1 of 4',
  [F.RELATIONSHIPS_SUB]: 'Step 1 of 4',
  [F.MODALITY]: 'Step 2 of 4',
  [F.PERSONALITY]: 'Step 3 of 4',
  [F.INVOLVEMENT]: 'Step 4 of 4',
  [F.RESULTS]: 'Step 4 of 4',
};

const DEBUG_FOOTER = {
  [F.LOCATION]: 'STEP 0 → Supported state: Step 1 | Unsupported state: Off-ramp',
  [F.UNSUPPORTED]: 'UNSUPPORTED STATE → Terminal (Schedule a support call)',
  [F.PRESENTING]: 'STEP 1 → Each card routes to its matching 1b sub-screen',
  [F.TRAUMA_FU]: 'TRAUMA FOLLOW-UP → All options route to Step 2',
  [F.CANCER]: 'CANCER CONTEXT → Options 1–3 → Step 2 · "Supporting a loved one" → 1b-Relationships',
  [F.OCD]: 'OCD SEVERITY → All options route to Step 2',
  [F.SUB_GATE]: 'SUBSTANCE GATE → Option 1 → Step 2 · Options 2 & 3 → Escalation screen',
  [F.ESCALATION]: 'ESCALATION → Off-ramp · "Go back" link returns to 1b-Behavioral',
  [F.MODALITY]: 'STEP 2 → Step 3 — Provider Personality',
  [F.PERSONALITY]: 'STEP 3 → Step 4 — Provider Involvement',
  [F.INVOLVEMENT]: 'STEP 4 → Step 5 — Confirmation / Results',
  [F.RESULTS]: 'STEP 4 → End of flow — Provider matches displayed',
};

// ===============================================================
// APP
// ===============================================================
function App() {
  const [history, setHistory] = useState([F.LOCATION]);
  const current = history[history.length - 1];

  const [state, setState] = useState({
    location: null,
    presenting: null,
    sub: null,       // sub-choice within the presenting sub-screen
    trauma_fu: null,
    cancer: null,
    ocd: null,
    sub_gate: null,
    relationships_sub: null,
    modality: null,
    personality: null,
    involvement: null,
  });

  const set = (k, v) => setState((s) => ({ ...s, [k]: v }));

  const push = (screen) => setHistory((h) => [...h, screen]);
  const back = () => {
    const prev = history[history.length - 2];
    if (prev === F.PRESENTING) set('presenting', null);
    setHistory((h) => (h.length > 1 ? h.slice(0, -1) : h));
  };
  const jumpTo = (screen) => {
    setHistory((h) => {
      const idx = h.lastIndexOf(screen);
      if (idx >= 0) return h.slice(0, idx + 1);
      return [...h, screen];
    });
  };

  // Session token — fetched once on mount, included on every API call
  const sessionToken = useRef(null);
  const [contactInfo, setContactInfo] = useState({ call_number: '', text_number: '' });
  useEffect(() => {
    fetch('/api/session')
      .then(r => r.ok ? r.json() : null)
      .then(d => { if (d?.token) sessionToken.current = d.token; })
      .catch(() => {});
    fetch('/api/config')
      .then(r => r.ok ? r.json() : null)
      .then(d => { if (d) setContactInfo(d); })
      .catch(() => {});
  }, []);

  // Anonymous per-load ID for funnel analytics — random, never stored, never tied to identity
  const anonId = useRef(Math.random().toString(36).slice(2, 10));

  // Analytics: step name only — no health values ever included
  useEffect(() => {
    if (!current) return;
    fetch('/api/event', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ step: current, sid: anonId.current }),
    }).catch(() => {});
  }, [current]);

  // Scroll to top on screen change
  const scRef = useRef(null);
  useEffect(() => {
    if (scRef.current) scRef.current.scrollTop = 0;
  }, [current]);

  // ---- Routing logic ----
  const afterSub = () => {
    // Determine which conditional branch (or direct to Step 2) based on presenting + sub value
    const p = state.presenting;
    const s = state.sub;
    if (p === 'mood') {
      if (s === 'cancer') return push(F.CANCER);
      return push(F.MODALITY);
    }
    if (p === 'trauma') {
      if (s === 'trauma') return push(F.TRAUMA_FU);
      if (s === 'cancer') return push(F.CANCER);
      return push(F.MODALITY);
    }
    if (p === 'behavioral') {
      if (s === 'ocd') return push(F.OCD);
      if (s === 'substances') return push(F.SUB_GATE);
      return push(F.MODALITY);
    }
    // relationships, identity, reproductive
    return push(F.MODALITY);
  };

  // -------- Render screens --------
  const progress = PROGRESS[current] ?? 0;
  const label = STEP_LABEL[current];
  const showBack = history.length > 1 && current !== F.RESULTS;

  const headerProgress = current === F.LOCATION ? null : progress;

  return (
    <div style={{
      minHeight: '100vh', background: BG, color: INK,
      fontFamily: '"Styrene B", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
    }} ref={scRef}>
      <Header
        progress={headerProgress}
        showBack={showBack}
        onBack={back}
        stepLabel={label}
      />

      <div key={current} style={{ animation: 'fadeIn 280ms ease both' }}>
        {current === F.LOCATION && (
          <LocationScreen
            value={state.location}
            onChange={(v) => set('location', v)}
            onContinue={() => {
              if (SUPPORTED_STATES.has(state.location)) {
                push(F.PRESENTING);
              } else {
                push(F.UNSUPPORTED);
              }
            }}
          />
        )}
        {current === F.UNSUPPORTED && (
          <UnsupportedStateScreen state={state.location} onBack={back} />
        )}
        {current === F.PRESENTING && (
          <PresentingScreen
            value={state.presenting}
            onChange={(v) => set('presenting', v)}
            onContinue={() => { set('sub', null); push(F.SUB); }}
          />
        )}
        {current === F.SUB && state.presenting && (
          <SubScreen
            spec={SUBSCREENS[state.presenting]}
            value={state.sub}
            onChange={(v) => set('sub', v)}
            onContinue={afterSub}
          />
        )}
        {current === F.TRAUMA_FU && (
          <SimpleRadio
            title="Is what you're working through something recent, or from further in your past?"
            subtitle="Both are valid. This just helps us match you with the right kind of support."
            options={[
              { value: 'recent', label: 'Something recent (within the last 6 months)' },
              { value: 'past', label: 'Something from further back that\'s still affecting me' },
              { value: 'unspecified', label: 'I\'d rather not specify right now' },
            ]}
            value={state.trauma_fu}
            onChange={(v) => set('trauma_fu', v)}
            onContinue={() => push(F.MODALITY)}
          />
        )}
        {current === F.CANCER && (
          <SimpleRadio
            title="Where are you in your journey right now?"
            subtitle="This helps us match you with someone who gets what you're going through."
            options={[
              { value: 'diagnosed', label: 'Recently diagnosed and processing the news' },
              { value: 'active', label: 'Currently in active treatment' },
              { value: 'remission', label: 'In remission or post-treatment' },
              { value: 'loved-one', label: 'Supporting a loved one with a cancer diagnosis' },
            ]}
            value={state.cancer}
            onChange={(v) => set('cancer', v)}
            onContinue={() => {
              if (state.cancer === 'loved-one') {
                // Route to 1b-Relationships — we set presenting=relationships and re-push SUB
                setState((s) => ({ ...s, presenting: 'relationships', sub: null }));
                push(F.SUB);
              } else {
                push(F.MODALITY);
              }
            }}
          />
        )}
        {current === F.OCD && (
          <SimpleRadio
            title="How much is this affecting your daily life?"
            subtitle="This helps us match you with a provider who specializes in the right level of care."
            options={[
              { value: 'mild', label: 'It\'s distressing but I\'m mostly functioning' },
              { value: 'severe', label: 'It\'s significantly interfering with my work, relationships, or daily routines' },
              { value: 'skip', label: 'I\'d rather not say right now' },
            ]}
            value={state.ocd}
            onChange={(v) => set('ocd', v)}
            onContinue={() => push(F.MODALITY)}
          />
        )}
        {current === F.SUB_GATE && (
          <SimpleRadio
            title="Before we continue, one important question."
            subtitle="Daylight offers coaching around substance use, but we're not a clinical addiction treatment program. We want to make sure we're the right fit."
            options={[
              { value: 'support', label: 'I\'m looking for support and accountability around my habits — I\'m not in crisis' },
              { value: 'active-treatment', label: 'I\'m currently in medical detox, rehab, or clinical treatment' },
              { value: 'need-treatment', label: 'I think I may need clinical treatment but haven\'t started yet' },
            ]}
            value={state.sub_gate}
            onChange={(v) => set('sub_gate', v)}
            onContinue={() => push(F.MODALITY)}
          />
        )}
        {current === F.MODALITY && (
          <TileTwoScreen
            title="What are you hoping to get from this experience first?"
            subtitle="There's no wrong answer — this helps us find the right fit."
            options={[
              { value: 'therapist', label: 'I want to process through difficult emotions or heal from past experiences' },
              { value: 'coach', label: 'I want tools, strategies, and accountability to improve how I function day-to-day' },
            ]}
            value={state.modality}
            onChange={(v) => set('modality', v)}
            onContinue={() => push(F.PERSONALITY)}
          />
        )}
        {current === F.PERSONALITY && (
          <TileThreeScreen
            title="What personality style do you tend to connect best with?"
            subtitle="There's no wrong answer — it helps us find the right fit."
            options={[
              { value: 'warm', icon: 'daylight-icons/heart-dotted.svg', title: 'Warm & Nurturing', label: 'A cheerleader who makes me feel deeply at ease' },
              { value: 'calm', icon: 'daylight-icons/anchor-dotted.svg', title: 'Calm & Steady', label: 'Someone grounded and anchoring, without being distant' },
              { value: 'direct', icon: 'daylight-icons/arrow-target-botanical.svg', title: 'Direct & Candid', label: 'Someone who tells it straight' },
            ]}
            value={state.personality}
            onChange={(v) => set('personality', v)}
            onContinue={() => push(F.INVOLVEMENT)}
          />
        )}
        {current === F.INVOLVEMENT && (
          <SimpleRadio
            title="How involved would you like your provider to be during sessions?"
            subtitle="This helps us select your communication style."
            options={[
              { value: 'listen', label: 'Mostly listening and giving me space to talk' },
              { value: 'balance', label: 'A balance of listening and offering feedback' },
              { value: 'active', label: 'More active — guidance and direction' },
              { value: 'structured', label: 'Very structured — worksheets and step-by-step support' },
            ]}
            value={state.involvement}
            onChange={(v) => set('involvement', v)}
            onContinue={() => push(F.RESULTS)}
          />
        )}
        {current === F.RESULTS && (
          <ResultsScreen state={state} onRestart={() => { setHistory([F.LOCATION]); }} sessionToken={sessionToken} contactInfo={contactInfo} />
        )}
      </div>


      <style>{`
        @keyframes fadeIn {
          from { opacity: 0; transform: translateY(6px); }
          to { opacity: 1; transform: translateY(0); }
        }
        @keyframes spin { to { transform: rotate(360deg); } }
        button:focus-visible {
          outline: 2px solid ${GOLD_DEEP};
          outline-offset: 2px;
        }
      `}</style>
    </div>
  );
}

// ===============================================================
// SCREENS
// ===============================================================

function LocationScreen({ value, onChange, onContinue }) {
  const [query, setQuery] = useState(value || '');
  const [open, setOpen] = useState(false);
  const containerRef = useRef(null);

  useEffect(() => {
    function handleClick(e) {
      if (containerRef.current && !containerRef.current.contains(e.target)) setOpen(false);
    }
    document.addEventListener('mousedown', handleClick);
    return () => document.removeEventListener('mousedown', handleClick);
  }, []);

  const filtered = STATES.filter((s) => s.toLowerCase().includes(query.toLowerCase()));

  function select(s) {
    onChange(s);
    setQuery(s);
    setOpen(false);
  }

  return (
    <QuestionShell
      title="First, where are you located?"
      subtitle="We'll use this to match you with providers licensed in your state. It takes just a second."
      onContinue={onContinue}
      continueEnabled={!!value}
    >
      <div ref={containerRef} style={{ maxWidth: 420, margin: '0 auto', position: 'relative' }}>
        <div style={{
          width: '100%', boxSizing: 'border-box', padding: '14px 20px',
          background: CARD, border: `1.5px solid ${open ? INK : CARD_BORDER}`, borderRadius: 12,
          display: 'flex', alignItems: 'center', gap: 8,
          transition: 'border-color 0.15s',
        }}>
          <input
            value={query}
            onChange={(e) => { const v = e.target.value.replace(/[^a-zA-Z\s]/g, ''); setQuery(v); onChange(null); setOpen(true); }}
            onFocus={() => setOpen(true)}
            placeholder="Type or select your state…"
            style={{
              flex: 1, border: 'none', outline: 'none', background: 'transparent',
              fontSize: 15, color: INK, fontFamily: 'inherit',
            }}
          />
          {query
            ? <button onClick={() => { setQuery(''); onChange(null); setOpen(true); }} style={{ border: 'none', background: 'transparent', cursor: 'pointer', padding: 0, color: INK_MUTED, lineHeight: 1, flexShrink: 0 }}>✕</button>
            : <svg width="16" height="16" viewBox="0 0 24 24" fill="none" style={{ flexShrink: 0, transition: 'transform 0.2s ease', transform: open ? 'rotate(180deg)' : 'rotate(0deg)' }}><path d="M6 9l6 6 6-6" stroke={INK_MUTED} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>
          }
        </div>
        {open && (
          <div style={{
            position: 'absolute', top: '100%', left: 0, right: 0, marginTop: 4,
            background: CARD, border: `1.5px solid ${CARD_BORDER}`, borderRadius: 12,
            maxHeight: 260, overflowY: 'auto', zIndex: 20,
            boxShadow: '0 10px 30px rgba(31,35,48,0.08)',
          }}>
            {filtered.length === 0
              ? <div style={{ padding: '12px 20px', fontSize: 14, color: INK_MUTED }}>No states found</div>
              : filtered.map((s) => (
                <button
                  key={s}
                  onMouseDown={(e) => { e.preventDefault(); select(s); }}
                  style={{
                    display: 'block', width: '100%', textAlign: 'left',
                    padding: '12px 20px', background: s === value ? SELECTED_BG : 'transparent',
                    border: 'none', cursor: 'pointer', fontSize: 14, color: INK, fontFamily: 'inherit',
                  }}
                  onMouseEnter={(e) => (e.currentTarget.style.background = SELECTED_BG)}
                  onMouseLeave={(e) => (e.currentTarget.style.background = s === value ? SELECTED_BG : 'transparent')}
                >{s}</button>
              ))
            }
          </div>
        )}
      </div>
    </QuestionShell>
  );
}

function PresentingScreen({ value, onChange, onContinue }) {
  return (
    <QuestionShell
      title="What best describes what you're going through right now?"
      subtitle="Select the one that resonates most with you."
      onContinue={onContinue}
      continueEnabled={!!value}
      wide
    >
      <CardGrid options={PRESENTING} value={value} onChange={onChange} columns={2} />
    </QuestionShell>
  );
}

function SubScreen({ spec, value, onChange, onContinue }) {
  return (
    <QuestionShell
      title={spec.title}
      subtitle={spec.subtitle}
      onContinue={onContinue}
      continueEnabled={!!value}
    >
      <RadioList options={spec.options} value={value} onChange={onChange} />
    </QuestionShell>
  );
}

function SimpleRadio({ title, subtitle, options, value, onChange, onContinue }) {
  return (
    <QuestionShell title={title} subtitle={subtitle} onContinue={onContinue} continueEnabled={!!value}>
      <RadioList options={options} value={value} onChange={onChange} />
    </QuestionShell>
  );
}

function TileTwoScreen({ title, subtitle, options, value, onChange, onContinue }) {
  const hasIcons = options.some(o => o.icon);
  return (
    <QuestionShell title={title} subtitle={subtitle} onContinue={onContinue} continueEnabled={!!value} wide>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14, maxWidth: 560, margin: '0 auto' }}>
        {options.map((o) => {
          const selected = value === o.value;
          return (
            <button
              key={o.value} onClick={() => onChange(o.value)}
              style={{
                background: selected ? SELECTED_BG : CARD,
                border: `1.5px solid ${selected ? SELECTED_RING : CARD_BORDER}`,
                borderRadius: 14, padding: '20px 20px 22px', cursor: 'pointer',
                textAlign: hasIcons ? 'left' : 'center', fontFamily: 'inherit', color: INK, minHeight: 180,
                display: 'flex', flexDirection: 'column', gap: 14,
                alignItems: hasIcons ? 'flex-start' : 'center', justifyContent: 'center',
              }}
            >
              {o.icon && <span style={{
                width: 34, height: 34, borderRadius: 8, background: '#FDF1D9',
                color: GOLD_DEEP, display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>{o.icon}</span>}
              {o.title && <div style={{ fontWeight: 700, fontSize: 17 }}>{o.title}</div>}
              <div style={{ fontSize: 13.5, color: INK, lineHeight: 1.45 }}>{o.label}</div>
            </button>
          );
        })}
      </div>
    </QuestionShell>
  );
}

function TileThreeScreen({ title, subtitle, options, value, onChange, onContinue }) {
  return (
    <QuestionShell title={title} subtitle={subtitle} onContinue={onContinue} continueEnabled={!!value} wide>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 14, maxWidth: 720, margin: '0 auto' }}>
        {options.map((o) => {
          const selected = value === o.value;
          return (
            <button
              key={o.value} onClick={() => onChange(o.value)}
              style={{
                background: selected ? SELECTED_BG : CARD,
                border: `1.5px solid ${selected ? SELECTED_RING : CARD_BORDER}`,
                borderRadius: 14, padding: '20px', cursor: 'pointer',
                textAlign: 'left', fontFamily: 'inherit', color: INK, minHeight: 180,
                display: 'flex', flexDirection: 'column', gap: 12,
              }}
            >
              {typeof o.icon === 'string'
                ? <img src={o.icon} width="30" height="30" alt="" style={{ display: 'block' }} />
                : <span style={{
                    width: 30, height: 30, borderRadius: 8, background: '#FDF1D9',
                    color: GOLD_DEEP, display: 'flex', alignItems: 'center', justifyContent: 'center',
                  }}>{o.icon}</span>
              }
              <div style={{ fontWeight: 700, fontSize: 15 }}>{o.title}</div>
              <div style={{ fontSize: 13, color: INK_SOFT, lineHeight: 1.45 }}>{o.label}</div>
            </button>
          );
        })}
      </div>
    </QuestionShell>
  );
}

function Escalation({ onBack }) {
  return (
    <div style={{ maxWidth: 560, margin: '30px auto 120px', padding: '0 24px', textAlign: 'center' }}>
      <div style={{
        width: 48, height: 48, borderRadius: '50%', background: '#fff',
        border: `1.5px solid ${CARD_BORDER}`, color: GOLD_DEEP,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        margin: '8px auto 18px',
      }}>{Icon.pin}</div>
      <h1 style={{ fontSize: 26, lineHeight: 1.2, fontWeight: 700, margin: '0 0 14px', letterSpacing: -0.3 }}>
        We want to make sure you get the right care.
      </h1>
      <p style={{ color: INK_SOFT, fontSize: 15, lineHeight: 1.55, margin: '0 auto 28px', maxWidth: 480 }}>
        Daylight offers coaching and therapy for a wide range of concerns, but based on what you shared,
        you may benefit more from a program that can offer specialized clinical support. We'd like to help
        you find the right resource.
      </p>
      <button style={{
        background: GOLD, color: INK, border: 'none', borderRadius: 999,
        padding: '14px 32px', fontSize: 15, fontWeight: 500, cursor: 'pointer',
        fontFamily: 'inherit', marginBottom: 20,
      }}>Connect me with Daylight support</button>

      <div style={{
        border: `1.5px dashed ${CARD_BORDER}`, borderRadius: 14, padding: '20px 24px',
        color: INK_MUTED, fontSize: 13, lineHeight: 1.5, maxWidth: 460, margin: '0 auto 24px',
      }}>
        <div style={{ letterSpacing: 2, textTransform: 'uppercase', fontSize: 10, fontWeight: 500, marginBottom: 6 }}>Placeholder</div>
        Additional referral resources to be added by the Daylight clinical team
      </div>

      <button onClick={onBack} style={{
        background: 'transparent', border: 'none', color: INK_SOFT,
        textDecoration: 'underline', cursor: 'pointer', fontSize: 14, fontFamily: 'inherit',
      }}>Actually, I selected the wrong option — let me go back</button>
    </div>
  );
}

// ===============================================================
// RESULTS
// ===============================================================
function ResultsScreen({ state, onRestart, sessionToken, contactInfo = {} }) {
  const [phase, setPhase] = useState('loading'); // loading | done
  const [data, setData] = useState({ matches: [], coach_matches: [], suggest_specialist: false });
  // availMap: { [providerName]: { slots: string[] } | null }
  // null = fetch errored (show provider anyway); { slots: [] } = no availability (hide); { slots: [...] } = has slots (show)
  const [availMap, setAvailMap] = useState({});

  function _fetchAvailability(providers) {
    providers.forEach(p => {
      if (!p.healthie_id) return;
      fetch(`/api/availability?provider_id=${encodeURIComponent(String(p.healthie_id))}`)
        .then(r => r.ok ? r.json() : null)
        .then(d => {
          const slots = d && Array.isArray(d.slots) ? d.slots : [];
          setAvailMap(prev => ({ ...prev, [p.name]: { slots } }));
        })
        .catch(() => setAvailMap(prev => ({ ...prev, [p.name]: null })));
    });
  }

  useEffect(() => {
    const payload = {
      state: state.location,
      presenting: state.presenting,
      sub: state.sub,
      personality: state.personality,
      involvement: state.involvement,
    };

    const authHeaders = {
      'Content-Type': 'application/json',
      ...(sessionToken?.current ? { 'X-Session-Token': sessionToken.current } : {}),
    };

    const minDelay = new Promise((res) => setTimeout(res, 1500));
    const fetchMatch = fetch('/api/match', {
      method: 'POST',
      headers: authHeaders,
      body: JSON.stringify(payload),
    }).then((r) => {
      if (!r.ok) throw new Error('api_down');
      return r.json();
    });

    Promise.all([minDelay, fetchMatch])
      .then(([, result]) => {
        setData(result);
        setPhase('done');
        _fetchAvailability([...(result.matches || []), ...(result.coach_matches || [])]);
      })
      .catch(() =>
        fetch('/api/coaches')
          .then((r) => { if (!r.ok) throw new Error('down'); return r.json(); })
          .then((fallback) => {
            setData({ matches: [], coach_matches: fallback.matches, suggest_specialist: true });
            setPhase('done');
            _fetchAvailability(fallback.matches || []);
          })
          .catch(() => {
            const fallbackCoaches = scoreAndRankCoaches(state);
            setData({ matches: [], coach_matches: fallbackCoaches, suggest_specialist: true });
            setPhase('done');
            _fetchAvailability(fallbackCoaches);
          })
      );
  }, []);

  const loading = phase === 'loading';
  const allMatches = [
    ...(data.matches || []).map(p => ({ ...p, _state: true })),
    ...(data.coach_matches || []).map(p => ({ ...p, _state: false })),
  ].sort((a, b) => b.fit_pct - a.fit_pct || (b._state ? 1 : 0) - (a._state ? 1 : 0));

  // Hide providers with a Healthie ID confirmed to have 0 slots in the next 14 days.
  // Providers with no ID (not yet on Healthie) are always shown.
  // While a check is still in-flight (not in availMap), show the provider.
  const visibleMatches = allMatches.filter(p => {
    if (!p.healthie_id) return true;
    const avail = availMap[p.name];
    if (avail === undefined) return true; // still fetching
    if (avail === null) return true;      // fetch errored — show anyway
    return avail.slots.length > 0;
  });

  return (
    <div style={{ maxWidth: 720, margin: '0 auto', padding: '24px 24px 100px' }}>

      {/* ── Page header ── */}
      <div style={{ textAlign: 'center', padding: '12px 0 32px' }}>
        <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 18 }}>
          {loading ? (
            <svg width="56" height="56" viewBox="0 0 56 56" fill="none" style={{ animation: 'spin 1.4s linear infinite' }}>
              <circle cx="28" cy="28" r="24" stroke="#F4E4BE" strokeWidth="3" fill="none" />
              <circle cx="28" cy="28" r="24" stroke={GOLD_DEEP} strokeWidth="3" fill="none"
                strokeDasharray="75 76" strokeLinecap="round" />
              <circle cx="28" cy="28" r="10" fill={GOLD} />
            </svg>
          ) : (
            <svg width="56" height="56" viewBox="0 0 56 56" fill="none">
              {[0,45,90,135,180,225,270,315].map((deg) => {
                const rad = (deg * Math.PI) / 180;
                return <line key={deg}
                  x1={28 + Math.cos(rad) * 16} y1={28 + Math.sin(rad) * 16}
                  x2={28 + Math.cos(rad) * 24} y2={28 + Math.sin(rad) * 24}
                  stroke={GOLD_DEEP} strokeWidth="2.5" strokeLinecap="round" />;
              })}
              <circle cx="28" cy="28" r="11" fill={GOLD_DEEP} />
              <circle cx="28" cy="28" r="8" fill={GOLD} />
            </svg>
          )}
        </div>
        <div style={{ fontSize: 11, letterSpacing: '0.15em', textTransform: 'uppercase', fontWeight: 500, color: INK_MUTED, marginBottom: 10 }}>
          Personalized Results
        </div>
        <h1 style={{ fontSize: 30, fontWeight: 700, lineHeight: 1.15, letterSpacing: -0.5, margin: '0 0 12px', color: INK }}>
          {loading ? 'Finding your matches…' : 'Expert Recommendations.\nJust For You.'}
        </h1>
        <p style={{ color: INK_SOFT, fontSize: 14.5, lineHeight: 1.55, margin: '0 auto', maxWidth: 460 }}>
          {loading
            ? "Based on your answers, we're finding the right Daylight provider for you."
            : 'Take the next step with a Daylight provider especially chosen for you.'}
        </p>
      </div>

      {/* ── Loading skeletons ── */}
      {loading && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          {[0, 1, 2].map((i) => <ProviderCard key={i} loading index={i} />)}
        </div>
      )}

      {/* ── All matched providers, sorted by fit, filtered by availability ── */}
      {!loading && visibleMatches.length > 0 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          {visibleMatches.map((p, i) => {
            const avail = p.healthie_id ? availMap[p.name] : null;
            return (
              <ProviderCard
                key={p.name}
                provider={p}
                loading={false}
                index={i}
                stateAbbr={STATE_ABBR[state.location]}
                slots={avail ? avail.slots : null}
                slotsLoading={!!p.healthie_id && !(p.name in availMap)}
              />
            );
          })}
        </div>
      )}

      {/* ── Still weighing section ── */}
      {phase === 'done' && (
        <div style={{
          marginTop: 32, borderRadius: 16, background: '#292136',
          padding: '32px 28px', display: 'flex', flexDirection: 'column',
          alignItems: 'center', textAlign: 'center', gap: 14,
        }}>
          <h2 style={{ fontSize: 20, fontWeight: 700, color: '#fff6e1', margin: 0, letterSpacing: -0.3 }}>
            Questions? We're here.
          </h2>
          <p style={{ fontSize: 14, color: 'rgba(255,246,225,0.6)', lineHeight: 1.6, margin: 0, maxWidth: 320 }}>
            Our team can help you find the right fit.
          </p>
          <div style={{ display: 'flex', gap: 10, marginTop: 4 }}>
            <a href={`tel:${contactInfo.call_number}`} style={{
              display: 'flex', alignItems: 'center', gap: 7,
              background: '#f4da55', color: '#1b1b1b', borderRadius: 999,
              padding: '11px 22px', fontSize: 14, fontWeight: 600,
              textDecoration: 'none', fontFamily: 'inherit',
            }}>
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M6.6 10.8a15.2 15.2 0 006.6 6.6l2.2-2.2a1 1 0 011.1-.2 11.5 11.5 0 003.6.6 1 1 0 011 1V21a1 1 0 01-1 1A17 17 0 012 5a1 1 0 011-1h3.5a1 1 0 011 1c0 1.3.2 2.5.6 3.6a1 1 0 01-.2 1.1L6.6 10.8z" stroke="#1b1b1b" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>
              Call us
            </a>
            <a href={`sms:${contactInfo.text_number}`} style={{
              display: 'flex', alignItems: 'center', gap: 7,
              background: 'transparent', color: '#fff6e1', borderRadius: 999,
              padding: '11px 22px', fontSize: 14, fontWeight: 600,
              textDecoration: 'none', fontFamily: 'inherit',
              border: '1.5px solid rgba(255,246,225,0.25)',
            }}>
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" stroke="#fff6e1" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>
              Text us
            </a>
          </div>
          <button onClick={onRestart} style={{
            background: 'transparent', border: 'none', fontSize: 13,
            color: 'rgba(255,246,225,0.4)', cursor: 'pointer', fontFamily: 'inherit',
            textDecoration: 'underline',
          }}>Start over</button>
        </div>
      )}
    </div>
  );
}

function _groupSlotsByDay(isoSlots) {
  const groups = {};
  (isoSlots || []).forEach(iso => {
    const d = new Date(iso);
    const key = d.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });
    if (!groups[key]) groups[key] = [];
    if (groups[key].length < 3) groups[key].push(d.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }));
  });
  return Object.entries(groups).slice(0, 3);
}

function ProviderCard({ provider, loading, index, stateAbbr, slots, slotsLoading }) {
  const healthieId = provider && provider.healthie_id;

  if (loading) {
    return (
      <div style={{
        background: CARD, border: `1px solid ${CARD_BORDER}`, borderRadius: 16,
        overflow: 'hidden', opacity: index > 0 ? 0.5 : 1, transition: 'opacity 400ms',
      }}>
        <div style={{ padding: '20px 22px', display: 'flex', alignItems: 'center', gap: 16 }}>
          <div style={{ width: 60, height: 60, borderRadius: '50%', background: '#F7EBD3', flexShrink: 0 }} />
          <div style={{ flex: 1 }}>
            <div style={{ height: 12, background: '#F0E2CC', borderRadius: 4, marginBottom: 8, width: '42%' }} />
            <div style={{ height: 9, background: '#F6ECD8', borderRadius: 4, width: '28%' }} />
          </div>
        </div>
        <div style={{ height: 1, background: CARD_BORDER }} />
        <div style={{ padding: '18px 22px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20 }}>
          <div>
            <div style={{ height: 9, background: '#F0E2CC', borderRadius: 4, marginBottom: 10, width: '38%' }} />
            <div style={{ height: 8, background: '#F6ECD8', borderRadius: 4, marginBottom: 5, width: '88%' }} />
            <div style={{ height: 8, background: '#F6ECD8', borderRadius: 4, width: '65%' }} />
          </div>
          <div>
            <div style={{ height: 8, background: '#F6ECD8', borderRadius: 4, marginBottom: 5, width: '92%' }} />
            <div style={{ height: 8, background: '#F6ECD8', borderRadius: 4, marginBottom: 5, width: '80%' }} />
            <div style={{ height: 8, background: '#F6ECD8', borderRadius: 4, width: '55%' }} />
          </div>
        </div>
        <div style={{ height: 1, background: CARD_BORDER }} />
        <div style={{ padding: '14px 22px' }}>
          <div style={{ height: 34, background: '#F6ECD8', borderRadius: 999, width: 170 }} />
        </div>
      </div>
    );
  }

  const firstName = provider.name.split(' ')[0];
  const roleLabel = provider._state ? `Therapist in ${stateAbbr || ''}` : 'Mental Health Coach';

  return (
    <div style={{
      background: CARD, border: `1px solid ${CARD_BORDER}`, borderRadius: 16, overflow: 'hidden',
    }}>
      {/* ── Header: photo + name + badges ── */}
      <div style={{ padding: '20px 22px 16px', display: 'flex', alignItems: 'center', gap: 16 }}>
        <div style={{ width: 62, height: 62, borderRadius: '50%', flexShrink: 0, background: '#EDE4D5', overflow: 'hidden' }}>
          {provider.headshot_url && (
            <img src={provider.headshot_url} alt={provider.name}
              style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
          )}
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontWeight: 700, fontSize: 16, color: INK, marginBottom: 3 }}>
            {provider.name}
            {provider.credentials && (
              <span style={{ fontWeight: 400, fontSize: 12, color: INK_MUTED, marginLeft: 7 }}>{provider.credentials}</span>
            )}
          </div>
          <div style={{ fontSize: 13, color: INK_SOFT }}>
            {roleLabel}{provider.languages.includes('Spanish') && ' · Habla español'}
          </div>
        </div>
        {provider.fit_pct != null && (
          <div style={{ flexShrink: 0 }}>
            <div style={{ background: '#FDEDC9', color: GOLD_DEEP, fontSize: 11.5, fontWeight: 600, padding: '4px 10px', borderRadius: 999 }}>
              {provider.fit_pct}% fit
            </div>
          </div>
        )}
      </div>

      <div style={{ height: 1, background: CARD_BORDER, margin: '0 22px' }} />

      {/* ── Body: two columns ── */}
      <div style={{ padding: '18px 22px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 24 }}>
        <div>
          <div style={{ fontWeight: 700, fontSize: 13, color: INK, marginBottom: 8 }}>Why {firstName}</div>
          {provider.matched_issues.length > 0 && (
            <div style={{ fontSize: 12.5, color: INK_SOFT, lineHeight: 1.5, marginBottom: 10 }}>
              {provider.matched_issues.slice(0, 3).join(' · ')}
            </div>
          )}
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5 }}>
            {provider.clinical_approaches.slice(0, 2).map((a) => (
              <span key={a} style={{ fontSize: 11, color: INK_MUTED, background: '#F5EFE6', padding: '3px 9px', borderRadius: 999 }}>
                {a.replace(/\s*\(.*?\)/g, '').trim()}
              </span>
            ))}
          </div>
          {/* ── Availability slots (only shown once Healthie IDs are filled in) ── */}
          {healthieId && (
            <div style={{ marginTop: 12 }}>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 6, marginBottom: 6 }}>
                <span style={{ fontWeight: 700, fontSize: 13, color: INK }}>{firstName}'s availability</span>
                <span style={{ fontSize: 10.5, color: INK_MUTED }}>
                  {new Date().toLocaleTimeString('en-US', { timeZoneName: 'short' }).split(' ').pop()}
                </span>
              </div>
              {slotsLoading && (
                <div style={{ fontSize: 11.5, color: INK_MUTED }}>Loading…</div>
              )}
              {!slotsLoading && slots !== null && slots.length === 0 && (
                <div style={{ fontSize: 11.5, color: INK_MUTED }}>No upcoming slots — check back soon.</div>
              )}
              {!slotsLoading && slots && slots.length > 0 && _groupSlotsByDay(slots).map(([day, times]) => (
                <div key={day} style={{ marginBottom: 6 }}>
                  <div style={{ fontSize: 11, color: INK_MUTED, marginBottom: 3 }}>{day}</div>
                  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
                    {times.map(t => (
                      <span key={t} style={{ fontSize: 11, color: '#145d7a', background: '#c4e8ed', padding: '2px 8px', borderRadius: 999 }}>{t}</span>
                    ))}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
        <div>
          <div style={{ fontWeight: 700, fontSize: 13, color: INK, marginBottom: 8 }}>About</div>
          <p style={{ fontSize: 12.5, color: INK_SOFT, lineHeight: 1.65, margin: 0 }}>{provider.bio}</p>
        </div>
      </div>

      <div style={{ height: 1, background: CARD_BORDER, margin: '0 22px' }} />

      {/* ── Footer: connect button ── */}
      <div style={{ padding: '14px 22px' }}>
        {healthieId ? (
          <a
            href={`https://secure.daylight-health.com/appointments/embed_appt?dietitian_id=${encodeURIComponent(String(healthieId))}&appt_type_id=324313`}
            target="_blank" rel="noopener noreferrer"
            style={{
              display: 'inline-block', border: `1.5px solid ${CARD_BORDER}`, borderRadius: 999,
              padding: '9px 22px', fontSize: 13, fontWeight: 500, color: INK,
              textDecoration: 'none', cursor: 'pointer', transition: 'border-color 160ms, color 160ms',
            }}
            onMouseEnter={(e) => { e.currentTarget.style.borderColor = GOLD_DEEP; e.currentTarget.style.color = GOLD_DEEP; }}
            onMouseLeave={(e) => { e.currentTarget.style.borderColor = CARD_BORDER; e.currentTarget.style.color = INK; }}
          >Connect with {firstName}</a>
        ) : (
          <a href="#" onClick={(e) => e.preventDefault()} title="Booking link coming soon"
            style={{
              display: 'inline-block', border: `1.5px solid ${CARD_BORDER}`, borderRadius: 999,
              padding: '9px 22px', fontSize: 13, fontWeight: 500, color: INK,
              textDecoration: 'none', cursor: 'pointer', transition: 'border-color 160ms, color 160ms',
              opacity: 0.6,
            }}
            onMouseEnter={(e) => { e.currentTarget.style.borderColor = GOLD_DEEP; e.currentTarget.style.color = GOLD_DEEP; }}
            onMouseLeave={(e) => { e.currentTarget.style.borderColor = CARD_BORDER; e.currentTarget.style.color = INK; }}
          >Connect with {firstName}</a>
        )}
      </div>
    </div>
  );
}

function summarize(state) {
  const modality = state.modality === 'therapist' ? 'therapy' : 'coaching';
  const bits = [];
  if (state.presenting) {
    const p = {
      mood: 'mood and stress',
      trauma: 'grief and life transitions',
      behavioral: 'behavior and habits',
      relationships: 'relationship dynamics',
      identity: 'identity and self-growth',
      reproductive: 'reproductive and perinatal wellbeing',
    }[state.presenting];
    if (p) bits.push(p);
  }
  return `${modality}${bits.length ? ' for ' + bits.join(', ') : ''}`;
}

// ===============================================================
// UNSUPPORTED STATE SCREEN
// ===============================================================
function UnsupportedStateScreen({ state: stateName, onBack }) {
  return (
    <div style={{ maxWidth: 640, margin: '20px auto 100px', padding: '0 24px' }}>
      <div style={{
        border: `1.5px solid ${CARD_BORDER}`,
        borderRadius: 24,
        padding: '56px 64px',
        background: 'transparent',
      }}>
        <h1 style={{
          fontSize: 30, fontWeight: 700, lineHeight: 1.18,
          color: INK, margin: '0 0 32px', letterSpacing: -0.4,
        }}>
          We can help with care coordination
        </h1>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 18, marginBottom: 44 }}>
          <p style={{ margin: 0, fontSize: 17, lineHeight: 1.6, color: INK_SOFT }}>
            Unfortunately, we are not available in{stateName ? ` ${stateName}` : ' your state'} at this time.
          </p>
          <p style={{ margin: 0, fontSize: 17, lineHeight: 1.6, color: INK_SOFT }}>
            However, we would still love to support you in getting insurance-covered care with another provider.
          </p>
          <p style={{ margin: 0, fontSize: 17, lineHeight: 1.6, color: INK_SOFT }}>
            If you need support in getting set up with an insurance-accepting provider, we would be happy to hop on a call with you.
          </p>
        </div>

        <div style={{ display: 'flex', justifyContent: 'center' }}>
          <a
            href="https://go.daylight-health.com/free-consultation-call"
            target="_blank"
            rel="noopener noreferrer"
            style={{
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              background: 'rgba(255,255,255,0.7)',
              border: `1.5px solid ${CARD_BORDER}`,
              borderRadius: 999, padding: '15px 36px',
              fontFamily: 'inherit', fontSize: 12, fontWeight: 600,
              letterSpacing: '0.1em', color: INK,
              textDecoration: 'none', textTransform: 'uppercase',
              cursor: 'pointer',
              transition: 'border-color 160ms, background 160ms',
            }}
            onMouseEnter={(e) => { e.currentTarget.style.borderColor = GOLD_DEEP; e.currentTarget.style.background = '#fff'; }}
            onMouseLeave={(e) => { e.currentTarget.style.borderColor = CARD_BORDER; e.currentTarget.style.background = 'rgba(255,255,255,0.7)'; }}
          >
            Schedule a Support Call
          </a>
        </div>
      </div>

      <div style={{ textAlign: 'center', marginTop: 20 }}>
        <button onClick={onBack} style={{
          background: 'transparent', border: 'none', color: INK_MUTED,
          fontSize: 13, cursor: 'pointer', fontFamily: 'inherit',
          textDecoration: 'underline',
        }}>
          ← Change my state
        </button>
      </div>
    </div>
  );
}

// Mount
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
