/* CaptureFlow.jsx — Muna Health intraoral photo capture.
   intro → 4×(capture → review) → summary → AI processing → (onComplete → result)
   Reads the shared design system: Stage (MunaFlow), Icon/Button/Card (MunaComponents),
   colors_and_type.css tokens. Voice: calm, brief, clinical-warm.
   Exports window.MunaCapture = { CaptureFlow }.

   ⚠ One DEV-only affordance: the per-photo "DEV · skip photo" button, gated on
   DEV_TOOLS — remove that block + the `DEV_TOOLS &&` usage for production. */

const { Stage: CapStage } = window.MunaFlow;
const CAP_DEV_TOOLS = true; /* ⚠ PROTOTYPE ONLY */

const PHOTOS = [
  { key: 'front', label: 'Front teeth', instruction: 'Smile naturally. Show your front teeth from top to bottom.' },
  { key: 'upper', label: 'Upper gums',  instruction: 'Tip your head back a little and lift your upper lip to show the gumline.' },
  { key: 'lower', label: 'Lower gums',  instruction: 'Pull your lower lip down gently to show the bottom gumline.' },
  { key: 'tongue', label: 'Tongue',     instruction: 'Open wide and stick your tongue out as far as is comfortable.' },
];
const FAIL_INDEX = 1; // upper gums "fails" on the first attempt to demo the retake path

// ─── Schematic mouth line-drawings (not photos — reduces ick, per the system) ──
function MouthGuide({ type, size = 188 }) {
  const s = { fill: 'none', stroke: 'currentColor', strokeWidth: 3, strokeLinecap: 'round', strokeLinejoin: 'round' };
  return (
    <svg width={size} height={size * 0.8} viewBox="0 0 200 160" aria-hidden="true">
      <path d="M20 80 Q100 22 180 80 Q100 138 20 80 Z" {...s}/>
      {type === 'front' && <line x1="26" y1="80" x2="174" y2="80" {...s}/>}
      {type === 'front' && [52, 76, 100, 124, 148].map(x => <line key={x} x1={x} y1="62" x2={x} y2="98" {...s}/>)}
      {type === 'upper' && <path d="M32 68 Q100 38 168 68" {...s}/>}
      {type === 'upper' && [58, 82, 106, 130].map(x => <line key={x} x1={x} y1="58" x2={x} y2="84" {...s}/>)}
      {type === 'lower' && <path d="M32 92 Q100 122 168 92" {...s}/>}
      {type === 'lower' && [58, 82, 106, 130].map(x => <line key={x} x1={x} y1="76" x2={x} y2="102" {...s}/>)}
      {type === 'tongue' && <path d="M68 88 Q100 150 132 88 Q100 104 68 88 Z" {...s}/>}
    </svg>
  );
}

// ─── Local paper-grain (self-contained) ────────────────────────────────
function CapGrain({ opacity = 0.06 }) {
  return (
    <div aria-hidden="true" style={{
      position: 'absolute', inset: 0, pointerEvents: 'none', opacity,
      backgroundImage:
        'radial-gradient(circle at 20% 30%, #57534E 0 1px, transparent 1.4px), ' +
        'radial-gradient(circle at 66% 70%, #57534E 0 1px, transparent 1.4px), ' +
        'radial-gradient(circle at 86% 36%, #57534E 0 0.8px, transparent 1.2px)',
      backgroundSize: '11px 11px, 15px 15px, 9px 9px',
    }}/>
  );
}

// ─── Viewfinder mock (neutral placeholder + corner brackets + guide) ────
function Viewfinder({ type, captured = false, style = {} }) {
  const bracket = { position: 'absolute', width: 26, height: 26, borderColor: captured ? 'rgba(255,255,255,0.7)' : 'var(--stone-400)', borderStyle: 'solid' };
  return (
    <div style={{
      position: 'relative', borderRadius: 'var(--radius-l)', overflow: 'hidden',
      background: captured ? 'var(--stone-300)' : 'var(--stone-200)',
      boxShadow: 'inset 0 0 0 1px var(--border-subtle)', ...style,
    }}>
      <CapGrain opacity={captured ? 0.09 : 0.06}/>
      {captured && <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(160deg, rgba(87,83,78,0.16), rgba(87,83,78,0.32))' }}/>}
      {/* corner brackets */}
      <div style={{ ...bracket, top: 14, left: 14, borderWidth: '2px 0 0 2px', borderTopLeftRadius: 6 }}/>
      <div style={{ ...bracket, top: 14, right: 14, borderWidth: '2px 2px 0 0', borderTopRightRadius: 6 }}/>
      <div style={{ ...bracket, bottom: 14, left: 14, borderWidth: '0 0 2px 2px', borderBottomLeftRadius: 6 }}/>
      <div style={{ ...bracket, bottom: 14, right: 14, borderWidth: '0 2px 2px 0', borderBottomRightRadius: 6 }}/>
      <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', color: captured ? 'rgba(255,255,255,0.85)' : 'var(--amber-500)' }}>
        <div style={{ opacity: captured ? 0.85 : 0.5 }}><MouthGuide type={type}/></div>
      </div>
    </div>
  );
}

// ─── Status ring (composed — kit has no check-circle / alert-circle) ────
function StatusRing({ pass }) {
  return (
    <div style={{
      width: 44, height: 44, borderRadius: '50%', flexShrink: 0,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      background: pass ? 'var(--sage-50)' : 'var(--amber-50)',
      color: pass ? 'var(--sage-600)' : 'var(--clay-500)',
    }}>
      {pass ? <Icon name="check" size={24} strokeWidth={2.5}/> : (
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round">
          <line x1="12" y1="7" x2="12" y2="13"/><line x1="12" y1="17" x2="12" y2="17"/>
        </svg>
      )}
    </div>
  );
}

// ─── Shutter (iOS affordance, amber) ────────────────────────────────────
function Shutter({ onClick }) {
  const [p, setP] = React.useState(false);
  return (
    <button onClick={onClick} aria-label="Take photo"
      onPointerDown={() => setP(true)} onPointerUp={() => setP(false)} onPointerLeave={() => setP(false)}
      style={{
        width: 78, height: 78, borderRadius: '50%', cursor: 'pointer', padding: 0,
        background: 'transparent', border: '3px solid var(--stone-300)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
      <span style={{
        width: 60, height: 60, borderRadius: '50%', background: 'var(--amber-500)',
        boxShadow: 'var(--shadow-glow-amber)', transform: p ? 'scale(0.9)' : 'scale(1)',
        transition: 'transform 90ms var(--ease-out)',
      }}/>
    </button>
  );
}

function DevSkipPhoto({ onClick }) {
  return (
    <button onClick={onClick} style={{
      background: 'var(--stone-100)', border: '1px dashed var(--stone-400)', borderRadius: 'var(--radius-pill)',
      cursor: 'pointer', color: 'var(--stone-500)', padding: '6px 14px', whiteSpace: 'nowrap',
      font: 'var(--type-overline)', letterSpacing: 'var(--tracking-loose)', textTransform: 'uppercase',
    }}>DEV · skip photo</button>
  );
}

// ─── Top nav (back chevron only) ────────────────────────────────────────
function CapNav({ onBack }) {
  return (
    <div style={{ height: 44, flexShrink: 0, display: 'flex', alignItems: 'center', paddingLeft: 8, paddingTop: 52 }}>
      <button onClick={onBack} aria-label="Back" style={{ background: 'transparent', border: 0, cursor: 'pointer', color: 'var(--fg-1)', width: 40, height: 40, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <Icon name="chevron-left" size={26}/>
      </button>
    </div>
  );
}

function PhotoOverline({ i }) {
  return (
    <div style={{ font: 'var(--type-overline)', letterSpacing: 'var(--tracking-loose)', textTransform: 'uppercase' }}>
      <span style={{ color: 'var(--stone-400)' }}>Photo {i + 1} of 4 · </span>
      <span style={{ color: 'var(--amber-600)' }}>{PHOTOS[i].label}</span>
    </div>
  );
}

// ─── Intro ──────────────────────────────────────────────────────────────
function CaptureIntro({ onReady, onBack }) {
  return (
    <div style={{ position: 'absolute', inset: 0, background: 'var(--bg)', display: 'flex', flexDirection: 'column' }}>
      <CapNav onBack={onBack}/>
      <div style={{ flex: 1, padding: '6px var(--gutter-screen) 0', display: 'flex', flexDirection: 'column' }}>
        <h1 style={{ font: 'var(--type-display-m)', color: 'var(--fg-1)', letterSpacing: 'var(--tracking-tight)', marginBottom: 12, textWrap: 'pretty' }}>Four photos. About 90 seconds.</h1>
        <p style={{ font: 'var(--type-body-l)', color: 'var(--fg-2)', textWrap: 'pretty', marginBottom: 26 }}>
          We’ll guide you through each one — point your phone at your mouth and follow the on-screen frame.
        </p>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          {PHOTOS.map((p, i) => (
            <Card key={p.key} padding={14} style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                <span style={{ font: 'var(--type-overline)', letterSpacing: 'var(--tracking-loose)', color: 'var(--stone-400)' }}>{i + 1}</span>
              </div>
              <div style={{ height: 64, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--amber-500)' }}>
                <MouthGuide type={p.key} size={104}/>
              </div>
              <div style={{ font: 'var(--type-label)', color: 'var(--fg-1)' }}>{p.label}</div>
            </Card>
          ))}
        </div>
      </div>
      <div style={{ flexShrink: 0, padding: '12px var(--gutter-screen) 38px' }}>
        <Button full variant="primary" onClick={onReady}>I’m ready</Button>
      </div>
    </div>
  );
}

// ─── Capture screen ─────────────────────────────────────────────────────
function CaptureScreen({ i, onShutter, onDevSkip, onBack }) {
  return (
    <div style={{ position: 'absolute', inset: 0, background: 'var(--bg)', display: 'flex', flexDirection: 'column' }}>
      <CapNav onBack={onBack}/>
      <div style={{ padding: '4px var(--gutter-screen) 14px' }}>
        <PhotoOverline i={i}/>
        <p style={{ font: 'var(--type-body)', color: 'var(--fg-2)', marginTop: 8, textWrap: 'pretty' }}>{PHOTOS[i].instruction}</p>
      </div>
      <Viewfinder type={PHOTOS[i].key} style={{ flex: 1, margin: '0 16px' }}/>
      <div style={{ flexShrink: 0, padding: '18px 0 30px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14 }}>
        <Shutter onClick={onShutter}/>
        {CAP_DEV_TOOLS && <DevSkipPhoto onClick={onDevSkip}/>}
      </div>
    </div>
  );
}

// ─── Review screen ──────────────────────────────────────────────────────
function ReviewScreen({ i, pass, onContinue, onRetake, onBack }) {
  return (
    <div style={{ position: 'absolute', inset: 0, background: 'var(--bg)', display: 'flex', flexDirection: 'column' }}>
      <CapNav onBack={onBack}/>
      <div style={{ padding: '4px var(--gutter-screen) 12px' }}>
        <PhotoOverline i={i}/>
      </div>
      <div style={{ flex: 1, padding: '0 var(--gutter-screen)', display: 'flex', flexDirection: 'column', minHeight: 0 }}>
        <Viewfinder type={PHOTOS[i].key} captured style={{ flex: 1, minHeight: 0 }}/>
        <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12, padding: '18px 2px 0' }}>
          <StatusRing pass={pass}/>
          <div style={{ flex: 1 }}>
            <div style={{ font: 'var(--type-h3)', color: 'var(--fg-1)', textWrap: 'pretty' }}>
              {pass ? 'Looks good.' : 'That photo was a little blurry — let’s try once more.'}
            </div>
            <div style={{ font: 'var(--type-body-s)', color: 'var(--fg-3)', marginTop: 3 }}>
              {pass ? (i < 3 ? 'On to the next photo.' : 'That’s the last one.') : 'Hold steady and keep your mouth in the frame.'}
            </div>
          </div>
        </div>
      </div>
      <div style={{ flexShrink: 0, padding: '14px var(--gutter-screen) 38px' }}>
        {pass
          ? <Button full variant="primary" onClick={onContinue}>{i < 3 ? 'Continue' : 'Review all four'}</Button>
          : <Button full variant="primary" leftIcon="camera" onClick={onRetake}>Retake</Button>}
      </div>
    </div>
  );
}

// ─── Summary ────────────────────────────────────────────────────────────
function CaptureSummary({ onStart, onBack }) {
  return (
    <div style={{ position: 'absolute', inset: 0, background: 'var(--bg)', display: 'flex', flexDirection: 'column' }}>
      <CapNav onBack={onBack}/>
      <div style={{ padding: '4px var(--gutter-screen) 0' }}>
        <h1 style={{ font: 'var(--type-display-m)', color: 'var(--fg-1)', letterSpacing: 'var(--tracking-tight)', marginBottom: 10 }}>Four photos in.</h1>
        <p style={{ font: 'var(--type-body-l)', color: 'var(--fg-2)', textWrap: 'pretty' }}>We’ll analyse them now.</p>
      </div>
      <div style={{ flex: 1, padding: '22px var(--gutter-screen) 0' }}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          {PHOTOS.map(p => (
            <div key={p.key} style={{ position: 'relative' }}>
              <Viewfinder type={p.key} captured style={{ height: 120 }}/>
              <div style={{ position: 'absolute', top: 8, right: 8, width: 26, height: 26, borderRadius: '50%', background: 'var(--sage-500)', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: 'var(--shadow-s)' }}>
                <Icon name="check" size={16} strokeWidth={3}/>
              </div>
              <div style={{ font: 'var(--type-caption)', color: 'var(--fg-3)', marginTop: 6 }}>{p.label}</div>
            </div>
          ))}
        </div>
      </div>
      <div style={{ flexShrink: 0, padding: '12px var(--gutter-screen) 38px' }}>
        <Button full variant="primary" glow rightIcon="arrow-right" onClick={onStart}>Start analysis</Button>
      </div>
    </div>
  );
}

// ─── AI processing (breathing pulse + rotating status lines, no bar) ────
function AIProcessing({ onDone }) {
  const LINES = [
    'Reading gingival features…',
    'Checking for plaque and recession…',
    'Cross-referencing your health profile…',
    'Computing your risk score…',
  ];
  const [li, setLi] = React.useState(0);
  const tapRef = React.useRef([]);
  const doneRef = React.useRef(null);
  React.useEffect(() => {
    const iv = setInterval(() => setLi(x => Math.min(x + 1, LINES.length - 1)), 2200);
    doneRef.current = setTimeout(onDone, 9200);
    return () => { clearInterval(iv); clearTimeout(doneRef.current); };
  }, []);
  // DEV: triple-tap the pulse to fast-forward to 1s (skip the wait on repeat demos)
  const onPulseTap = () => {
    const now = Date.now();
    tapRef.current = [...tapRef.current.filter(t => now - t < 600), now];
    if (tapRef.current.length >= 3) {
      tapRef.current = [];
      clearTimeout(doneRef.current);
      doneRef.current = setTimeout(onDone, 1000);
    }
  };
  return (
    <div style={{ position: 'absolute', inset: 0, background: 'var(--bg)', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '0 var(--gutter-screen)', textAlign: 'center' }}>
      <div onClick={onPulseTap} style={{ position: 'relative', width: 128, height: 128, marginBottom: 36, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
        <div style={{ position: 'absolute', inset: 0, borderRadius: '50%', background: 'var(--amber-100)', animation: 'mh-breathe 2.4s var(--ease-in-out) infinite' }}/>
        <div style={{ position: 'absolute', inset: 24, borderRadius: '50%', background: 'var(--amber-50)', animation: 'mh-breathe 2.4s var(--ease-in-out) infinite 0.3s' }}/>
        <div style={{ position: 'relative', color: 'var(--amber-600)' }}><Icon name="sparkles" size={36} strokeWidth={1.6}/></div>
      </div>
      <h2 style={{ font: 'var(--type-display-s)', color: 'var(--fg-1)', letterSpacing: 'var(--tracking-snug)', marginBottom: 12 }}>Reading your photos</h2>
      <p style={{ font: 'var(--type-body-l)', color: 'var(--fg-2)', maxWidth: 300, textWrap: 'pretty', marginBottom: 26 }}>
        We’re matching your photos against 2.4 million patterns. About 30 seconds.
      </p>
      <div key={li} style={{ font: 'var(--type-body)', color: 'var(--fg-3)', animation: 'mh-fadeup 0.5s var(--ease-out) both', minHeight: 24 }}>
        {LINES[li]}
      </div>
    </div>
  );
}

// ─── Controller (history-stack so Back & Retake stay coherent) ──────────
function CaptureFlow({ onComplete, onBack, initHist }) {
  const [hist, setHist] = React.useState(initHist || ['intro']);
  const [dir, setDir] = React.useState(1);
  const [attempts, setAttempts] = React.useState({});
  const frame = hist[hist.length - 1];

  const push = (next) => { setDir(1); setHist(h => [...h, next]); };
  const back = () => {
    if (hist.length > 1) { setDir(-1); setHist(h => h.slice(0, -1)); }
    else onBack && onBack();
  };
  const passed = (i) => i !== FAIL_INDEX || (attempts[i] || 0) >= 2;

  const shutter = (i) => { setAttempts(a => ({ ...a, [i]: (a[i] || 0) + 1 })); push('rev-' + i); };
  const afterReview = (i) => { if (i < 3) push('cap-' + (i + 1)); else push('summary'); };
  const retake = (i) => push('cap-' + i);
  const devSkip = (i) => { setAttempts(a => ({ ...a, [i]: 2 })); afterReview(i); }; // auto-pass + advance

  const render = (key) => {
    if (key === 'intro') return <CaptureIntro onReady={() => push('cap-0')} onBack={onBack}/>;
    if (key === 'summary') return <CaptureSummary onStart={() => push('processing')} onBack={back}/>;
    if (key === 'processing') return <AIProcessing onDone={onComplete}/>;
    const m = key.match(/^(cap|rev)-(\d+)$/);
    if (m) {
      const i = Number(m[2]);
      if (m[1] === 'cap') return <CaptureScreen i={i} onShutter={() => shutter(i)} onDevSkip={() => devSkip(i)} onBack={back}/>;
      return <ReviewScreen i={i} pass={passed(i)} onContinue={() => afterReview(i)} onRetake={() => retake(i)} onBack={back}/>;
    }
    return null;
  };

  return (
    <div style={{ position: 'absolute', inset: 0, overflow: 'hidden' }}>
      <CapStage activeKey={frame} direction={dir} render={render}/>
    </div>
  );
}

window.MunaCapture = { CaptureFlow };
