// 그란데 독서타임 — 내 스탬프
//
// 도끼책 원정대 보상. 나무 카드에 손으로 찍던 것을 웹으로 옮겼다.
//   도끼꾼 1회 참여당 1장 (2026-10-02 변경. 이전엔 발표 시 1장 더)
// 원정대 탭 우측 '내 스탬프' 버튼을 누르면 열린다. 로그인했을 때만 보인다.
//
// 팝업은 #scaler 밖(document.body portal)에 그린다.
// scaler 의 transform: scale() 이 position:fixed 기준을 바꿔버리기 때문.

const STAMP_ENDPOINT = 'https://script.google.com/macros/s/AKfycbwRygO5DaybmUOnVTGm78vO2MgV24xHnkG6w7y-j4MWOn9jimwCII_kQnwXD0AY07Fo/exec';

async function postStamp(payload) {
  const res = await fetch(STAMP_ENDPOINT, {
    method: 'POST',
    headers: { 'Content-Type': 'text/plain;charset=utf-8' },
    body: JSON.stringify(payload),
    redirect: 'follow',
  });
  const text = await res.text();
  try { return JSON.parse(text); }
  catch (e) { return { ok: false, error: '서버 응답을 읽지 못했어요.' }; }
}

window.stampStore = {
  mine() {
    return postStamp({ action: 'myStamps', session: window.authStore.session })
      .catch(e => ({ ok: false, error: '네트워크 오류: ' + (e && e.message ? e.message : String(e)) }));
  },
  all() {
    return postStamp({ action: 'allStamps', session: window.authStore.session })
      .catch(e => ({ ok: false, error: '네트워크 오류: ' + (e && e.message ? e.message : String(e)) }));
  },
  save(round, rows) {
    return postStamp({ action: 'saveStamps', session: window.authStore.session, round, rows })
      .catch(e => ({ ok: false, error: '네트워크 오류: ' + (e && e.message ? e.message : String(e)) }));
  },
};

// 도끼 도장. 이모지 대신 직접 그려서 크기와 색을 마음대로 쓴다.
// 살짝 기울여 손으로 찍은 느낌을 낸다.
const AxeMark = ({ color, opacity = 1, size = '50%' }) => (
  <div style={{
    position: 'absolute', inset: 0,
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    pointerEvents: 'none',
  }}>
    <svg viewBox="0 0 64 64" style={{ width: size, height: size, transform: 'rotate(-8deg)', opacity }}>
      {/* 자루 — 왼쪽 아래에서 오른쪽 위로 */}
      <path d="M16 52 L38 26" stroke={color} strokeWidth="6" strokeLinecap="round" fill="none" />
      {/* 날 — 사다리꼴. 바깥쪽(오른쪽)이 날, 안쪽이 자루에 물린다 */}
      <path d="M33 24 L50 8 L60 25 L43 35 Z" fill={color} />
    </svg>
  </div>
);

// ---------- 내 스탬프 팝업 ----------
const StampModal = ({ open, onClose }) => {
  const t = window.tokens;
  const cfg = window.expeditionConfig || {};
  const rewards = cfg.rewards || [];
  const goal = rewards.length ? Math.max(...rewards.map(r => r.stamps)) : 6;

  const [state, setState] = React.useState({ loading: true, error: '', stamps: [], total: 0, user: null });

  React.useEffect(() => {
    if (!open) return;
    let alive = true;
    setState(s => ({ ...s, loading: true, error: '' }));
    window.stampStore.mine().then(r => {
      if (!alive) return;
      if (r && r.ok) setState({ loading: false, error: '', stamps: r.stamps || [], total: r.total || 0, user: r.user });
      else setState(s => ({ ...s, loading: false, error: (r && r.error) || '스탬프를 불러오지 못했어요.' }));
    });
    return () => { alive = false; };
  }, [open]);

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = prev; };
  }, [open]);

  if (!open) return null;

  const { loading, error, stamps, total, user } = state;

  // 회차별로 묶기. 한 회차에 참석 1장 + 도끼꾼 1장.
  const rounds = stamps.slice().sort((a, b) => String(a.round).localeCompare(String(b.round)));

  return ReactDOM.createPortal(
    <div
      onClick={onClose}
      style={{
        position: 'fixed', inset: 0, zIndex: 10000,
        background: 'rgba(10,10,10,0.55)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: t.font.sans, padding: 20,
      }}
    >
      <div onClick={(e) => e.stopPropagation()} style={{
        background: '#fff', width: 500, maxWidth: '100%', maxHeight: '86vh',
        borderRadius: 14, position: 'relative', display: 'flex', flexDirection: 'column',
      }}>
        <div onClick={onClose} style={{
          position: 'absolute', top: 14, right: 18, fontSize: 24,
          color: t.color.mutedLight, cursor: 'pointer', lineHeight: 1, zIndex: 2,
        }}>×</div>

        <div style={{ padding: '30px 30px 24px' }}>
          <div style={{ fontSize: 13, color: t.color.muted, fontWeight: 500 }}>도끼책 원정대</div>
          <div style={{ fontSize: 26, fontWeight: 800, letterSpacing: '-0.03em', marginTop: 4 }}>
            {user ? `${user.name}님의 스탬프` : '내 스탬프'}
          </div>

          {loading ? (
            <div style={{ fontSize: 14, color: t.color.muted, marginTop: 22 }}>불러오는 중</div>
          ) : error ? (
            <div style={{ fontSize: 14, color: '#C53030', marginTop: 22, lineHeight: 1.6 }}>{error}</div>
          ) : (
            <>
              {/* 도장판 — 카페 적립 쿠폰. 찍히면 도끼 도장이 남는다.
                  상품이 걸린 칸에는 상품명이 크게 들어가고, 나머지 칸은 비워둔다. */}
              <div style={{
                display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)',
                gap: 16, marginTop: 26,
              }}>
                {Array.from({ length: goal }).map((_, i) => {
                  const n = i + 1;
                  const got = n <= total;
                  const reward = rewards.find(r => r.stamps === n);
                  return (
                    <div key={i} style={{
                      position: 'relative',
                      aspectRatio: '1 / 1',
                      borderRadius: '50%',
                      background: got ? t.color.blue : '#fff',
                      border: got
                        ? `2px solid ${t.color.blue}`
                        : `2px dashed ${reward ? t.color.blueMid : t.color.silver}`,
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      textAlign: 'center', padding: 10,
                      transition: 'all .2s', overflow: 'hidden',
                    }}>
                      {/* 도장 자국 — 찍힌 칸은 진하게, 빈 칸은 흐리게 밑그림처럼 */}
                      <AxeMark
                        color={got ? '#fff' : t.color.silver}
                        opacity={got ? (reward ? 0.28 : 0.95) : (reward ? 0.16 : 0.4)}
                        size={reward ? '78%' : '46%'}
                      />
                      {reward && (
                        <div style={{
                          position: 'relative', zIndex: 1,
                          fontSize: 15, fontWeight: 800, lineHeight: 1.2,
                          letterSpacing: '-0.02em', wordBreak: 'keep-all',
                          color: got ? '#fff' : t.color.blueMid,
                        }}>
                          {reward.label}
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            </>
          )}
        </div>

        {/* 회차 내역 */}
        {!loading && !error && (
          <div style={{ borderTop: `1px solid ${t.color.ruleSoft}`, overflowY: 'auto', padding: '4px 30px 8px' }}>
            {rounds.length === 0 ? (
              <div style={{ fontSize: 13, color: t.color.muted, padding: '18px 0 24px', lineHeight: 1.6 }}>
                아직 모은 스탬프가 없어요. 도끼타임에 참여하면 한 장씩 쌓입니다.
              </div>
            ) : rounds.map((s, i) => (
              <div key={s.round + i} style={{
                display: 'flex', alignItems: 'baseline', gap: 12,
                padding: '14px 0', borderTop: i === 0 ? 'none' : `1px solid ${t.color.ruleSoft}`,
              }}>
                <div style={{ flex: '0 0 66px', fontSize: 14, fontWeight: 700, color: t.color.mutedLight, fontVariantNumeric: 'tabular-nums' }}>
                  {s.round}
                </div>
                <div style={{ flex: 1, minWidth: 0, fontSize: 14, color: t.color.inkSoft }}>
                  {[s.attended ? '참석' : '', s.axe ? '도끼꾼' : ''].filter(Boolean).join(', ')}
                </div>
                <div style={{ fontSize: 14, fontWeight: 700, color: t.color.blue, fontVariantNumeric: 'tabular-nums' }}>
                  {s.count}장
                </div>
              </div>
            ))}
          </div>
        )}

      </div>
    </div>,
    document.body
  );
};

window.StampModal = StampModal;
