/* ────────────────────────────────────────────────────────────
   dashboard.jsx — 차시(프로젝트) 대시보드
   CONTRACT §3.2:
     GET  /api/projects -> {items:[{id,courseName,chapterName,status,masterId,slideCount,updatedAt}]}
     POST /api/projects {courseName,chapterName} -> 201 {project}
   ──────────────────────────────────────────────────────────── */

function StatusBadge({ status }) {
  const m = projStatusMeta(status);
  return React.createElement(Pill, { color: m.color, bg: m.bg },
    React.createElement("span", { style: { width: 6, height: 6, borderRadius: "50%", background: m.dot } }),
    m.label);
}

function fmtDate(s) {
  if (!s) return "";
  try {
    const d = new Date(s);
    if (isNaN(d.getTime())) return "";
    const mm = String(d.getMonth() + 1).padStart(2, "0");
    const dd = String(d.getDate()).padStart(2, "0");
    return `${d.getFullYear()}.${mm}.${dd}`;
  } catch (e) { return ""; }
}

function NewProjectModal({ onClose, onCreated }) {
  const [courseName, setCourseName] = useState("");
  const [chapterName, setChapterName] = useState("");
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");

  async function submit(e) {
    e.preventDefault();
    setErr(""); setBusy(true);
    try {
      const { project } = await api("/projects", { method: "POST", body: { courseName: courseName.trim(), chapterName: chapterName.trim() } });
      onCreated(project);
    } catch (ex) {
      setErr(ex.message || "차시를 만들지 못했어요.");
    } finally { setBusy(false); }
  }

  return React.createElement("div", {
    onClick: onClose,
    style: { position: "fixed", inset: 0, background: "rgba(20,25,30,0.42)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 100, padding: 24 },
  },
    React.createElement("div", {
      onClick: (e) => e.stopPropagation(),
      style: { width: "100%", maxWidth: 460, background: "var(--bg-normal)", borderRadius: "var(--r-lg)", boxShadow: "var(--sh-3)", padding: "26px 26px 24px" },
    },
      React.createElement("div", { className: "t-heading-1", style: { marginBottom: 4 } }, "새 차시 만들기"),
      React.createElement("p", { className: "t-body-2", style: { color: "var(--label-alt)", margin: "0 0 20px" } }, "과목명과 차시명을 입력하면 빈 스토리보드가 만들어져요."),
      React.createElement("form", { onSubmit: submit },
        React.createElement(Field, { label: "과목명", value: courseName, onChange: (e) => setCourseName(e.target.value), placeholder: "예) 산업안전보건교육", autoFocus: true }),
        React.createElement(Field, { label: "차시명", value: chapterName, onChange: (e) => setChapterName(e.target.value), placeholder: "예) 1차시" }),
        err ? React.createElement("div", { className: "t-label-2", style: { color: "var(--negative)", background: "var(--negative-bg)", borderRadius: "var(--r-sm)", padding: "9px 12px", marginBottom: 14 } }, err) : null,
        React.createElement("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 8 } },
          React.createElement(Button, { type: "button", kind: "outline", onClick: onClose }, "취소"),
          React.createElement(Button, { type: "submit", disabled: busy },
            busy ? React.createElement(Spinner, { s: 15, color: "#fff" }) : "만들기"))
      )
    )
  );
}

function ProjectCard({ project, onOpen }) {
  const title = project.chapterName || project.courseName || "제목 없는 차시";
  const sub = project.chapterName ? (project.courseName || "") : "";
  return React.createElement("button", {
    onClick: () => onOpen(project),
    style: {
      textAlign: "left", background: "var(--bg-normal)", border: "1px solid var(--border)", borderRadius: "var(--r-lg)",
      padding: "18px 18px 16px", cursor: "pointer", display: "flex", flexDirection: "column", gap: 12,
      transition: "border-color var(--t-fast), box-shadow var(--t-fast)",
    },
    onMouseEnter: (e) => { e.currentTarget.style.borderColor = "var(--label-disable)"; e.currentTarget.style.boxShadow = "var(--sh-1)"; },
    onMouseLeave: (e) => { e.currentTarget.style.borderColor = "var(--border)"; e.currentTarget.style.boxShadow = "none"; },
  },
    React.createElement("div", { style: { display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 10 } },
      React.createElement("div", { style: { minWidth: 0 } },
        React.createElement("div", { className: "t-headline-1", style: { color: "var(--label-normal)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, title),
        sub ? React.createElement("div", { className: "t-caption-1", style: { color: "var(--label-alt)", marginTop: 3 } }, sub) : null),
      React.createElement(StatusBadge, { status: project.status })),
    React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 12, marginTop: 2 } },
      React.createElement("span", { className: "t-caption-1 tnum", style: { color: "var(--label-neutral)", fontWeight: 700 } },
        React.createElement("span", { style: { color: "var(--label-assist)", fontWeight: 600 } }, "슬라이드 "),
        `${typeof project.slideCount === "number" ? project.slideCount : 0}장`),
      project.masterId ? React.createElement(Pill, { color: "var(--cyan)", bg: "var(--cyan-bg)" }, "마스터 지정됨") : null,
      React.createElement("span", { className: "t-caption-1", style: { marginLeft: "auto", color: "var(--label-assist)" } }, fmtDate(project.updatedAt)))
  );
}

/* 빈상태 안내 — 신규 사용자 온보딩. 랜딩의 5단계 파이프라인을 온브랜드로 녹임. */
const PIPELINE_STEPS = ["원고 업로드", "AI 스토리보드", "듀얼뷰 편집", "마스터 적용", "PPTX 내보내기"];

function PipelineSteps() {
  return React.createElement("div", {
    style: { display: "flex", flexWrap: "wrap", alignItems: "center", justifyContent: "center", gap: 8, maxWidth: 560 },
  },
    PIPELINE_STEPS.map((label, i) =>
      React.createElement(React.Fragment, { key: label },
        React.createElement("span", {
          style: {
            display: "inline-flex", alignItems: "center", gap: 8,
            background: "var(--bg-normal)", border: "1px solid var(--border)", borderRadius: "var(--r-md)",
            padding: "9px 13px", fontSize: 13, fontWeight: 700, color: "var(--label-neutral)",
          },
        },
          React.createElement("span", {
            style: {
              width: 20, height: 20, borderRadius: "var(--r-xs)", background: "var(--primary)", color: "#fff",
              fontSize: 11, fontWeight: 700, display: "inline-flex", alignItems: "center", justifyContent: "center",
            },
          }, String(i + 1)),
          label),
        i < PIPELINE_STEPS.length - 1
          ? React.createElement("span", { style: { color: "var(--label-assist)", fontSize: 13 } }, "→")
          : null))
  );
}

function EmptyState({ onCreate }) {
  return React.createElement("div", {
    style: {
      border: "1px dashed var(--border)", borderRadius: "var(--r-lg)", background: "var(--bg-neutral)",
      display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center",
      textAlign: "center", gap: 16, padding: "56px 24px 52px",
    },
  },
    /* 브랜드 로고 모티프 — 라운드 사각형 아이콘 */
    React.createElement("span", {
      style: {
        width: 52, height: 52, borderRadius: "var(--r-md)", background: "var(--primary)",
        display: "inline-flex", alignItems: "center", justifyContent: "center", boxShadow: "var(--sh-1)",
      },
    },
      React.createElement("svg", { width: 26, height: 26, 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("div", null,
      React.createElement("div", { className: "t-title-3", style: { color: "var(--label-normal)" } }, "첫 차시를 만들어 볼까요"),
      React.createElement("p", { className: "t-body-2", style: { color: "var(--label-alt)", margin: "6px auto 0", maxWidth: 420 } },
        "원고만 넣으면 AI가 스토리보드를 설계해요. 듀얼뷰로 편집하고 마스터를 적용해 편집 가능한 PPTX로 내보내요.")),
    React.createElement(PipelineSteps, null),
    React.createElement("div", { style: { marginTop: 4 } },
      React.createElement(Button, { size: "lg", onClick: onCreate },
        React.createElement("svg", { width: 17, height: 17, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.4, strokeLinecap: "round" }, React.createElement("path", { d: "M12 5v14M5 12h14" })),
        "새 차시 만들기"))
  );
}

function TopBar({ user, onLogout, onOpenMasters, onOpenAdmin }) {
  const isAdmin = !!(user && user.role === "admin");
  return React.createElement("header", {
    style: {
      height: 60, display: "flex", alignItems: "center", gap: 14, padding: "0 24px",
      background: "var(--bg-normal)", borderBottom: "1px solid var(--line-normal)", position: "sticky", top: 0, zIndex: 20,
    },
  },
    React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 9 } },
      React.createElement("span", { style: { width: 28, height: 28, borderRadius: "var(--r-sm)", background: "var(--primary)", display: "inline-flex", alignItems: "center", justifyContent: "center" } },
        React.createElement("svg", { width: 15, height: 15, 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-headline-1", style: { letterSpacing: "-0.02em" } }, "Storyboard")),
    React.createElement("div", { style: { marginLeft: "auto", display: "flex", alignItems: "center", gap: 12 } },
      onOpenMasters ? React.createElement(Button, { kind: "ghost", size: "sm", onClick: onOpenMasters }, "마스터 관리") : null,
      /* 관리자 — 관리자에게만 노출(user.role === 'admin'). 전용 관리자 페이지로 진입. */
      (isAdmin && onOpenAdmin) ? React.createElement(Button, { kind: "ghost", size: "sm", onClick: onOpenAdmin }, "관리자") : null,
      user ? React.createElement("span", { className: "t-label-2", style: { color: "var(--label-alt)" } }, `${user.name || user.email}님`) : null,
      React.createElement(Button, { kind: "ghost", size: "sm", onClick: onLogout }, "로그아웃"))
  );
}

function DashboardView({ user, onOpenProject, onLogout, onOpenAdmin }) {
  const [items, setItems] = useState(null);   // null=로딩
  const [err, setErr] = useState("");
  const [showNew, setShowNew] = useState(false);
  const [showMasters, setShowMasters] = useState(false);

  const load = useCallback(async () => {
    setErr("");
    try {
      const data = await api("/projects");
      setItems(Array.isArray(data?.items) ? data.items : []);
    } catch (ex) {
      setErr(ex.message || "차시 목록을 불러오지 못했어요.");
      setItems([]);
    }
  }, []);
  useEffect(() => { load(); }, [load]);

  return React.createElement("div", { style: { minHeight: "100vh" } },
    React.createElement(TopBar, { user, onLogout, onOpenMasters: () => setShowMasters(true), onOpenAdmin }),
    React.createElement("main", { style: { maxWidth: 1080, margin: "0 auto", padding: "32px 24px 64px" } },
      React.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 22 } },
        React.createElement("div", null,
          React.createElement("div", { className: "t-title-3" }, "내 차시"),
          React.createElement("p", { className: "t-body-2", style: { color: "var(--label-alt)", margin: "4px 0 0" } }, "원고를 스토리보드로 만들고 마스터를 적용해 PPTX로 내보내요.")),
        React.createElement(Button, { onClick: () => setShowNew(true) },
          React.createElement("svg", { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.4, strokeLinecap: "round" }, React.createElement("path", { d: "M12 5v14M5 12h14" })),
          "새 차시")),

      err ? React.createElement("div", { className: "t-label-2", style: { color: "var(--negative)", background: "var(--negative-bg)", borderRadius: "var(--r-sm)", padding: "10px 14px", marginBottom: 16 } }, err) : null,

      items === null
        ? React.createElement(StateMsg, { icon: React.createElement(Spinner, { s: 24 }), title: "불러오는 중이에요" })
        : items.length === 0
          ? React.createElement(EmptyState, { onCreate: () => setShowNew(true) })
          : React.createElement("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(280px, 360px))", gap: 16, justifyContent: "start" } },
              items.map((p) => React.createElement(ProjectCard, { key: p.id, project: p, onOpen: onOpenProject })))
    ),
    showNew ? React.createElement(NewProjectModal, {
      onClose: () => setShowNew(false),
      onCreated: (project) => { setShowNew(false); onOpenProject(project); },
    }) : null,
    /* 마스터 라이브러리 관리 (프로젝트 미선택 — 적용 버튼 비활성) */
    showMasters ? React.createElement(MasterManagerModal, {
      project: null, activeMasterId: null,
      onAssigned: () => {},
      onClose: () => { setShowMasters(false); load(); },
    }) : null
  );
}

Object.assign(window, { DashboardView, StatusBadge, NewProjectModal, TopBar, EmptyState, PipelineSteps, fmtDate });
