/* ────────────────────────────────────────────────────────────
   invite-accept.jsx — 초대 수락 화면(feature b §7) — /invite/<token>
   · 비로그인 → 로그인/가입 안내(로그인 후 같은 화면에서 수락).
   · 로그인 → POST /api/invites/:token/accept → 성공 시 대시보드로 이동(공유받음 표시).
   · 만료(410)/불일치(403)/없음(404) 모두 비-백지 안내.
   초대 = COPY-PASTE 링크. 이메일 발송 없음(받은 사람이 직접 링크 열어 수락).
   REST: POST /api/invites/:token/accept (requireAuth) → { project:{id}, role }.
   window 노출 패턴. tokens·해요체·이모지 없음.
   ──────────────────────────────────────────────────────────── */

/* 경로에서 초대 토큰 추출 — /invite/<token>[/...] → <token>. */
function parseInviteToken() {
  try {
    const m = window.location.pathname.match(/^\/invite\/([^/?#]+)/);
    return m ? decodeURIComponent(m[1]) : null;
  } catch (e) { return null; }
}

const INVITE_ROLE_LABEL = (typeof SHARE_ROLE_LABEL !== "undefined" && SHARE_ROLE_LABEL)
  ? SHARE_ROLE_LABEL
  : { owner: "소유자", editor: "편집자", reviewer: "검수자", viewer: "뷰어" };

/* 브랜디드 카드 셸 — 가운데 정렬. */
function inviteShell(children) {
  return React.createElement("div", {
    style: { minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", background: "var(--bg-canvas)", padding: 24 },
  },
    React.createElement("div", { style: { width: "100%", maxWidth: 440, background: "var(--bg-normal)", border: "1px solid var(--border)", borderRadius: "var(--r-lg)", boxShadow: "var(--sh-2)", padding: "30px 28px", textAlign: "center" } },
      React.createElement("div", { style: { display: "inline-flex", alignItems: "center", gap: 9, marginBottom: 18 } },
        React.createElement("span", { style: { width: 30, height: 30, borderRadius: "var(--r-sm)", background: "var(--primary)", display: "inline-flex", alignItems: "center", justifyContent: "center" } },
          React.createElement("svg", { width: 17, height: 17, viewBox: "0 0 24 24", fill: "none", stroke: "#fff", strokeWidth: 2 }, React.createElement("rect", { x: 3, y: 3, width: 18, height: 18, rx: 2 }), React.createElement("path", { d: "M3 9h18M9 21V9" }))),
        React.createElement("span", { className: "t-heading-1", style: { letterSpacing: "-0.02em", color: "var(--label-normal)" } }, "Storyboard")),
      children));
}

function InviteAccept({ user, onAuthed, onDone }) {
  const token = useMemo(() => parseInviteToken(), []);
  /* phase: needauth | ready | accepting | done | error */
  const [phase, setPhase] = useState(user ? "ready" : "needauth");
  const [result, setResult] = useState(null);   // { project:{id}, role } | null
  const [err, setErr] = useState("");
  const [showRegister, setShowRegister] = useState(false);

  useEffect(() => { if (user && phase === "needauth") setPhase("ready"); }, [user, phase]);

  const accept = useCallback(async () => {
    if (!token) { setErr("유효하지 않은 초대 링크예요."); setPhase("error"); return; }
    setPhase("accepting"); setErr("");
    try {
      const data = await api(`/invites/${token}/accept`, { method: "POST", body: {} });
      setResult(data || null);
      setPhase("done");
    } catch (ex) {
      if (ex.status === 410) setErr("초대가 만료됐어요. 새 초대를 요청해 주세요.");
      else if (ex.status === 403) setErr("이 초대는 다른 이메일로 발급됐어요. 초대받은 이메일로 로그인해 주세요.");
      else if (ex.status === 404) setErr("유효하지 않은 초대예요. 링크를 다시 확인해 주세요.");
      else setErr(ex.message || "초대를 수락하지 못했어요.");
      setPhase("error");
    }
  }, [token]);

  const goApp = useCallback(() => {
    // 대시보드로 이동(공유받음 섹션에 노출). app.jsx 가 직접 라우팅하면 onDone 사용.
    if (onDone) onDone(result);
    else { try { window.location.assign("/app/"); } catch (e) { window.location.pathname = "/app/"; } }
  }, [onDone, result]);

  if (!token) {
    return inviteShell(React.createElement("div", null,
      React.createElement("div", { className: "t-headline-1", style: { color: "var(--label-normal)", marginBottom: 8 } }, "유효하지 않은 초대 링크예요"),
      React.createElement("p", { className: "t-body-2", style: { color: "var(--label-alt)", margin: "0 0 18px" } }, "초대 링크를 다시 확인해 주세요.")));
  }

  /* 비로그인 — 로그인/가입 후 수락. LoginView/RegisterView 재사용(onAuthed→상위 user 갱신). */
  if (phase === "needauth") {
    if (typeof LoginView !== "function") {
      return inviteShell(React.createElement("div", null,
        React.createElement("div", { className: "t-headline-1", style: { color: "var(--label-normal)", marginBottom: 8 } }, "로그인이 필요해요"),
        React.createElement("p", { className: "t-body-2", style: { color: "var(--label-alt)", margin: "0 0 18px" } }, "초대를 수락하려면 먼저 로그인해 주세요."),
        React.createElement(Button, { kind: "primary", onClick: () => window.location.assign("/app/") }, "로그인 하러 가기")));
    }
    return React.createElement("div", null,
      React.createElement("div", { style: { textAlign: "center", padding: "20px 24px 4px", background: "var(--bg-canvas)" } },
        React.createElement("p", { className: "t-body-2", style: { color: "var(--label-alt)", margin: 0 } }, "초대를 수락하려면 먼저 로그인해 주세요. 초대받은 이메일로 로그인하면 자동으로 차시에 참여돼요.")),
      showRegister
        ? React.createElement(RegisterView, { onAuthed: (u) => { if (onAuthed) onAuthed(u); setPhase("ready"); }, goLogin: () => setShowRegister(false) })
        : React.createElement(LoginView, { onAuthed: (u) => { if (onAuthed) onAuthed(u); setPhase("ready"); }, goRegister: () => setShowRegister(true) }));
  }

  if (phase === "error") {
    return inviteShell(React.createElement("div", null,
      React.createElement("div", { className: "t-headline-1", style: { color: "var(--label-normal)", marginBottom: 8 } }, "초대를 수락하지 못했어요"),
      React.createElement("p", { className: "t-body-2", style: { color: "var(--negative)", margin: "0 0 18px", lineHeight: 1.55 } }, err),
      React.createElement(Button, { kind: "outline", onClick: () => window.location.assign("/app/") }, "작업실로 가기")));
  }

  if (phase === "done") {
    const roleLabel = result && result.role ? (INVITE_ROLE_LABEL[result.role] || result.role) : null;
    return inviteShell(React.createElement("div", null,
      React.createElement("div", { style: { width: 46, height: 46, borderRadius: "50%", background: "var(--positive-bg)", display: "inline-flex", alignItems: "center", justifyContent: "center", marginBottom: 14 } },
        React.createElement("svg", { width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "var(--positive)", strokeWidth: 2.6, strokeLinecap: "round", strokeLinejoin: "round" }, React.createElement("path", { d: "M20 6 9 17l-5-5" }))),
      React.createElement("div", { className: "t-headline-1", style: { color: "var(--label-normal)", marginBottom: 8 } }, "초대를 수락했어요"),
      React.createElement("p", { className: "t-body-2", style: { color: "var(--label-alt)", margin: "0 0 18px", lineHeight: 1.55 } },
        roleLabel ? React.createElement(React.Fragment, null, React.createElement("b", { style: { color: "var(--label-neutral)" } }, roleLabel), " 권한으로 차시에 참여했어요. 작업실의 ‘공유받음’에서 열 수 있어요.")
                  : "차시에 참여했어요. 작업실의 ‘공유받음’에서 열 수 있어요."),
      React.createElement(Button, { kind: "primary", onClick: goApp }, "차시 열기")));
  }

  /* ready / accepting — 수락 버튼. */
  return inviteShell(React.createElement("div", null,
    React.createElement("div", { className: "t-headline-1", style: { color: "var(--label-normal)", marginBottom: 8 } }, "차시 초대를 받았어요"),
    React.createElement("p", { className: "t-body-2", style: { color: "var(--label-alt)", margin: "0 0 20px", lineHeight: 1.55 } },
      user && user.email
        ? React.createElement(React.Fragment, null, React.createElement("b", { style: { color: "var(--label-neutral)" } }, user.email), " 계정으로 이 초대를 수락할게요.")
        : "아래 버튼을 눌러 초대를 수락해 주세요."),
    React.createElement(Button, { kind: "primary", onClick: accept, disabled: phase === "accepting" },
      phase === "accepting" ? React.createElement(Spinner, { s: 15, color: "#fff" }) : "초대 수락"),
    React.createElement("div", { style: { marginTop: 12 } },
      React.createElement("button", { onClick: () => window.location.assign("/app/"), style: { background: "none", border: "none", cursor: "pointer", color: "var(--label-alt)", fontSize: 13, fontWeight: 600 } }, "나중에 하기"))));
}

Object.assign(window, { InviteAccept, parseInviteToken });
