// p07-search.jsx, p08-newcollection.jsx, p09-processing.jsx
// Combined to one file — small screens

// ─── P07 Search ─────────────────────────────────────────────
function ScreenSearch({ state, onNavigate, user }) {
  const T = window.T;
  const offline = state === 'offline';
  const initial = state === 'results' ? '주문' : (state === 'empty' ? '없는단어' : '');
  const [q, setQ] = React.useState(initial);

  // Sync with URL-driven state changes (DevPanel state toggles) — useState's
  // initial value is read once at mount, so without this the q text wouldn't
  // refresh when the user clicks "results" / "empty" / "default" in the panel.
  React.useEffect(() => {
    setQ(state === 'results' ? '주문' : (state === 'empty' ? '없는단어' : ''));
  }, [state]);

  const all = window.MOCK_SEEDS;
  const results = q.trim() === '' ? [] : all.filter(s =>
    s.foreign.includes(q) || s.korean.includes(q) || (s.pron || '').includes(q)
  );

  // Highlight match in text
  const highlight = (text, query) => {
    if (!query) return text;
    const idx = text.indexOf(query);
    if (idx < 0) return text;
    return (
      <React.Fragment>
        {text.slice(0, idx)}
        <span style={{ color: T.accent, fontWeight: 700, background: T.accentSoft,
                       borderRadius: 3, padding: '0 2px' }}>{query}</span>
        {text.slice(idx + query.length)}
      </React.Fragment>
    );
  };

  return (
    <div style={{ position: 'absolute', inset: 0, background: T.bg,
                  display: 'flex', flexDirection: 'column' }}>
      {/* Header — matches P02 exactly so the search bar feels stationary */}
      <div style={{
        flexShrink: 0,
        padding: '8px 20px 6px',
        display: 'flex', alignItems: 'center', gap: 10,
      }}>
        <div style={{
          width: 36, height: 36, borderRadius: '50%',
          background: '#F2EBE0',
          overflow: 'hidden',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          flexShrink: 0,
          border: '0.5px solid rgba(60,42,20,0.10)',
        }}>
          <Hamster count={user?.todayPouch || 0} max={10} size={36} headOnly/>
        </div>
        <div style={{ flex: 1, fontSize: 18, fontWeight: 800, color: T.ink, letterSpacing: '-0.03em' }}>
          CheekPouch
        </div>
        {offline && <OfflineBadge/>}
      </div>

      {/* Search row — same vertical position as P02's clickable search bar */}
      <div style={{ padding: '6px 20px 14px', display: 'flex',
                    alignItems: 'center', gap: 8 }}>
        <div style={{ flex: 1 }}>
          <SearchBar value={q} onChange={setQ} autoFocus
                     placeholder="한국어 또는 외국어로 검색해보세요"/>
        </div>
        <button onClick={() => onNavigate('back')} style={{
          background: 'transparent', border: 'none',
          color: T.accent, fontSize: 14.5, fontWeight: 600,
          padding: '0 4px', fontFamily: 'inherit', cursor: 'pointer',
        }}>취소</button>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 20px 24px' }}>
        {q.trim() === '' ? (
          <div style={{ padding: '24px 0', textAlign: 'center' }}>
            <div style={{ fontSize: 13.5, color: T.ink3, lineHeight: 1.6 }}>
              표현 · 단어 · 주머니 이름으로<br/>빠르게 찾을 수 있어요
            </div>
          </div>
        ) : results.length === 0 ? (
          <EmptyState
            icon={<Icons.Search size={42} color={T.ink3}/>}
            title={`'${q}'에 맞는 씨앗이 없어요`}
            message="다른 단어로 다시 검색해보세요"
          />
        ) : (
          <React.Fragment>
            <div style={{ fontSize: 12, color: T.ink3, padding: '8px 0' }}>
              {results.length}개의 결과
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {results.map(s => (
                <div key={s.id} onClick={() => onNavigate('P05', { seedId: s.id })}
                     style={{
                       background: T.surface, borderRadius: 14,
                       border: `0.5px solid ${T.hairline}`,
                       padding: 14, cursor: 'pointer',
                     }}>
                  <div style={{ fontSize: 10.5, fontWeight: 700, color: T.ink3,
                                letterSpacing: '0.08em', textTransform: 'uppercase',
                                marginBottom: 6 }}>{s.langLabel}</div>
                  <div style={{ fontSize: 16, fontWeight: 600, color: T.ink,
                                letterSpacing: '-0.01em', marginBottom: 4 }}>
                    {highlight(s.foreign, q)}
                  </div>
                  <div style={{ fontSize: 13, color: T.ink2 }}>
                    {highlight(s.korean, q)}
                  </div>
                </div>
              ))}
            </div>
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

// ─── P08 New Collection ─────────────────────────────────────
function ScreenNewCollection({ onNavigate }) {
  const T = window.T;
  const [name, setName] = React.useState('');
  const [color, setColor] = React.useState('pouchA');
  const [cover, setCover] = React.useState('auto');
  const [coverIcon, setCoverIcon] = React.useState('Plane');
  const [coverPhoto, setCoverPhoto] = React.useState(null);
  const colors = ['pouchA', 'pouchB', 'pouchC', 'pouchD', 'pouchE', 'pouchF'];
  const iconChoices = ['Plane','Heart2','Sparkle','Bag','Globe','Sun','Mascot','Bookmark'];
  // Only use icons that actually exist
  const validIcons = iconChoices.filter(k => Icons[k]);
  const fileRef = React.useRef(null);

  const onPickPhoto = (e) => {
    const f = e.target.files && e.target.files[0];
    if (!f) return;
    const reader = new FileReader();
    reader.onload = (ev) => setCoverPhoto(ev.target.result);
    reader.readAsDataURL(f);
  };

  return (
    <div style={{ position: 'absolute', inset: 0, background: T.bg,
                  display: 'flex', flexDirection: 'column' }}>
      <TopBar title="새 주머니"
        leading={<IconButton icon={<Icons.Back size={22} color={T.ink}/>}
                             onClick={() => onNavigate('back')}/>}
        trailing={
          <button onClick={() => onNavigate('back')}
                  disabled={!name.trim()}
                  style={{
            background: 'transparent', border: 'none',
            color: name.trim() ? T.accent : T.ink3,
            fontSize: 15, fontWeight: 700, padding: '0 4px',
            fontFamily: 'inherit', cursor: 'pointer',
          }}>완료</button>
        }
      />

      <div style={{ flex: 1, overflowY: 'auto', padding: '4px 20px 24px' }}>
        {/* Live preview */}
        <div style={{ display: 'flex', justifyContent: 'center', padding: '14px 0 26px' }}>
          <div style={{ width: 156, transform: 'scale(1.1)' }}>
            <PouchCard pouch={{
              name: name || '주머니 이름',
              color, seedIds: [],
              coverIcon: cover === 'icon' ? coverIcon : null,
              coverPhoto: cover === 'photo' ? coverPhoto : null,
            }}/>
          </div>
        </div>

        <div style={{ marginBottom: 22 }}>
          <div style={{ fontSize: 11.5, fontWeight: 700, color: T.ink3,
                        letterSpacing: '0.08em', textTransform: 'uppercase',
                        marginBottom: 10 }}>이름</div>
          <input value={name} onChange={e => setName(e.target.value.slice(0, 30))}
                 placeholder="예) 도쿄 5일"
                 autoFocus
                 style={{
                   width: '100%', height: 52,
                   background: T.surface, border: `0.5px solid ${T.hairline}`,
                   borderRadius: 14, padding: '0 14px',
                   fontSize: 16, color: T.ink, fontFamily: 'inherit',
                   outline: 'none', letterSpacing: '-0.01em',
                 }}/>
          <div style={{ fontSize: 11.5, color: T.ink3, padding: '6px 4px 0', textAlign: 'right' }}>
            {name.length}/30
          </div>
        </div>

        <div style={{ marginBottom: 22 }}>
          <div style={{ fontSize: 11.5, fontWeight: 700, color: T.ink3,
                        letterSpacing: '0.08em', textTransform: 'uppercase',
                        marginBottom: 10 }}>색상</div>
          <div style={{ display: 'flex', gap: 10, justifyContent: 'space-between' }}>
            {colors.map(c => (
              <button key={c} onClick={() => setColor(c)} style={{
                width: 44, height: 44, borderRadius: '50%',
                background: T[c], border: 'none',
                padding: 0, cursor: 'pointer',
                outline: color === c ? `2.5px solid ${T.ink}` : 'none',
                outlineOffset: 2,
                transition: 'transform .12s',
                transform: color === c ? 'scale(1.05)' : 'scale(1)',
              }}/>
            ))}
          </div>
        </div>

        <div>
          <div style={{ fontSize: 11.5, fontWeight: 700, color: T.ink3,
                        letterSpacing: '0.08em', textTransform: 'uppercase',
                        marginBottom: 10 }}>표지</div>
          <Segment options={[
            { value: 'auto', label: '자동' },
            { value: 'icon', label: '아이콘' },
            { value: 'photo', label: '사진' },
          ]} value={cover} onChange={setCover}/>

          {cover === 'auto' && (
            <div style={{ fontSize: 12.5, color: T.ink3, padding: '12px 2px 0', lineHeight: 1.5 }}>
              주머니에 담긴 씨앗의 언어로 자동 표시돼요
            </div>
          )}

          {cover === 'icon' && (
            <div style={{ marginTop: 14, display: 'grid',
                          gridTemplateColumns: 'repeat(6, 1fr)', gap: 8 }}>
              {validIcons.map(key => {
                const IconCmp = Icons[key];
                const selected = coverIcon === key;
                return (
                  <button key={key} onClick={() => setCoverIcon(key)} style={{
                    aspectRatio: '1 / 1',
                    background: selected ? T[color] : T.surface,
                    border: `0.5px solid ${selected ? T.ink : T.hairline}`,
                    borderRadius: 12, padding: 0, cursor: 'pointer',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    outline: selected ? `2px solid ${T.ink}` : 'none',
                    outlineOffset: 1,
                    transition: 'background .12s',
                  }}>
                    <IconCmp size={22} color={selected ? '#FFF' : T.ink2}/>
                  </button>
                );
              })}
            </div>
          )}

          {cover === 'photo' && (
            <div style={{ marginTop: 14 }}>
              <input ref={fileRef} type="file" accept="image/*"
                     onChange={onPickPhoto}
                     style={{ display: 'none' }}/>
              {coverPhoto ? (
                <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
                  <div style={{
                    width: 72, height: 72, borderRadius: 12,
                    background: `center/cover no-repeat url(${coverPhoto})`,
                    border: `0.5px solid ${T.hairline}`,
                    flexShrink: 0,
                  }}/>
                  <div style={{ flex: 1, display: 'flex', gap: 8 }}>
                    <Button kind="secondary" size="sm"
                            onClick={() => fileRef.current && fileRef.current.click()}>
                      변경
                    </Button>
                    <Button kind="ghost" size="sm"
                            onClick={() => setCoverPhoto(null)}>
                      삭제
                    </Button>
                  </div>
                </div>
              ) : (
                <button onClick={() => fileRef.current && fileRef.current.click()} style={{
                  width: '100%', height: 96,
                  background: T.surface,
                  border: `1px dashed ${T.hairline2 || T.hairline}`,
                  borderRadius: 14, padding: 0, cursor: 'pointer',
                  display: 'flex', flexDirection: 'column',
                  alignItems: 'center', justifyContent: 'center', gap: 6,
                  fontFamily: 'inherit',
                }}>
                  <Icons.Image size={22} color={T.ink3}/>
                  <div style={{ fontSize: 13, color: T.ink2, fontWeight: 500 }}>
                    사진 추가하기
                  </div>
                  <div style={{ fontSize: 11, color: T.ink3 }}>
                    JPG · PNG · 정사각형 권장
                  </div>
                </button>
              )}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ─── P09 Processing ─────────────────────────────────────────
// Auto-advances to P10 (seed created confirmation) after ~2.4s when the
// processing succeeds. Error state stays on screen until the user taps
// 다시 시도 / 취소. Without this auto-advance, the flow was a dead end —
// the user landed on a spinner and never saw the result they just made.
function ScreenProcessing({ state, onNavigate }) {
  const T = window.T;
  const isMulti = state === 'multi';
  const isError = state === 'error';
  const count = isMulti ? 5 : 1;
  const [dotCount, setDotCount] = React.useState(0);

  React.useEffect(() => {
    if (isError) return;
    const t = setInterval(() => setDotCount(d => (d + 1) % 4), 400);
    return () => clearInterval(t);
  }, [isError]);

  // Auto-advance to P10 (seed-created confirmation). Preserve `multi` so
  // P10 can show "5개" vs "1개" copy.
  React.useEffect(() => {
    if (isError) return;
    const t = setTimeout(() => {
      onNavigate('P10', isMulti ? { state: 'multi' } : {});
    }, 2400);
    return () => clearTimeout(t);
  }, [isError, isMulti]);

  return (
    <div style={{ position: 'absolute', inset: 0, background: T.bg,
                  display: 'flex', flexDirection: 'column' }}>
      <TopBar leading={
        isError ? <IconButton icon={<Icons.Close size={22} color={T.ink}/>}
                              onClick={() => onNavigate('back')}/> : null
      }/>

      <div style={{ flex: 1,
                    display: 'flex', flexDirection: 'column',
                    alignItems: 'center', justifyContent: 'center',
                    padding: '0 24px', textAlign: 'center' }}>
        {isError ? (
          <React.Fragment>
            <div style={{ width: 88, height: 88, borderRadius: '50%',
                          background: T.dangerSoft,
                          display: 'flex', alignItems: 'center', justifyContent: 'center',
                          marginBottom: 24 }}>
              <Icons.Warning size={44} color={T.danger}/>
            </div>
            <div style={{ fontSize: 21, fontWeight: 700, color: T.ink,
                          letterSpacing: '-0.025em', marginBottom: 8 }}>
              씨앗을 못 만들었어요
            </div>
            <div style={{ fontSize: 14, color: T.ink2,
                          lineHeight: 1.5, maxWidth: 280, marginBottom: 28 }}>
              잠시 후 다시 시도해볼까요?<br/>인터넷 연결을 확인해주세요.
            </div>
            <div style={{ display: 'flex', gap: 10 }}>
              <Button kind="secondary" onClick={() => onNavigate('back')}>취소</Button>
              <Button kind="primary" icon={<Icons.Refresh size={16} color="#FFF"/>}>
                다시 시도
              </Button>
            </div>
          </React.Fragment>
        ) : (
          <React.Fragment>
            <HamsterAnimated size={180}/>
            <div style={{
              fontSize: 21, fontWeight: 700, color: T.ink,
              letterSpacing: '-0.025em', marginTop: 26, marginBottom: 8,
            }}>
              {isMulti ? `${count}개 씨앗을 만드는 중` : '씨앗을 만드는 중'}
              <span style={{ color: T.accent, display: 'inline-block', width: 24, textAlign: 'left' }}>
                {'.'.repeat(dotCount)}
              </span>
            </div>
            <div style={{ fontSize: 13, color: T.ink3, lineHeight: 1.5 }}>
              보통 3초 안에 끝나요
            </div>
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

// ─── P10 Seed Created — confirmation ────────────────────────
// Shown right after P09 (만드는 중) succeeds. Lets the user *see* what
// was just created before deciding what to do next.
//
//   default → 1 seed card (large) + editable auto-categories
//   multi   → 5 seed cards stacked vertically + per-card chevron to detail
//
// Design decisions (per user feedback):
//   · Pouches are NEVER auto-assigned here. The user puts seeds into
//     pouches explicitly from P05 / P05b. A small hint reminds them.
//   · Categories ARE auto-set by AI (✨ badge). The user can fix any
//     wrong category right here — remove ×, add via "+ 추가" sheet.
function ScreenProcessed({ state, onNavigate }) {
  const T = window.T;
  const isMulti = state === 'multi';

  // Pretend the user just made these. In a real app, the freshly-created
  // ids would be passed in via navigate params; for the prototype we pick
  // recognisable seeds from the mock store so the visuals are honest.
  const allSeeds = window.MOCK_SEEDS || [];
  const created = isMulti
    ? allSeeds.slice(0, 5)
    : allSeeds.slice(0, 1);
  const first = created[0];
  const langSet = Array.from(new Set(created.map(s => s.langLabel)));

  // Categories — editable for single-seed flow. Seeded from AI-detected
  // categories on the seed. Track per-id whether it was AI-suggested so
  // we can show the ✨ badge only on those (user additions don't get it).
  const initialCats = (first.categories || []).slice(0, 4);
  const [cats, setCats] = React.useState(initialCats);
  const [autoSet] = React.useState(new Set(initialCats));
  const [pickerOpen, setPickerOpen] = React.useState(false);

  const allCats = window.__cpCats || window.MOCK_CATEGORIES || [];
  const catById = Object.fromEntries(allCats.map(c => [c.id, c]));

  const removeCat = (id) => setCats(cs => cs.filter(c => c !== id));
  const addCat    = (id) => setCats(cs => cs.includes(id) ? cs : [...cs, id]);

  return (
    <div style={{ position: 'absolute', inset: 0, background: T.bg,
                  display: 'flex', flexDirection: 'column' }}>
      <TopBar
        leading={<IconButton icon={<Icons.Close size={22} color={T.ink}/>}
                             onClick={() => onNavigate('P02')}/>}
      />

      <div style={{ flex: 1, overflowY: 'auto', padding: '8px 20px 20px',
                    display: 'flex', flexDirection: 'column' }}>
        {/* Success header */}
        <div style={{ textAlign: 'center', padding: '8px 0 18px' }}>
          <div style={{
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            width: 64, height: 64, borderRadius: '50%',
            background: T.accentSoft, color: T.accent,
            marginBottom: 14, position: 'relative',
            animation: 'cp-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both',
          }}>
            <Icons.Check size={32} color={T.accent} strokeWidth={3}/>
          </div>
          <div style={{ fontSize: 22, fontWeight: 800, color: T.ink,
                        letterSpacing: '-0.028em', marginBottom: 6,
                        lineHeight: 1.25 }}>
            {isMulti
              ? <React.Fragment>씨앗 <span style={{ color: T.accent }}>{created.length}개</span>를 만들었어요</React.Fragment>
              : '씨앗을 만들었어요'}
          </div>
          <div style={{ fontSize: 13.5, color: T.ink2, lineHeight: 1.5 }}>
            {isMulti
              ? `${langSet.join(' · ')} · 카테고리는 씨앗별로 확인해주세요`
              : '발음·대화 맥락까지 함께 만들었어요'}
          </div>
        </div>

        {/* Created seed(s) preview — single or multi, both styled
            as tappable cards so the user can drill in. */}
        {!isMulti ? (
          <React.Fragment>
            <div style={{ fontSize: 11.5, color: T.ink3, padding: '0 4px 8px',
                          letterSpacing: '-0.005em', lineHeight: 1.5 }}>
              카드를 탭해서 자세히 보고 카테고리를 확인해주세요
            </div>
            <div
              onClick={() => onNavigate('P05', { seedId: first.id, from: 'P10' })}
              style={{
                background: T.surface, borderRadius: 18,
                border: `0.5px solid ${T.hairline}`,
                padding: '18px 18px 16px', marginBottom: 14,
                position: 'relative', cursor: 'pointer',
              }}>
              <div style={{
                position: 'absolute', top: 12, right: 12,
                fontSize: 10, fontWeight: 800, color: T.accent,
                background: T.accentSoft, padding: '3px 8px', borderRadius: 999,
                letterSpacing: '0.06em',
              }}>NEW</div>

              <div style={{ fontSize: 10.5, fontWeight: 700, color: T.ink3,
                            letterSpacing: '0.08em', textTransform: 'uppercase',
                            marginBottom: 10 }}>{first.langLabel}</div>
              <div style={{ fontSize: 20, fontWeight: 700, color: T.ink,
                            letterSpacing: '-0.02em', lineHeight: 1.35,
                            marginBottom: 8 }}>{first.foreign}</div>
              <div style={{ fontSize: 13, color: T.ink3, lineHeight: 1.5,
                            marginBottom: 10 }}>{first.pron}</div>
              <div style={{ height: 0.5, background: T.hairline, margin: '6px 0 10px' }}/>
              <div style={{ fontSize: 14, color: T.ink2, lineHeight: 1.5,
                            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                            gap: 8 }}>
                <span style={{ flex: 1 }}>{first.korean}</span>
                <Icons.ChevronR size={16} color={T.ink3}/>
              </div>
            </div>
          </React.Fragment>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8,
                        marginBottom: 14 }}>
            <div style={{ fontSize: 11.5, color: T.ink3, padding: '0 4px 4px',
                          letterSpacing: '-0.005em', lineHeight: 1.5 }}>
              카드를 탭해서 자세히 보고 카테고리를 확인해주세요
            </div>
            {created.map((s, i) => (
              <div key={s.id}
                   onClick={() => onNavigate('P05', { seedId: s.id, from: 'P10m' })}
                   style={{
                background: T.surface, borderRadius: 14,
                border: `0.5px solid ${T.hairline}`,
                padding: '12px 14px',
                display: 'flex', alignItems: 'center', gap: 12,
                cursor: 'pointer',
              }}>
                <div style={{
                  width: 28, height: 28, borderRadius: '50%',
                  background: T.accent, color: '#FFF',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: 12, fontWeight: 800, flexShrink: 0,
                }}>{i + 1}</div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 9.5, fontWeight: 700, color: T.ink3,
                                letterSpacing: '0.08em', textTransform: 'uppercase',
                                marginBottom: 2 }}>{s.langLabel}</div>
                  <div style={{ fontSize: 14.5, fontWeight: 600, color: T.ink,
                                letterSpacing: '-0.01em', lineHeight: 1.3,
                                overflow: 'hidden', textOverflow: 'ellipsis',
                                whiteSpace: 'nowrap' }}>{s.foreign}</div>
                  <div style={{ fontSize: 12, color: T.ink2, marginTop: 2,
                                overflow: 'hidden', textOverflow: 'ellipsis',
                                whiteSpace: 'nowrap' }}>{s.korean}</div>
                </div>
                <Icons.ChevronR size={16} color={T.ink3}/>
              </div>
            ))}
          </div>
        )}

        {/* Editable category section — single-seed only.
            Multi case: user fixes per-seed categories from P05. */}
        {!isMulti && (
          <div style={{ marginBottom: 14 }}>
            <div style={{
              display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              gap: 8, padding: '0 2px 8px',
            }}>
              <div style={{ display: 'inline-flex', alignItems: 'center', gap: 6,
                            minWidth: 0, flexShrink: 0 }}>
                <span style={{ fontSize: 11.5, fontWeight: 700, color: T.ink3,
                               letterSpacing: '0.08em', textTransform: 'uppercase',
                               whiteSpace: 'nowrap' }}>
                  카테고리
                </span>
                <span style={{
                  display: 'inline-flex', alignItems: 'center', gap: 3,
                  fontSize: 10.5, color: T.accent, fontWeight: 700,
                  background: T.accentSoft, padding: '2px 7px 2px 5px',
                  borderRadius: 999, letterSpacing: '-0.005em',
                  whiteSpace: 'nowrap',
                }}>
                  <Icons.Sparkle size={10} color={T.accent}/>
                  자동
                </span>
              </div>
              <span style={{ fontSize: 11, color: T.ink3, whiteSpace: 'nowrap',
                             overflow: 'hidden', textOverflow: 'ellipsis',
                             flexShrink: 1, minWidth: 0 }}>
                틀렸으면 × 로 빼주세요
              </span>
            </div>

            <div style={{
              background: T.surface, borderRadius: 14,
              border: `0.5px solid ${T.hairline}`,
              padding: '12px 12px 10px',
              display: 'flex', flexWrap: 'wrap', gap: 6, alignItems: 'center',
            }}>
              {cats.map(id => {
                const cat = catById[id];
                if (!cat) return null;
                const isAuto = autoSet.has(id);
                return (
                  <CategoryChip key={id} cat={cat} isAuto={isAuto}
                                onRemove={() => removeCat(id)}/>
                );
              })}

              <button onClick={() => setPickerOpen(true)} style={{
                height: 30, padding: '0 12px',
                background: 'transparent',
                border: `0.5px dashed ${T.hairlineStrong}`,
                borderRadius: 15,
                color: T.ink2, fontFamily: 'inherit',
                fontSize: 12.5, fontWeight: 600, letterSpacing: '-0.005em',
                cursor: 'pointer', display: 'inline-flex',
                alignItems: 'center', gap: 4, whiteSpace: 'nowrap',
                WebkitTapHighlightColor: 'transparent',
              }}>
                <Icons.Plus size={12} color={T.ink2} strokeWidth={2}/>
                추가
              </button>

              {cats.length === 0 && (
                <div style={{ fontSize: 12, color: T.ink3, padding: '6px 4px',
                              lineHeight: 1.5 }}>
                  카테고리 없이 저장돼요. 나중에 씨앗 상세에서 추가할 수 있어요.
                </div>
              )}
            </div>
          </div>
        )}

        {/* Pouch hint — pouches are user-controlled, not auto-assigned. */}
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8,
          padding: '10px 12px', borderRadius: 12,
          background: T.inkOverlaySoft || 'rgba(60,42,20,0.04)',
          marginBottom: 18,
          fontSize: 12, color: T.ink2, letterSpacing: '-0.005em',
          lineHeight: 1.45,
        }}>
          <Icons.Bag size={15} color={T.ink3}/>
          <span style={{ flex: 1 }}>
            주머니로 묶는 건 <b style={{ color: T.ink, fontWeight: 700 }}>씨앗 자세히 보기</b>에서
            직접 골라주세요
          </span>
        </div>

        <div style={{ flex: 1 }}/>

        {/* Actions — same shape for both default and multi: card itself
            is the entry point to detail, the bottom row is just "또 담기"
            (primary, expected next action) and "홈으로" (escape). */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          <Button kind="primary" fullWidth
                  onClick={() => onNavigate('P06')}>
            또 담기
          </Button>
          <Button kind="ghost" fullWidth
                  onClick={() => onNavigate('P02')}>
            홈으로
          </Button>
        </div>
      </div>

      {pickerOpen && (
        <CategoryAddSheet
          allCats={allCats}
          excludeIds={cats}
          onPick={(id) => { addCat(id); setPickerOpen(false); }}
          onClose={() => setPickerOpen(false)}
        />
      )}
    </div>
  );
}

// Single auto/user category chip. Auto = ✨ badge on the left.
function CategoryChip({ cat, isAuto, onRemove }) {
  const T = window.T;
  const icon = cat.icon;
  const mono = !icon ? window.monogramOf(cat.label) : null;
  return (
    <div style={{
      height: 30, padding: '0 4px 0 8px',
      background: isAuto ? T.accentSoft : T.surface,
      border: `0.5px solid ${isAuto ? 'transparent' : T.hairlineStrong}`,
      borderRadius: 15,
      display: 'inline-flex', alignItems: 'center', gap: 5,
      fontFamily: 'inherit', whiteSpace: 'nowrap', flexShrink: 0,
      WebkitTapHighlightColor: 'transparent',
    }}>
      {isAuto && (
        <span style={{
          width: 16, height: 16, borderRadius: '50%',
          background: T.accent,
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          flexShrink: 0,
        }}>
          <Icons.Sparkle size={9} color="#FFF"/>
        </span>
      )}
      <span style={{ fontSize: 13, lineHeight: 1, color: T.ink2,
                     display: 'inline-flex', alignItems: 'center', gap: 4 }}>
        {icon ? <span style={{ fontSize: 13 }}>{icon}</span>
              : <span style={{ fontSize: 10, fontWeight: 700, color: T.ink2 }}>{mono}</span>}
        <span style={{ fontSize: 12.5, fontWeight: 600, color: T.ink,
                       letterSpacing: '-0.005em' }}>{cat.label}</span>
      </span>
      <button onClick={onRemove} style={{
        width: 22, height: 22, borderRadius: '50%',
        background: 'transparent', border: 'none', padding: 0,
        cursor: 'pointer', flexShrink: 0,
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        WebkitTapHighlightColor: 'transparent',
      }} aria-label={`${cat.label} 카테고리 빼기`}>
        <Icons.Close size={11} color={T.ink3} strokeWidth={2.4}/>
      </button>
    </div>
  );
}

// Bottom sheet that lets the user pick from the remaining categories.
// Also exposes a "+ 새 카테고리 만들기" affordance (inline form) so the
// user can create a new custom category without leaving the flow.
function CategoryAddSheet({ allCats, excludeIds, onPick, onClose }) {
  const T = window.T;
  // Local store mirror — adding a new category persists to window.__cpCats
  // so it shows up everywhere else (P05c, P02 filter, P13b) without refresh.
  const [cats, setCats] = React.useState(() => allCats || window.MOCK_CATEGORIES);
  const [creating, setCreating] = React.useState(false);

  const exclude = new Set(excludeIds);
  const available = (cats || []).filter(c => !exclude.has(c.id));

  const handleCreate = ({ label, icon }) => {
    if (!window.makeNewCat) return; // safety
    const newCat = window.makeNewCat(label, icon);
    const next = [newCat, ...cats];
    setCats(next);
    window.__cpCats = next; // propagate to other screens this session
    setCreating(false);
    // Auto-pick the new category — saves a tap, matches user intent.
    onPick(newCat.id);
  };

  return (
    <div onClick={onClose} style={{
      position: 'absolute', inset: 0, zIndex: 60,
      background: 'rgba(0,0,0,0.32)',
      display: 'flex', flexDirection: 'column', justifyContent: 'flex-end',
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        background: T.bg, borderRadius: '20px 20px 0 0',
        maxHeight: '82%', display: 'flex', flexDirection: 'column',
        boxShadow: '0 -10px 40px rgba(0,0,0,0.18)',
      }}>
        <div style={{ display: 'flex', justifyContent: 'center', padding: '8px 0 4px' }}>
          <div style={{ width: 36, height: 4, borderRadius: 2,
                        background: T.hairlineStrong }}/>
        </div>

        <div style={{ padding: '6px 16px 12px',
                      display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div>
            <div style={{ fontSize: 17, fontWeight: 700, color: T.ink,
                          letterSpacing: '-0.02em' }}>
              {creating ? '새 카테고리 만들기' : '카테고리 추가'}
            </div>
            <div style={{ fontSize: 11.5, color: T.ink3, marginTop: 2 }}>
              {creating
                ? '내 분류를 직접 만들 수 있어요 · 다른 씨앗에서도 쓸 수 있어요'
                : '탭해서 추가 · 없으면 새로 만들 수 있어요'}
            </div>
          </div>
          <IconButton icon={<Icons.Close size={20} color={T.ink2}/>}
                      onClick={() => creating ? setCreating(false) : onClose()}
                      size={32}/>
        </div>

        <div style={{ flex: 1, overflowY: 'auto', padding: '0 16px 18px' }}>
          {creating ? (
            window.NewCategoryForm ? (
              <window.NewCategoryForm
                submitLabel="만들고 추가"
                onSubmit={handleCreate}
                onCancel={() => setCreating(false)}
              />
            ) : (
              <div style={{ padding: 20, color: T.danger, fontSize: 13 }}>
                새 카테고리 폼을 불러올 수 없어요
              </div>
            )
          ) : (
            <React.Fragment>
              {available.length > 0 ? (
                <CategorySection items={available} onPick={onPick}/>
              ) : (
                <div style={{ padding: '32px 0 16px', textAlign: 'center',
                              color: T.ink3, fontSize: 13, lineHeight: 1.6 }}>
                  모든 카테고리가 이미 추가됐어요.<br/>
                  새 카테고리를 만들 수도 있어요
                </div>
              )}

              {/* New-category CTA — always visible so the user knows
                  custom categories are an option. */}
              <button onClick={() => setCreating(true)} style={{
                width: '100%', marginTop: 12,
                padding: '14px 16px', borderRadius: 14,
                background: 'transparent',
                border: `1px dashed ${T.hairlineStrong}`,
                color: T.accent, fontFamily: 'inherit',
                fontSize: 13.5, fontWeight: 700, letterSpacing: '-0.01em',
                cursor: 'pointer',
                display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
                WebkitTapHighlightColor: 'transparent',
              }}>
                <Icons.Plus size={14} color={T.accent} strokeWidth={2.2}/>
                새 카테고리 만들기
              </button>
            </React.Fragment>
          )}
        </div>
      </div>
    </div>
  );
}

function CategorySection({ label, items, onPick }) {
  const T = window.T;
  return (
    <div style={{ marginBottom: 14 }}>
      {label && (
        <div style={{ fontSize: 11, fontWeight: 700, color: T.ink3,
                      letterSpacing: '0.08em', textTransform: 'uppercase',
                      padding: '8px 4px 8px' }}>{label}</div>
      )}
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
        {items.map(cat => {
          const mono = !cat.icon ? window.monogramOf(cat.label) : null;
          return (
            <button key={cat.id} onClick={() => onPick(cat.id)} style={{
              height: 38, padding: '0 14px 0 10px',
              background: T.surface,
              border: `0.5px solid ${T.hairlineStrong}`,
              borderRadius: 19,
              display: 'inline-flex', alignItems: 'center', gap: 6,
              cursor: 'pointer', fontFamily: 'inherit',
              WebkitTapHighlightColor: 'transparent',
            }}>
              {cat.icon ? <span style={{ fontSize: 15 }}>{cat.icon}</span>
                        : <span style={{ fontSize: 12, fontWeight: 700,
                                         color: T.ink2 }}>{mono}</span>}
              <span style={{ fontSize: 13.5, fontWeight: 600, color: T.ink,
                             letterSpacing: '-0.005em' }}>{cat.label}</span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

Object.assign(window, { ScreenSearch, ScreenNewCollection, ScreenProcessing, ScreenProcessed, CategoryChip, CategoryAddSheet, CategorySection });
