// Applications page — Creator application review

const ApplicationsPage = ({ adminEmail, onPendingCountChange }) => {
  const [tab, setTab] = useState("pending");
  const [query, setQuery] = useState("");
  const [selected, setSelected] = useState(null);
  const [approveApp, setApproveApp] = useState(null);
  const [rejectApp, setRejectApp] = useState(null);
  const [applications, setApplications] = useState([]);
  const [loading, setLoading] = useState(true);
  const toast = useToast();

  async function loadApplications() {
    setLoading(true);
    const res = await fetch("/api/admin/applications");
    if (res.ok) {
      const data = await res.json();
      setApplications(data);
      onPendingCountChange?.(data.filter(a => a.status === "pending").length);
    }
    setLoading(false);
  }

  useEffect(() => { loadApplications(); }, []);

  // Update selected when applications refresh
  useEffect(() => {
    if (selected) {
      const updated = applications.find(a => a.id === selected.id);
      if (updated) setSelected(updated);
    }
  }, [applications]);

  const filtered = applications.filter(a => {
    if (tab !== "all" && a.status !== tab) return false;
    if (query) {
      const q = query.toLowerCase();
      if (!a.name.toLowerCase().includes(q) && !(a.uid ?? "").includes(q) && !a.email.toLowerCase().includes(q)) return false;
    }
    return true;
  });

  const counts = {
    pending: applications.filter(a => a.status === "pending").length,
    approved: applications.filter(a => a.status === "approved").length,
    rejected: applications.filter(a => a.status === "rejected").length,
    all: applications.length,
  };

  // Auto-select first on mount
  useEffect(() => {
    if (!selected && filtered.length > 0) setSelected(filtered[0]);
  }, [filtered, selected]);

  async function doApprove() {
    const res = await fetch(`/api/admin/applications/${approveApp.id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action: "approve", adminEmail }),
    });
    if (!res.ok) {
      const data = await res.json().catch(() => ({}));
      toast({ title: "審核失敗", message: data.error || "請稍後再試", tone: "danger" });
      return;
    }
    toast({ title: "已通過申請", message: `邀請碼已自動寄送至 ${approveApp.email}`, icon: "check" });
    setApproveApp(null);
    await loadApplications();
  }

  async function doReject(reason) {
    const res = await fetch(`/api/admin/applications/${rejectApp.id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action: "reject", reason, adminEmail }),
    });
    if (!res.ok) {
      const data = await res.json().catch(() => ({}));
      toast({ title: "操作失敗", message: data.error || "請稍後再試", tone: "danger" });
      return;
    }
    toast({ title: "已拒絕申請", message: `${rejectApp.name} · 申請已標記為拒絕`, tone: "danger" });
    setRejectApp(null);
    await loadApplications();
  }

  return (
    <div className="fade-in">
      <PageHeader
        title="創作者申請審核"
        subtitle={`${counts.pending} 件待審核`}
        actions={<>
          <Button variant="secondary" icon="refresh" onClick={loadApplications}>重新整理</Button>
        </>}
      />

      <div style={{ marginBottom: 14 }}>
        <Tabs active={tab} onChange={t => { setTab(t); setSelected(null); }} tabs={[
          { value: "pending", label: "待審核", count: counts.pending },
          { value: "approved", label: "已通過", count: counts.approved },
          { value: "rejected", label: "已拒絕", count: counts.rejected },
          { value: "all", label: "全部", count: counts.all },
        ]}/>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "340px 1fr", gap: 16, alignItems: "flex-start" }}>
        {/* LEFT: list */}
        <Card padding={0} style={{ overflow: "hidden" }}>
          <div style={{ padding: "10px 12px", borderBottom: "1px solid var(--border)" }}>
            <Input icon="search" placeholder="搜尋姓名、ID、Email…" value={query} onChange={e => setQuery(e.target.value)}/>
          </div>
          <div style={{ maxHeight: "calc(100vh - 280px)", overflow: "auto" }}>
            {loading && (
              <div style={{ padding: "40px 16px", textAlign: "center", color: "var(--ink-4)", fontSize: 13 }}>
                載入中…
              </div>
            )}
            {!loading && filtered.length === 0 && (
              <div style={{ padding: "40px 16px", textAlign: "center", color: "var(--ink-4)", fontSize: 13 }}>
                <Icon name="shield" size={24} style={{ color: "var(--success)", marginBottom: 8 }}/>
                <div>目前沒有{tab === "pending" ? "待審" : ""}申請</div>
              </div>
            )}
            {filtered.map(a => {
              const active = selected?.id === a.id;
              const typeLabel = a.creatorType === "illustrator" ? "繪圖創作者" : "文字創作者";
              return (
                <button key={a.id} onClick={() => setSelected(a)} style={{
                  width: "100%", padding: "12px 14px", textAlign: "left",
                  display: "flex", gap: 10, alignItems: "flex-start",
                  borderBottom: "1px solid var(--border)",
                  background: active ? "var(--surface-2)" : "transparent",
                  borderLeft: "3px solid " + (active ? "var(--accent)" : "transparent"),
                }}>
                  <Avatar hue={a.avatar.hue} glyph={a.avatar.glyph} size={34}/>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 500, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.name}</div>
                    <div className="mono" style={{ fontSize: 11.5, color: "var(--ink-3)", marginTop: 2 }}>{a.email}</div>
                    <div style={{ display: "flex", gap: 6, marginTop: 6, flexWrap: "wrap" }}>
                      <Badge tone="accent" size="sm">{typeLabel}</Badge>
                    </div>
                    <div style={{ fontSize: 11, color: "var(--ink-4)", marginTop: 6 }}>{a.submittedAt}</div>
                  </div>
                  {a.status !== "pending" && (
                    <Badge tone={a.status === "approved" ? "success" : "danger"} size="sm" dot>
                      {a.status === "approved" ? "通過" : "拒絕"}
                    </Badge>
                  )}
                </button>
              );
            })}
          </div>
        </Card>

        {/* RIGHT: detail */}
        {selected ? (
          <ApplicationDetail
            app={selected}
            onApprove={() => setApproveApp(selected)}
            onReject={() => setRejectApp(selected)}
          />
        ) : (
          <Card padding={60} style={{ textAlign: "center", color: "var(--ink-4)" }}>
            選取左側申請以查看詳情
          </Card>
        )}
      </div>

      {/* APPROVE DIALOG */}
      <ConfirmDialog
        open={!!approveApp} onClose={() => setApproveApp(null)}
        onConfirm={doApprove}
        title={<span><Icon name="check" size={14} style={{ color: "var(--success)", marginRight: 6 }}/>通過申請 · {approveApp?.name || ""}</span>}
        description={<>確認通過後，系統將自動產生邀請碼並寄送至 <b>{approveApp?.email || "申請人 Email"}</b>，無需其他操作。</>}
        variant="info"
        icon="check"
        confirmText="通過並發送邀請碼"
      />

      {/* REJECT DIALOG */}
      <ConfirmDialog
        open={!!rejectApp} onClose={() => setRejectApp(null)}
        onConfirm={({ reason }) => doReject(reason)}
        title={`拒絕申請 · ${rejectApp?.name || ""}`}
        description="申請將被標記為已拒絕。申請人可稍後重新提交申請。"
        variant="danger"
        icon="x"
        confirmText="拒絕申請"
        requireReason
        reasonLabel="拒絕理由（選填）"
        reasonPlaceholder="例：作品集數量不足，或與平台風格不符"
      />
    </div>
  );
};

// ============== Text file preview modal ==============

const TextFilePreviewModal = ({ item, onClose }) => {
  const [content, setContent] = useState(null); // string (plain) | { __html: string } (docx)
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [size, setSize] = useState({ width: 760, height: 580 });
  const ext = (item.filename || "").split(".").pop().toLowerCase();
  const isPdf = ext === "pdf";
  const isDocx = ext === "docx";
  const isDoc = ext === "doc";  // old binary — use iframe viewer

  useEffect(() => {
    if (isPdf || isDoc) { setLoading(false); return; }
    setLoading(true);
    fetch(item.content)
      .then(r => {
        if (!r.ok) throw new Error("fetch failed");
        return isDocx ? r.arrayBuffer() : r.text();
      })
      .then(data => {
        if (isDocx) {
          return mammoth.convertToHtml({ arrayBuffer: data })
            .then(result => setContent({ __html: result.value }));
        }
        setContent(data);
      })
      .then(() => setLoading(false))
      .catch(() => { setError("無法載入檔案內容"); setLoading(false); });
  }, [item.content, isDocx, isDoc, isPdf]);

  const handleResizeStart = (e) => {
    e.preventDefault();
    const startX = e.clientX;
    const startY = e.clientY;
    const startW = size.width;
    const startH = size.height;
    const onMove = (me) => {
      setSize({
        width:  Math.max(420, Math.min(window.innerWidth  - 48, startW + me.clientX - startX)),
        height: Math.max(300, Math.min(window.innerHeight - 48, startH + me.clientY - startY)),
      });
    };
    const onUp = () => {
      document.removeEventListener("mousemove", onMove);
      document.removeEventListener("mouseup", onUp);
    };
    document.addEventListener("mousemove", onMove);
    document.addEventListener("mouseup", onUp);
  };

  return (
    <div
      style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.5)", zIndex: 200, display: "flex", alignItems: "center", justifyContent: "center" }}
      onClick={e => { if (e.target === e.currentTarget) onClose(); }}
    >
      <div style={{
        background: "var(--surface)", borderRadius: 16, boxShadow: "var(--shadow-lg)",
        width: size.width, height: size.height,
        maxWidth: "calc(100vw - 32px)", maxHeight: "calc(100vh - 32px)",
        display: "flex", flexDirection: "column", position: "relative",
      }}>
        <div style={{ padding: "14px 20px", borderBottom: "1px solid var(--border)", display: "flex", alignItems: "center", justifyContent: "space-between", flexShrink: 0 }}>
          <div style={{ fontSize: 14, fontWeight: 600, color: "var(--ink-2)" }}>{item.filename}</div>
          <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
            <a href={item.content} target="_blank" rel="noreferrer" style={{ fontSize: 12, color: "var(--accent-ink)", fontWeight: 500 }}>另開下載</a>
            <button onClick={onClose} style={{ color: "var(--ink-3)", padding: 4 }}><Icon name="x" size={18}/></button>
          </div>
        </div>
        <div style={{ flex: 1, overflow: "auto", minHeight: 0, padding: isPdf || isDoc ? 0 : 20 }}>
          {(isPdf || isDoc) ? (
            <iframe
              src={isPdf ? item.content : `https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(item.content)}`}
              style={{ width: "100%", height: "100%", border: "none" }}
              title={item.filename}
            />
          ) : loading ? (
            <div style={{ textAlign: "center", padding: "48px 0", color: "var(--ink-4)", fontSize: 13 }}>載入中…</div>
          ) : error ? (
            <div style={{ textAlign: "center", padding: "48px 0", color: "var(--danger)", fontSize: 13 }}>{error}</div>
          ) : content && typeof content === "object" ? (
            <div
              dangerouslySetInnerHTML={content}
              style={{ fontSize: 14, lineHeight: 1.8, color: "var(--ink-2)" }}
            />
          ) : (
            <pre style={{ fontFamily: "var(--font-mono)", fontSize: 13, lineHeight: 1.7, whiteSpace: "pre-wrap", wordBreak: "break-word", color: "var(--ink-2)", margin: 0 }}>
              {content}
            </pre>
          )}
        </div>

        {/* Resize handle — bottom-right corner */}
        <div
          onMouseDown={handleResizeStart}
          title="拖曳調整大小"
          style={{ position: "absolute", bottom: 0, right: 0, width: 20, height: 20, cursor: "nwse-resize", zIndex: 1, borderRadius: "0 0 16px 0" }}
        >
          <svg width="20" height="20" viewBox="0 0 20 20" fill="none" style={{ display: "block" }}>
            <line x1="5"  y1="17" x2="17" y2="5"  stroke="var(--border-strong)" strokeWidth="1.5" strokeLinecap="round"/>
            <line x1="9"  y1="17" x2="17" y2="9"  stroke="var(--border-strong)" strokeWidth="1.5" strokeLinecap="round"/>
            <line x1="13" y1="17" x2="17" y2="13" stroke="var(--border-strong)" strokeWidth="1.5" strokeLinecap="round"/>
          </svg>
        </div>
      </div>
    </div>
  );
};

// ============== Application detail ==============

const ApplicationDetail = ({ app, onApprove, onReject }) => {
  const [previewItem, setPreviewItem] = useState(null);
  const isPending = app.status === "pending";
  const typeLabel = app.creatorType === "illustrator" ? "繪圖創作者" : "文字創作者";

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      {/* Header card */}
      <Card padding={24}>
        <div style={{ display: "flex", gap: 16, alignItems: "flex-start" }}>
          <Avatar hue={app.avatar.hue} glyph={app.avatar.glyph} size={72}/>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
              <h2 style={{ fontSize: 22, fontWeight: 600 }}>{app.name}</h2>
              {isPending && <Badge tone="warn" dot>待審核</Badge>}
              {!isPending && (
                <Badge tone={app.status === "approved" ? "success" : "danger"} dot>
                  {app.status === "approved" ? "已通過" : "已拒絕"}
                </Badge>
              )}
              <Badge tone="accent">{typeLabel}</Badge>
            </div>
            <div style={{ fontSize: 13, color: "var(--ink-3)", marginTop: 4, display: "flex", gap: 10, flexWrap: "wrap" }}>
              <span className="mono">{app.email}</span>
              {app.uid && <><span>·</span><span className="mono">#{app.uid}</span></>}
              <span>·</span>
              <span>提交於 {app.submittedAt}</span>
            </div>
          </div>
        </div>
      </Card>

      {/* Social media */}
      <Card padding={24}>
        <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 12 }}>社交平台帳號</div>
        <div style={{ fontSize: 13.5, color: "var(--ink-2)", fontFamily: "monospace" }}>
          {app.socialMedia}
        </div>
      </Card>

      {/* Portfolio */}
      <Card padding={24}>
        <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 14 }}>
          作品集 <span style={{ color: "var(--ink-3)", fontWeight: 400, marginLeft: 6 }}>{(app.portfolio || []).length} 件</span>
        </div>
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          {(app.portfolio || []).map((item, i) => (
            <div key={i} style={{ border: "1px solid var(--border)", borderRadius: 10, overflow: "hidden" }}>
              {(item.type === "image" || item.type === "image_url") ? (
                <div>
                  <div style={{ padding: "8px 12px", background: "var(--surface-2)", fontSize: 11, color: "var(--ink-4)", display: "flex", alignItems: "center", gap: 6 }}>
                    <Icon name="palette" size={12}/>
                    圖片作品 {i + 1}
                  </div>
                  {item.content && (
                    <div style={{ padding: "10px 12px" }}>
                      <div style={{ borderRadius: 8, overflow: "hidden", maxHeight: 300, background: "var(--surface-2)", display: "flex", alignItems: "center", justifyContent: "center" }}>
                        <img
                          src={item.content}
                          alt={`作品 ${i + 1}`}
                          style={{ maxWidth: "100%", maxHeight: 300, objectFit: "contain" }}
                          onError={e => { e.target.style.display = "none"; }}
                        />
                      </div>
                    </div>
                  )}
                </div>
              ) : (
                <div>
                  <div style={{ padding: "8px 12px", background: "var(--surface-2)", fontSize: 11, color: "var(--ink-4)", display: "flex", alignItems: "center", gap: 6 }}>
                    <Icon name={item.filename ? "file" : "edit"} size={12}/>
                    {item.filename ? `文字檔案 ${i + 1}` : `文字描述 ${i + 1}`}
                    {item.filename && (
                      <button
                        onClick={() => setPreviewItem(item)}
                        style={{ marginLeft: "auto", padding: "2px 10px", borderRadius: 6, fontSize: 11, background: "var(--accent)", color: "#fff", fontWeight: 500 }}
                      >
                        預覽
                      </button>
                    )}
                  </div>
                  {item.filename ? (
                    <div style={{ padding: "8px 12px", fontSize: 12, color: "var(--ink-3)", fontFamily: "var(--font-mono)" }}>
                      {item.filename}
                    </div>
                  ) : (
                    <div style={{ padding: "10px 12px", fontSize: 13.5, color: "var(--ink-2)", lineHeight: 1.7, whiteSpace: "pre-wrap" }}>
                      {item.content}
                    </div>
                  )}
                </div>
              )}
            </div>
          ))}
        </div>
      </Card>

      {previewItem && <TextFilePreviewModal item={previewItem} onClose={() => setPreviewItem(null)}/>}

      {/* Actions */}
      {isPending ? (
        <div style={{
          display: "flex", gap: 10, padding: "14px 20px",
          background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 12,
          position: "sticky", bottom: 0,
        }}>
          <div style={{ flex: 1 }}/>
          <Button variant="secondary" onClick={onReject} style={{ color: "var(--danger)" }}>
            <Icon name="x" size={15}/> 拒絕
          </Button>
          <Button variant="primary" icon="check" onClick={onApprove}>通過申請</Button>
        </div>
      ) : (
        <Card padding={16} style={{ background: app.status === "approved" ? "var(--success-soft)" : "var(--danger-soft)" }}>
          <div style={{ fontSize: 12.5, color: "var(--ink-2)" }}>
            此申請已於 {app.reviewedAt || app.submittedAt} 由 <b>{app.reviewedBy || "管理員"}</b>{" "}
            {app.status === "approved" ? "通過" : "拒絕"}
            {app.rejectReason && <> · 理由：{app.rejectReason}</>}
          </div>
        </Card>
      )}
    </div>
  );
};

window.ApplicationsPage = ApplicationsPage;
