/* ============================================================
   grouping.jsx — image-mode "group review" step (방법 2 분기)
   분석 후 업로드 배너를 디자인 유사도로 자동 클러스터링 →
   그룹 1개면 가이드 1개(정확도↑), 여러 개면 가이드 N개(일괄 추출).
   사용자는 그룹 합치기/이동/이름짓기 후 생성한다.
   ============================================================ */

const GROUP_PRESETS = [
  { name: '가이드 A', palette: ['#3B1D6E', '#FFD84D', '#E5487F'] },
  { name: '가이드 B', palette: ['#13345C', '#4CC9F0', '#FFFFFF'] },
  { name: '가이드 C', palette: ['#0F5132', '#FFE066', '#1A7A4C'] },
  { name: '가이드 D', palette: ['#6B4226', '#FFB347', '#3A2618'] },
];

const newId = (p) => p + Math.random().toString(36).slice(2, 7);

function autoGroup(images) {
  const n = images.length;
  // simulate visual clustering: few images → 1 group, more → chunk into blocks of ~4
  const count = n <= 3 ? 1 : Math.min(Math.ceil(n / 4), GROUP_PRESETS.length);
  const per = Math.ceil(n / count);
  const groups = Array.from({ length: count }, (_, i) => ({
    id: newId('g'),
    name: GROUP_PRESETS[i].name,
    palette: GROUP_PRESETS[i].palette,
    confidence: count === 1 ? Math.min(96, 78 + n * 3) : 80 + ((i * 6) % 14),
    imgs: [],
  }));
  images.forEach((src, i) => {
    const gi = Math.min(count - 1, Math.floor(i / per));
    groups[gi].imgs.push({ id: newId('im'), src });
  });
  return groups;
}

function GroupReview({ images, groups: initialGroups, mergedPalette, onBack, onGenerate }) {
  const base = (initialGroups && initialGroups.length) ? initialGroups : autoGroup(images);
  const clone = (gs) => gs.map((g) => ({ ...g, imgs: g.imgs.map((im) => ({ ...im })) }));
  const [groups, setGroups] = React.useState(() => clone(base));
  const [merged, setMerged] = React.useState(base.length === 1);
  const [drag, setDrag] = React.useState(null); // {gid, imgId}
  const [overGid, setOverGid] = React.useState(null); // group/zone currently hovered during drag

  const allImgs = () => base.reduce((a, g) => a.concat(g.imgs), []);
  const singlePalette = (mergedPalette && mergedPalette.length) ? mergedPalette : (base[0] && base[0].palette) || GROUP_PRESETS[0].palette;

  const toSingle = () => {
    setMerged(true);
    const imgs = allImgs().map((im) => ({ ...im }));
    setGroups([{
      id: newId('g'), name: base[0] ? base[0].name : GROUP_PRESETS[0].name, palette: singlePalette,
      confidence: Math.min(96, 78 + imgs.length * 3),
      imgs,
    }]);
  };
  const toAuto = () => { setMerged(false); setGroups(clone(base)); };

  const rename = (gid, name) => setGroups((gs) => gs.map((g) => (g.id === gid ? { ...g, name } : g)));

  const cleanup = (gs) => gs.filter((g) => g.imgs.length > 0);

  const moveImg = (fromGid, imgId, toGid) => {
    setMerged(false);
    setGroups((gs) => {
      let moved = null;
      let next = gs.map((g) => {
        if (g.id === fromGid) { moved = g.imgs.find((x) => x.id === imgId); return { ...g, imgs: g.imgs.filter((x) => x.id !== imgId) }; }
        return g;
      });
      if (!moved) return gs;
      if (toGid === '__new') {
        const idx = next.length;
        const p = GROUP_PRESETS[Math.min(idx, GROUP_PRESETS.length - 1)];
        next = [...next, { id: newId('g'), name: p.name, palette: p.palette, confidence: 82, imgs: [moved] }];
      } else {
        next = next.map((g) => (g.id === toGid ? { ...g, imgs: [...g.imgs, moved] } : g));
      }
      return cleanup(next);
    });
  };

  const excludeImg = (gid, imgId) => {
    setGroups((gs) => cleanup(gs.map((g) => (g.id === gid ? { ...g, imgs: g.imgs.filter((x) => x.id !== imgId) } : g))));
  };

  const onDrop = (toGid) => (e) => {
    e.preventDefault();
    setOverGid(null);
    if (drag && drag.gid !== toGid) moveImg(drag.gid, drag.imgId, toGid);
    setDrag(null);
  };

  const total = groups.reduce((a, g) => a + g.imgs.length, 0);
  const single = groups.length === 1;
  const accuracy = Math.min(100, 38 + total * 9); // for single-group framing

  return (
    <div className="content"><div className="content-pad" style={{ maxWidth: 940 }}>
      <button className="btn btn-ghost btn-sm" style={{ marginBottom: 16, marginLeft: -8 }} onClick={onBack}>
        <S2Icon name="arrowLeft" size={15} /> 다시 업로드
      </button>

      <div className="page-head" style={{ marginBottom: 20 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <h1 className="page-title">가이드 그룹 확인</h1>
          <span className="pill green"><span className="pill-dot" /> 분석 완료</span>
        </div>
        <p className="page-sub">업로드한 배너를 디자인이 비슷한 것끼리 자동으로 묶었어요. <b style={{ color: 'var(--text-2)' }}>그룹 하나당 가이드가 1개씩</b> 만들어집니다.</p>
      </div>

      {/* mode toggle + summary */}
      <div className="grp-bar">
        <div className="seg" style={{ width: 'auto' }}>
          <button className={!merged ? 'on' : ''} onClick={toAuto} style={{ padding: '0 14px' }}>
            <S2Icon name="grid" size={14} /> 여러 가이드로 분류
          </button>
          <button className={merged ? 'on' : ''} onClick={toSingle} style={{ padding: '0 14px' }}>
            <S2Icon name="layers" size={14} /> 하나의 가이드로 합치기
          </button>
        </div>
        <div className="grp-summary">
          <S2Icon name="sparkles" size={15} />
          <span>이미지 <b>{total}장</b> · 가이드 <b style={{ color: 'var(--accent-text)' }}>{groups.length}개</b> 생성 예정</span>
        </div>
      </div>

      {/* framing callout */}
      {single ? (
        <div className="grp-note">
          <div className="grp-note-ic"><S2Icon name="zap" size={16} /></div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div className="grp-note-t">하나의 가이드로 학습해요</div>
            <div className="grp-note-d">같은 가이드로 만든 배너가 많을수록 추출 정확도가 올라갑니다.</div>
          </div>
          <div className="acc-meter" title={`정확도 ${accuracy}%`}>
            <div className="acc-track"><div className="acc-fill" style={{ width: `${accuracy}%` }} /></div>
            <span className="acc-val">{accuracy}%</span>
          </div>
        </div>
      ) : (
        <div className="grp-note">
          <div className="grp-note-ic"><S2Icon name="layers" size={16} /></div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div className="grp-note-t">서로 다른 가이드 {groups.length}개를 감지했어요</div>
            <div className="grp-note-d">그룹이 잘못 묶였다면 썸네일을 다른 그룹 카드로 <b style={{ color: 'var(--text-2)' }}>드래그</b>해 옮기거나, × 로 빼낼 수 있어요.</div>
          </div>
        </div>
      )}

      {/* group cards */}
      <div className="grp-list">
        {groups.map((g, gi) => {
          const isTarget = drag && drag.gid !== g.id;
          return (
            <div key={g.id}
              className={`grp-card fade-up ${overGid === g.id && isTarget ? 'drop-on' : ''} ${isTarget ? 'droppable' : ''}`}
              style={{ animationDelay: `${gi * 50}ms` }}
              onDragOver={(e) => { if (isTarget) { e.preventDefault(); setOverGid(g.id); } }}
              onDragLeave={(e) => { if (e.currentTarget === e.target || !e.currentTarget.contains(e.relatedTarget)) setOverGid((v) => (v === g.id ? null : v)); }}
              onDrop={onDrop(g.id)}>
              <div className="grp-head">
                <span className="grp-badge">{gi + 1}</span>
                <input className="grp-name" value={g.name} onChange={(e) => rename(g.id, e.target.value)}
                  spellCheck={false} aria-label="그룹 이름" />
                <span className="pill accent" style={{ flexShrink: 0 }}>신뢰도 {g.confidence}%</span>
                <span className="grp-count">{g.imgs.length}장</span>
                <div className="grp-pal">{g.palette.map((c, i) => <i key={i} style={{ background: c, borderColor: c === '#FFFFFF' ? 'var(--border-strong)' : 'transparent' }} />)}</div>
              </div>
              <div className="grp-imgs">
                {g.imgs.map((im) => (
                  <div key={im.id}
                    className={`grp-thumb ${drag && drag.imgId === im.id ? 'dragging' : ''}`}
                    draggable
                    onDragStart={(e) => { setDrag({ gid: g.id, imgId: im.id }); e.dataTransfer.effectAllowed = 'move'; try { e.dataTransfer.setData('text/plain', im.id); } catch (_) {} }}
                    onDragEnd={() => { setDrag(null); setOverGid(null); }}
                    style={im.w && im.h ? { aspectRatio: `${im.w} / ${im.h}` } : null}>
                    <img src={im.src} alt="" draggable={false} />
                    <button className="grp-thumb-x" title="분석에서 제외"
                      onClick={() => excludeImg(g.id, im.id)}><S2Icon name="x" size={12} /></button>
                  </div>
                ))}
              </div>
            </div>
          );
        })}

        {/* drop-to-new-group zone (only while dragging) */}
        <div className={`grp-newzone ${drag ? 'show' : ''} ${overGid === '__new' ? 'drop-on' : ''}`}
          onDragOver={(e) => { if (drag) { e.preventDefault(); setOverGid('__new'); } }}
          onDragLeave={() => setOverGid((v) => (v === '__new' ? null : v))}
          onDrop={onDrop('__new')}>
          <S2Icon name="plus" size={16} /> 여기로 드래그해 새 그룹으로 분리
        </div>
      </div>

      {/* footer */}
      <div className="grp-foot">
        <div style={{ fontSize: 13, color: 'var(--text-muted)' }}>
          {single ? '배너를 더 올리면 정확도를 높일 수 있어요.' : `${groups.length}개의 편집 가능한 가이드가 만들어집니다.`}
        </div>
        <div style={{ marginLeft: 'auto', display: 'flex', gap: 10 }}>
          <button className="btn btn-secondary" onClick={onBack}><S2Icon name="upload" size={15} /> 이미지 추가</button>
          <button className="btn btn-primary" onClick={() => onGenerate(groups)}>
            <S2Icon name="sparkles" size={16} /> 가이드 {groups.length}개 생성
          </button>
        </div>
      </div>
    </div></div>
  );
}

Object.assign(window, { GroupReview, autoGroup });
