// bodycheck.jsx — Body Camera / Body Check (optional, private, no-shame)
const { useState: useStateBC, useEffect: useEffectBC } = React;

function BodyCheck({ initial, exit, startQuest }) {
  const [step, setStep] = useStateBC(initial || 'history');
  const [snapshot, setSnapshot] = useStateBC(null);
  const go = (s, payload) => { if (payload !== undefined) setSnapshot(payload); setStep(s); };
  const map = {
    history: <BCHistory go={go} exit={exit}/>,
    guide: <BCGuide go={go} exit={exit}/>,
    capture: <BCCapture go={go}/>,
    analyzing: <BCAnalyzing go={go} exit={exit} snapshot={snapshot}/>,
    result: <BCResult go={go} exit={exit} startQuest={startQuest} snapshot={snapshot}/>,
    fallback: <BCFallback go={go} exit={exit}/>,
    privacy: <BCPrivacy go={go} exit={exit}/>,
  };
  return map[step];
}

// ── Chronicle: timeline of past body snapshots ─────────────
function BCHistory({ go, exit }) {
  const entries = [
    { date: '오늘', rel: '방금', label: '체크하기', today: true },
    { date: '5월 25일', rel: '1주 전', tags: [['상체 정렬', T.teal], ['긴장도', T.violet]], note: '상체가 한결 편해졌어요' },
    { date: '5월 18일', rel: '2주 전', tags: [['움직임 준비도', T.calm]], note: '꾸준함이 보이기 시작했어요' },
    { date: '5월 4일', rel: '4주 전', tags: [['첫 기록', T.coral]], note: '첫 Body Check를 남겼어요' },
  ];
  return (
    <Screen bg={T.surface}>
      <TopBar title="바디 체크" onBack={exit}/>
      <AvaSays size={42} style={{ marginBottom: 18 }}>지금까지의 변화예요. 점수가 아니라 ‘방향’만 기록해요.</AvaSays>

      {/* chronicle timeline */}
      <div style={{ paddingLeft: 2 }}>
        {entries.map((e, i) => {
          const first = i === 0, last = i === entries.length - 1;
          return (
            <div key={i} style={{ display: 'flex', gap: 14, position: 'relative' }}>
              <div style={{ position: 'relative', width: 30, flexShrink: 0, display: 'flex', justifyContent: 'center' }}>
                {!first && <div style={{ position: 'absolute', top: -10, height: 48, width: 3, borderRadius: 2, background: T.line2 }}/>}
                {!last && <div style={{ position: 'absolute', top: 38, bottom: -10, width: 3, borderRadius: 2, background: T.line2 }}/>}
                <div style={{ position: 'absolute', top: 26, width: e.today ? 28 : 18, height: e.today ? 28 : 18, borderRadius: '50%', background: e.today ? T.teal : T.surface2, boxShadow: e.today ? `0 3px 0 ${T.tealDark}` : 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', border: e.today ? 'none' : `2.5px solid ${T.bg}` }}>
                  {e.today && <Icon name="scan" size={15} color="#fff" sw={2}/>}
                </div>
              </div>
              {e.today ? (
                <button onClick={() => go('guide')} style={{ flex: 1, textAlign: 'left', border: 'none', cursor: 'pointer', fontFamily: 'inherit', background: T.bg, borderRadius: 20, padding: 16, marginBottom: 12, boxShadow: `0 0 0 2px ${T.teal}, 0 10px 24px ${T.teal}22`, display: 'flex', alignItems: 'center', gap: 12 }}>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 11, fontWeight: 800, color: T.tealDark, letterSpacing: 0.5 }}>오늘</div>
                    <div style={{ fontSize: 17, fontWeight: 800, color: T.ink, letterSpacing: -0.3, marginTop: 1 }}>지금 바디 체크 하기</div>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6, background: T.teal, color: '#fff', borderRadius: 12, padding: '9px 14px', fontSize: 13.5, fontWeight: 800, boxShadow: `0 3px 0 ${T.tealDark}` }}>체크<Icon name="arrow" size={14} color="#fff" sw={2.4}/></div>
                </button>
              ) : (
                <div style={{ flex: 1, background: T.bg, borderRadius: 20, padding: 16, marginBottom: 12, boxShadow: '0 2px 8px rgba(0,0,0,0.05)' }}>
                  <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 8 }}>
                    <span style={{ fontSize: 15.5, fontWeight: 800, color: T.ink }}>{e.date}</span>
                    <span style={{ fontSize: 12, fontWeight: 700, color: T.ink3 }}>{e.rel}</span>
                  </div>
                  <div style={{ fontSize: 14, color: T.ink2, fontWeight: 500, marginBottom: 10 }}>{e.note}</div>
                  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                    {e.tags.map((t, k) => (
                      <span key={k} style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '5px 10px', borderRadius: 9, background: `${t[1]}1a`, fontSize: 12.5, fontWeight: 700, color: t[1] }}><span style={{ width: 6, height: 6, borderRadius: 999, background: t[1] }}/>{t[0]}</span>
                    ))}
                  </div>
                </div>
              )}
            </div>
          );
        })}
      </div>

      <button onClick={() => go('privacy')} style={{ display: 'block', margin: '8px auto 4px', background: 'none', border: 'none', color: T.ink3, fontSize: 13, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', textDecoration: 'underline' }}>데이터 관리 · 삭제</button>
      <div style={{ height: 12 }}/>
    </Screen>
  );
}

function BCGuide({ go, exit }) {
  return (
    <Screen bg={T.bg}>
      <TopBar title="촬영 가이드" onBack={() => go('history')}/>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginBottom: 8 }}>
        {[['밝은 곳에 서주세요', 'sparkle'], ['휴대폰을 수평으로 세워주세요', 'cameraline'], ['가능하면 머리부터 발까지', 'scan'], ['편한 운동복이면 충분해요', 'check']].map((g, i) => (
          <Card key={i} pad={16} style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
            <div style={{ width: 30, height: 30, borderRadius: 999, background: T.calmSoft, color: T.calm, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 14, fontWeight: 800, flexShrink: 0 }}>{i + 1}</div>
            <span style={{ flex: 1, fontSize: 16, fontWeight: 600, color: T.ink }}>{g[0]}</span>
            <Icon name={g[1]} size={20} color={T.ink3} sw={2}/>
          </Card>
        ))}
      </div>
      <div style={{ fontSize: 13.5, color: T.ink3, textAlign: 'center', fontWeight: 600, marginTop: 14 }}>전신이 부담스럽다면 상반신 체크만 해도 괜찮아요.</div>
      <FloatCTA>
        <Btn variant="calm" onClick={() => go('capture')} icon={<Icon name="cameraline" size={19} color="#fff"/>}>정면 촬영 시작</Btn>
        <Btn variant="soft" size="md" style={{ marginTop: 8 }} onClick={() => go('capture')}>상반신만 체크</Btn>
        <Btn variant="ghost" size="sm" style={{ marginTop: 2 }} onClick={exit}>오늘은 건너뛰기</Btn>
      </FloatCTA>
    </Screen>
  );
}

function BCCapture({ go }) {
  const [count, setCount] = useStateBC(null);
  const [frame, setFrame] = useStateBC(null);
  useEffectBC(() => {
    if (count === null) return;
    if (count === 0) {
      const captured = window.FitbodyCamera ? window.FitbodyCamera.captureFrame('body_check') : frame;
      if (captured && captured.ok) setFrame(captured);
      const t = setTimeout(() => go('analyzing', captured || frame), 400);
      return () => clearTimeout(t);
    }
    const t = setTimeout(() => setCount(c => c - 1), 800);
    return () => clearTimeout(t);
  }, [count]);
  return (
    <div style={{ position: 'absolute', inset: 0, background: T.ink, display: 'flex', flexDirection: 'column' }}>
      <StatusBar light/>
      <div style={{ padding: '54px 22px 0' }}><TopBar title="바디 체크" light transparent onBack={() => go('guide')}/></div>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', padding: '8px 22px 0' }}>
        <div style={{ position: 'relative', flex: 1, display: 'flex' }}>
          <CameraView label="BODY CHECK" tint={T.calm} onFrame={setFrame}/>
          {count > 0 && <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}><div key={count} style={{ fontSize: 110, fontWeight: 800, color: '#fff', animation: 'popNum .6s ease' }}>{count}</div></div>}
        </div>
        <div style={{ padding: '16px 2px 0', display: 'flex', flexDirection: 'column', gap: 9 }}>
          {[['조명', cameraBrightnessLabel(frame), frame && frame.ok && frame.brightness >= 45 && frame.brightness <= 215], ['화면 안정도', cameraStabilityLabel(frame), frame && frame.ok && frame.motion <= 18], ['자세 구분', cameraContrastLabel(frame), frame && frame.ok && frame.contrast >= 18]].map((c, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <div style={{ width: 22, height: 22, borderRadius: 999, background: c[2] ? T.calm : 'rgba(255,255,255,0.15)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                <Icon name={c[2] ? 'check' : 'arrow'} size={13} color="#fff" sw={2.6}/>
              </div>
              <span style={{ fontSize: 14.5, color: c[2] ? '#fff' : 'rgba(255,255,255,0.7)', fontWeight: 500 }}>{c[0]} · {c[1]}</span>
            </div>
          ))}
        </div>
      </div>
      <div style={{ padding: '16px 22px 32px' }}>
        <Btn variant="calm" onClick={() => setCount(3)} disabled={count !== null}>{count !== null ? '촬영 중…' : '3초 타이머 촬영'}</Btn>
      </div>
    </div>
  );
}

function BCAnalyzing({ go, exit, snapshot }) {
  useEffectBC(() => {
    const frame = snapshot && snapshot.ok ? snapshot : (window.FitbodyCamera && window.FitbodyCamera.latest && window.FitbodyCamera.latest());
    const report = buildBodyCheckReport(frame);
    if (window.FitbodyBackend) window.FitbodyBackend.recordBodyCheck(report).catch(() => {});
    const t = setTimeout(() => go('result', report), 2300);
    return () => clearTimeout(t);
  }, []);
  return (
    <div style={{ position: 'absolute', inset: 0, background: T.surface, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '0 40px', textAlign: 'center' }}>
      <StatusBar/>
      <AvaOrb size={72} speaking/>
      <h1 style={{ fontSize: 22, fontWeight: 800, color: T.ink, letterSpacing: -0.4, margin: '26px 0 8px' }}>체크 중이에요</h1>
      <p style={{ fontSize: 15, color: T.ink2, lineHeight: 1.5, maxWidth: 280, margin: '0 0 26px' }}>사진을 평가하는 게 아니라, 자세와 움직임 신호를 확인하고 있어요.</p>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10, alignItems: 'flex-start' }}>
        {['촬영 안정도 확인', '기기 내 프레임 신호 분석', '이번 주 Quest와 연결'].map((s, i) => (
          <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 9, fontSize: 14, color: T.ink2, fontWeight: 600 }}>
            <span style={{ width: 7, height: 7, borderRadius: 999, background: T.calm, animation: `avaGlow 1.2s ${i * 0.3}s ease-in-out infinite` }}/>{s}
          </div>
        ))}
      </div>
      <button onClick={exit} style={{ position: 'absolute', bottom: 40, background: 'none', border: 'none', color: T.ink3, fontSize: 13.5, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' }}>중단하고 삭제</button>
    </div>
  );
}

function BCResultRow({ label, value, tone }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '14px 16px', background: T.bg, borderRadius: 16 }}>
      <span style={{ fontSize: 15.5, fontWeight: 700, color: T.ink }}>{label}</span>
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '5px 12px', borderRadius: 999, background: tone === T.ink3 ? T.surface2 : T.calmSoft, fontSize: 13.5, fontWeight: 700, color: tone }}>{value}</span>
    </div>
  );
}

function buildBodyCheckReport(frame) {
  const usable = frame && frame.ok;
  const stable = usable && frame.motion <= 18;
  const lit = usable && frame.brightness >= 45 && frame.brightness <= 215;
  const clear = usable && frame.contrast >= 18;
  return {
    id: `bc-${Date.now().toString(36)}`,
    capturedAt: (frame && frame.capturedAt) || new Date().toISOString(),
    frame: usable ? { brightness: frame.brightness, contrast: frame.contrast, motion: frame.motion, width: frame.width, height: frame.height } : null,
    upperAlignment: clear && stable ? '안정적인 편' : clear ? '확인 가능' : '참고용',
    pelvisBalance: usable ? '오늘은 참고용' : '분석 불가',
    readiness: lit && stable ? '좋음' : lit ? '보통' : '조명 확인',
    recommendation: stable ? '흉추 열기' : '회복 호흡',
  };
}

function BCResult({ go, exit, startQuest, snapshot }) {
  const report = snapshot && snapshot.recommendation ? snapshot : buildBodyCheckReport(snapshot);
  const quest = report.recommendation === '회복 호흡'
    ? { title: '회복 호흡', seconds: 60, tone: T.calm, steps: ['편하게 앉아요', '천천히 들이마셔요', '길게 내쉬어요'], avaLine: '오늘은 안정적인 호흡부터 시작해요', xp: 12 }
    : { title: '흉추 열기', seconds: 180, tone: T.calm, steps: ['네발 자세로 앉아요', '한 손을 머리 뒤에 대요', '천천히 가슴을 열어요'], avaLine: '깊이보다 방향이 중요해요', xp: 25 };
  return (
    <Screen bg={T.surface}>
      <TopBar title="오늘의 바디 스냅샷" onBack={exit}/>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginBottom: 14 }}>
        <BCResultRow label="상체 정렬" value={report.upperAlignment} tone={report.upperAlignment === '참고용' ? T.ink3 : T.calm}/>
        <BCResultRow label="골반 균형" value={report.pelvisBalance} tone={T.ink3}/>
        <BCResultRow label="움직임 준비도" value={report.readiness} tone={report.readiness === '좋음' ? T.calm : T.ink3}/>
      </div>

      {/* weekly change — qualitative, no scores */}
      <Card pad={18} style={{ marginBottom: 14 }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
          <span style={{ fontSize: 12, fontWeight: 800, color: T.ink3, letterSpacing: 0.5 }}>지난주와 비교</span>
          <span style={{ fontSize: 12, fontWeight: 700, color: T.ink3 }}>5월 18일 → 오늘</span>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {[['상체 정렬', '조금 더 편해졌어요', T.teal, 'up'], ['움직임 준비도', '비슷해요', T.ink3, 'same'], ['긴장도', '약간 줄었어요', T.violet, 'up']].map((r, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 11 }}>
              <div style={{ width: 30, height: 30, borderRadius: 9, background: r[3] === 'same' ? T.surface2 : `${r[2]}1f`, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                <Icon name={r[3] === 'up' ? 'arrow' : 'wind'} size={15} color={r[2]} sw={2.4} style={r[3] === 'up' ? { transform: 'rotate(-45deg)' } : {}}/>
              </div>
              <span style={{ flex: 1, fontSize: 14.5, fontWeight: 700, color: T.ink }}>{r[0]}</span>
              <span style={{ fontSize: 13.5, fontWeight: 700, color: r[2] }}>{r[1]}</span>
            </div>
          ))}
        </div>
        <div style={{ fontSize: 12, color: T.ink3, fontWeight: 600, marginTop: 14, lineHeight: 1.4 }}>점수가 아니라 ‘방향’만 봐요. 촬영 조건에 따라 달라질 수 있어요.</div>
      </Card>
      <Card pad={16} style={{ marginBottom: 14, display: 'flex', alignItems: 'flex-start', gap: 11 }}>
        <AvaOrb size={36} speaking/>
        <div style={{ fontSize: 14.5, color: T.ink, fontWeight: 500, lineHeight: 1.5 }}>오늘은 흉추를 가볍게 열고 시작하면 움직임이 더 편해질 수 있어요. 골반은 촬영 조건 영향이 있어 판단하지 않을게요.</div>
      </Card>
      <Card pad={18} style={{ marginBottom: 14, background: `linear-gradient(150deg, ${T.calmSoft}, ${T.bg})` }}>
        <div style={{ fontSize: 12, fontWeight: 800, color: T.calm, letterSpacing: 0.8, marginBottom: 4 }}>추천 QUEST</div>
        <div style={{ fontSize: 19, fontWeight: 800, color: T.ink, letterSpacing: -0.3, marginBottom: 14 }}>3분 흉추 열기</div>
        <Btn variant="calm" onClick={() => startQuest(quest)} icon={<Icon name="play" size={19} color="#fff"/>}>Quest 시작</Btn>
      </Card>
      <div style={{ display: 'flex', gap: 10 }}>
        <Btn variant="soft" size="md" style={{ flex: 1 }} onClick={exit}>결과 숨기기</Btn>
        <Btn variant="soft" size="md" style={{ flex: 1 }} onClick={() => go('privacy')}>데이터 삭제</Btn>
      </div>
      <button onClick={() => go('fallback')} style={{ display: 'block', margin: '16px auto 8px', background: 'none', border: 'none', color: T.ink3, fontSize: 13, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', textDecoration: 'underline' }}>이 결과가 불편하게 느껴졌어요</button>
      <div style={{ height: 8 }}/>
    </Screen>
  );
}

function BCFallback({ go, exit }) {
  return (
    <Screen bg={T.surface}>
      <TopBar title="" onBack={() => go('result')}/>
      <div style={{ textAlign: 'center', paddingTop: 12 }}>
        <AvaOrb size={60} speaking style={{ margin: '0 auto 20px' }}/>
        <h1 style={{ fontSize: 24, fontWeight: 800, color: T.ink, letterSpacing: -0.5, margin: '0 0 14px' }}>괜찮아요</h1>
      </div>
      <Card pad={16} style={{ marginBottom: 24, display: 'flex', alignItems: 'flex-start', gap: 11 }}>
        <div style={{ fontSize: 15, color: T.ink, fontWeight: 500, lineHeight: 1.55 }}>이 체크가 불편하게 느껴졌다면 지금은 결과를 보지 않아도 괜찮아요. Fitbody는 몸을 평가하지 않아요. 오늘은 컨디션과 회복 중심으로 도와드릴게요.</div>
      </Card>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        <Btn variant="calm" onClick={() => go('result')}>에너지 중심으로 보기</Btn>
        <Btn variant="soft" size="md" onClick={exit}>Body Check 잠시 끄기</Btn>
        <Btn variant="ghost" size="sm" onClick={() => go('privacy')}>사진·데이터 삭제하기</Btn>
      </div>
    </Screen>
  );
}

function BCPrivacy({ go, exit }) {
  const [s, setS] = useStateBC({ savePhoto: false, report: true, coach: true, train: false });
  const t = (k) => setS(c => ({ ...c, [k]: !c[k] }));
  return (
    <Screen bg={T.surface}>
      <TopBar title="데이터 관리" onBack={() => go('history')}/>
      <Card pad={0} style={{ marginBottom: 18 }}>
        <NotifToggle label="사진 저장" sub={s.savePhoto ? 'private vault에 저장' : '저장 안 함'} on={s.savePhoto} onToggle={() => t('savePhoto')}/>
        <NotifToggle label="자세 변화 기록" sub="리포트 생성용" on={s.report} onToggle={() => t('report')}/>
        <NotifToggle label="Ava 코칭에 사용" on={s.coach} onToggle={() => t('coach')}/>
        <div style={{ borderBottom: 'none' }}><NotifToggle label="모델 개선에 사용" sub="기본 꺼짐" on={s.train} onToggle={() => t('train')}/></div>
      </Card>
      <div style={{ fontSize: 13, fontWeight: 800, color: T.ink3, letterSpacing: 0.5, margin: '4px 2px 10px' }}>데이터 삭제</div>
      <Card pad={0} style={{ marginBottom: 16 }}>
        {[['사진 삭제', 'cameraline'], ['특정 기록 삭제', 'scan'], ['모든 바디 체크 데이터 삭제', 'close'], ['내 데이터 내보내기', 'share']].map((r, i, a) => (
          <button key={i} onClick={() => go('history')} style={{ display: 'flex', alignItems: 'center', gap: 14, width: '100%', textAlign: 'left', cursor: 'pointer', fontFamily: 'inherit', background: 'none', border: 'none', padding: '14px 16px', borderBottom: i < a.length - 1 ? `0.5px solid ${T.line}` : 'none' }}>
            <div style={{ width: 32, height: 32, borderRadius: 9, background: T.surface, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><Icon name={r[1]} size={17} color={i === 2 ? T.coralDark : T.ink2} sw={2}/></div>
            <span style={{ flex: 1, fontSize: 15.5, fontWeight: 600, color: i === 2 ? T.coralDark : T.ink }}>{r[0]}</span>
            <Icon name="chevron" size={16} color={T.ink3} sw={2.2}/>
          </button>
        ))}
      </Card>
      <div style={{ fontSize: 12.5, color: T.ink3, fontWeight: 600, lineHeight: 1.5, padding: '0 4px' }}>삭제해도 Quest, XP, Streak는 유지돼요. 바디 체크 데이터만 삭제됩니다.</div>
      <div style={{ height: 12 }}/>
    </Screen>
  );
}

Object.assign(window, { BodyCheck });
