/* ============================================================
   FileManager — interactive CDE document browser
   ============================================================ */
const { useState: useStateFM, useRef: useRefFM, useEffect: useEffectFM } = React;

/* ---------- Folder tree (sidebar of the doc module) ---------- */
function TreeNode({ id, cur, setCur, expanded, toggle, depth }) {
  const f = folderById(id);
  const kids = childFolders(id);
  const isOpen = expanded.has(id);
  const active = cur === id;
  return (
    <div>
      <div onClick={() => setCur(id)}
        style={{ display: "flex", alignItems: "center", gap: 7, cursor: "pointer", padding: "7px 8px",
          paddingLeft: 8 + depth * 14, borderRadius: 8, marginBottom: 1,
          background: active ? "var(--accent-soft)" : "transparent",
          color: active ? "var(--accent)" : "var(--ink-2)", fontSize: 13, fontWeight: active ? 700 : 600 }}>
        {kids.length ? (
          <span onClick={(e) => { e.stopPropagation(); toggle(id); }} title={isOpen ? "Thu lại" : "Mở ra"}
            style={{ display: "grid", placeItems: "center", width: 18, height: 18, marginLeft: -3, marginRight: -4, borderRadius: 5, flex: "none", cursor: "pointer" }}>
            <Icon.chevR size={13} color={active ? "var(--accent)" : "var(--ink-4)"}
              style={{ transform: isOpen ? "rotate(90deg)" : "none", transition: ".15s" }} />
          </span>
        ) : <span style={{ width: 13, flex: "none" }} />}
        {f.disc
          ? <span style={{ width: 9, height: 9, borderRadius: 3, background: DISC_COL[f.disc], flex: "none" }} />
          : <Icon.layers size={15} color={active ? "var(--accent)" : "var(--ink-3)"} style={{ flex: "none" }} />}
        <span style={{ flex: 1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{f.name}</span>
        {f.tag && <span style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: ".04em", color: "var(--ink-4)",
          border: "1px solid var(--line)", borderRadius: 5, padding: "1px 5px" }}>{f.tag}</span>}
      </div>
      {isOpen && kids.map(k => (
        <TreeNode key={k.id} id={k.id} cur={cur} setCur={setCur} expanded={expanded} toggle={toggle} depth={depth + 1} />
      ))}
    </div>
  );
}

/* ---------- Review workflow stepper ---------- */
function ReviewFlow({ status }) {
  const order = { wip: 0, review: 1, changes: 1, shared: 2, approved: 2, published: 3 };
  const cur = order[status] ?? 0;
  const steps = [
    { k: "WIP", ic: "clock" }, { k: "Duyệt", ic: "eye" },
    { k: "Chia sẻ", ic: "link" }, { k: "Phát hành", ic: "check" },
  ];
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 0, margin: "4px 0 6px" }}>
      {steps.map((s, i) => {
        const done = i < cur, active = i === cur;
        const Ico = Icon[s.ic];
        const col = status === "changes" && i === 1 ? "var(--danger)" : "var(--accent)";
        return (
          <React.Fragment key={i}>
            <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 6, flex: "none" }}>
              <span style={{ width: 30, height: 30, borderRadius: 99, display: "grid", placeItems: "center", flex: "none",
                background: done || active ? col : "var(--sunken)",
                color: done || active ? "#fff" : "var(--ink-4)",
                boxShadow: active ? `0 0 0 4px ${status==="changes"&&i===1?"rgba(239,68,68,.15)":"var(--accent-soft)"}` : "none" }}>
                {done ? <Icon.check size={15} /> : <Ico size={14} />}
              </span>
              <span style={{ fontSize: 10.5, fontWeight: 700, color: active ? "var(--ink)" : "var(--ink-4)" }}>{s.k}</span>
            </div>
            {i < steps.length - 1 && (
              <div style={{ flex: 1, height: 2, background: i < cur ? "var(--accent)" : "var(--line)", marginBottom: 18 }} />
            )}
          </React.Fragment>
        );
      })}
    </div>
  );
}

/* ---------- Detail drawer ---------- */
/* FR-4 — gated four-state transitions */
const TRANSITIONS = {
  wip:       [["Gửi duyệt", "review", true]],
  review:    [["Duyệt → Chia sẻ", "shared", true], ["Từ chối", "changes", false]],
  changes:   [["Gửi lại", "review", true]],
  shared:    [["Duyệt", "approved", true]],
  approved:  [["Phát hành", "published", true]],
  published: [],
};

function DetailDrawer({ file, onClose, live, onChanged }) {
  const [tab, setTab] = useStateFM("versions");
  const [busy, setBusy] = useStateFM(false);
  const [pdfUrl, setPdfUrl] = useStateFM(null);
  if (!file) return null;
  const st = STATUS[file.status];
  const acts = live ? (TRANSITIONS[file.status] || []) : [];

  const dl = (key) => {
    if (!key) { window.alert("Phiên bản này chưa có tệp đính kèm (dữ liệu mẫu)."); return; }
    window.open(cdeData.downloadUrl(key), "_blank");
  };
  const doTransition = async (to) => {
    setBusy(true);
    try { await cdeData.setContainerStatus(file.id, to); onChanged && onChanged(to); }
    catch (e) { window.alert("Đổi trạng thái thất bại: " + e.message); }
    finally { setBusy(false); }
  };
  const openPdf = () => {
    const key = file.versions && file.versions[0] && file.versions[0].r2_key;
    if (!key) { window.alert("Chưa có tệp PDF đính kèm (dữ liệu mẫu). Hãy nạp một tệp PDF để xem."); return; }
    setPdfUrl(cdeData.objectUrl(key));
  };
  return (
    <div style={{ width: 396, flex: "none", borderLeft: "1px solid var(--line)", background: "var(--surface)",
      display: "flex", flexDirection: "column", minHeight: 0,
      position: "absolute", top: 0, right: 0, bottom: 0, zIndex: 20, boxShadow: "var(--shadow-lg)",
      animation: "drawerIn .22s cubic-bezier(.2,.8,.2,1)" }}>
      <div style={{ padding: "16px 18px", borderBottom: "1px solid var(--line)", display: "flex", alignItems: "flex-start", gap: 10 }}>
        <TypeIcon type={file.type} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="mono" style={{ fontSize: 13.5, fontWeight: 700, color: "var(--ink)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{file.name}</div>
          <div style={{ fontSize: 12, color: "var(--ink-3)", fontWeight: 500, marginTop: 2 }}>{file.desc}</div>
        </div>
        <button className="icon-btn" style={{ width: 30, height: 30, borderRadius: 8, flex: "none" }} onClick={onClose}>
          <span style={{ fontSize: 18, lineHeight: 0 }}>✕</span>
        </button>
      </div>

      <div style={{ flex: 1, overflowY: "auto", padding: 18 }}>
        <SheetPreview file={file} big />
        <div style={{ display: "flex", gap: 8, margin: "14px 0 4px" }}>
          <span className={`chip ${st.cls}`}>{(()=>{const Ico=Icon[st.icon];return <Ico size={12}/>;})()} {st.label}</span>
          <span className="tag-mono" style={{ height: 26, display: "inline-flex", alignItems: "center", fontWeight: 700 }}>REV {file.rev}</span>
          <span className={`chip ${file.disc}`}>{DISC_NAME[file.disc]}</span>
        </div>

        {file.type === "PDF" && (
          <button className="btn sm" style={{ width: "100%", justifyContent: "center", marginTop: 6 }} onClick={openPdf}>
            <Icon.eye size={14} /> Xem PDF (2D)
          </button>
        )}

        <div style={{ margin: "18px 0 4px", padding: "14px 14px 6px", background: "var(--sunken)", borderRadius: 12 }}>
          <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: ".06em", color: "var(--ink-4)", marginBottom: 10 }}>QUY TRÌNH DUYỆT · ISO 19650</div>
          <ReviewFlow status={file.status} />
        </div>

        {/* tabs */}
        <div className="seg" style={{ width: "100%", margin: "16px 0 14px" }}>
          {[["versions","Phiên bản"],["props","Thuộc tính"],["activity","Hoạt động"]].map(([k,l])=>(
            <button key={k} className={tab===k?"on":""} style={{ flex: 1 }} onClick={()=>setTab(k)}>{l}</button>
          ))}
        </div>

        {tab === "versions" && (
          <div style={{ display: "flex", flexDirection: "column" }}>
            {file.versions.map((vv,i) => {
              const vst = STATUS[vv.status];
              return (
                <div key={i} style={{ display: "flex", gap: 12, paddingBottom: 16, position: "relative" }}>
                  <div style={{ display: "flex", flexDirection: "column", alignItems: "center", flex: "none" }}>
                    <span style={{ width: 26, height: 26, borderRadius: 99, display: "grid", placeItems: "center", flex: "none",
                      background: i===0 ? "var(--accent)" : "var(--sunken)", color: i===0?"#fff":"var(--ink-3)",
                      fontFamily: "var(--mono)", fontSize: 9.5, fontWeight: 700 }}>{vv.rev}</span>
                    {i < file.versions.length-1 && <span style={{ width: 2, flex: 1, background: "var(--line)", marginTop: 2 }} />}
                  </div>
                  <div style={{ flex: 1, minWidth: 0, paddingTop: 1 }}>
                    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                      <span style={{ fontSize: 13, fontWeight: 700, whiteSpace: "nowrap" }}>{vv.by}</span>
                      {i===0 && <span className="chip ok" style={{ height: 20, fontSize: 10, flex: "none" }}>Hiện hành</span>}
                    </div>
                    <div style={{ fontSize: 11.5, color: "var(--ink-3)", marginTop: 3, fontWeight: 500, display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap" }}>
                      <span style={{ whiteSpace: "nowrap" }}>{vv.date}</span>
                      <span className={`chip ${vst.cls}`} style={{ height: 18, fontSize: 10, padding: "0 6px" }}>{vst.label}</span>
                    </div>
                    {vv.note && <div style={{ fontSize: 12, color: "var(--ink-2)", marginTop: 5, fontWeight: 500 }}>{vv.note}</div>}
                  </div>
                  <button className="btn sm" style={{ height: 28, padding: "0 9px", flex: "none" }}
                    onClick={() => dl(vv.r2_key)} title={vv.r2_key ? "Tải bản này" : "Chưa có tệp đính kèm"}><Icon.download size={13} /></button>
                </div>
              );
            })}
          </div>
        )}

        {tab === "props" && (
          <div>
            {[["Mã hồ sơ", file.name],["Bộ môn", DISC_NAME[file.disc]],["Định dạng", file.type],["Phiên bản", file.rev],
              ["Dung lượng", file.size],["Người cập nhật", file.by],["Thời gian", file.date],["Trạng thái", STATUS[file.status].label],
              ["Suitability", SUITABILITY[STATUS[file.status].suit] || "—"]].map(([k,val],i)=>(
              <div key={i} style={{ display: "flex", justifyContent: "space-between", padding: "11px 0", borderBottom: "1px solid var(--line-soft)", fontSize: 13, gap: 14 }}>
                <span style={{ color: "var(--ink-3)", fontWeight: 600, flex: "none" }}>{k}</span>
                <span style={{ fontWeight: 700, textAlign: "right", fontFamily: i===0||i===3?"var(--mono)":"inherit", fontSize: i===0||i===3?12:13, whiteSpace: i===0?"nowrap":"normal", overflow: "hidden", textOverflow: "ellipsis" }}>{val}</span>
              </div>
            ))}
          </div>
        )}

        {tab === "activity" && (
          <div className="feed">
            {[["upload","var(--accent)","tải lên phiên bản",file.rev,file.by,file.date.split("·")[1]||file.date],
              ["check","var(--ok)","phê duyệt hồ sơ",null,"Phạm Tuấn","Hôm qua"],
              ["link","var(--str)","chia sẻ phối hợp",null,file.by,"2 ngày"],
              ["eye","var(--info)","xem & tải về",null,"Đỗ Hải","3 ngày"]].map(([ic,c,act,code,who,t],i)=>{
              const Ico = Icon[ic];
              return (
                <div className="feed-item" key={i}>
                  <div className="feed-ico" style={{ background: `${c}1f`, color: c }}><Ico size={14} /></div>
                  <div className="feed-main"><div className="feed-t"><b>{who}</b> {act} {code && <span className="tag-mono">{code}</span>}</div></div>
                  <div className="feed-time">{t}</div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      <div style={{ padding: 14, borderTop: "1px solid var(--line)", display: "flex", gap: 8, flexWrap: "wrap" }}>
        <button className="btn sm" style={{ flex: 1, justifyContent: "center", minWidth: 110 }}
          onClick={() => dl(file.versions?.[0]?.r2_key)}><Icon.download size={14} /> Tải về</button>
        {live ? (
          acts.length ? acts.map(([label, to, primary]) => (
            <button key={to} className={`btn sm ${primary ? "primary" : ""}`} disabled={busy}
              style={{ flex: 1.2, justifyContent: "center", minWidth: 120, opacity: busy ? .6 : 1 }}
              onClick={() => doTransition(to)}>
              {primary ? <Icon.checkCircle size={14} /> : <Icon.eyeOff size={14} />} {label}
            </button>
          )) : <button className="btn sm" disabled style={{ flex: 1.2, justifyContent: "center", opacity: .55 }}><Icon.check size={14} /> Đã phát hành</button>
        ) : (
          <button className="btn sm primary" style={{ flex: 1.2, justifyContent: "center" }}><Icon.checkCircle size={14} /> Duyệt</button>
        )}
      </div>
      {pdfUrl && <PdfViewer url={pdfUrl} name={file.name} onClose={() => setPdfUrl(null)} />}
    </div>
  );
}

window.TreeNode = TreeNode;
window.DetailDrawer = DetailDrawer;
window.ReviewFlow = ReviewFlow;
