/* ============================================================
   Issues · BCF – Quản lý vấn đề dựa trên mô hình
   ============================================================ */

/* useState comes from the global declared in ui.jsx (no redeclare) */

/* ── Status meta (BCF lifecycle) ──────────────────────────── */
const ISS_STATUS = {
  open:      { label: "Open",       cls: "info",   icon: "flag" },
  progress:  { label: "In Progress", cls: "warn",   icon: "clock" },
  closed:    { label: "Closed",     cls: "ok",     icon: "checkCircle" },
  reopened:  { label: "ReOpened",   cls: "danger", icon: "alert" },
};

/* ── Priority chip class map ──────────────────────────────── */
const PRI_CLS = { Cao: "danger", TB: "warn", Thấp: "idle" };

/* ── Helper to get icon component by key ──────────────────── */
function getIcon(key) {
  const iconMap = {
    flag: Icon.flag,
    clock: Icon.clock,
    checkCircle: Icon.checkCircle,
    alert: Icon.alert,
  };
  return iconMap[key] || Icon.flag;
}

/* ── Sample data ──────────────────────────────────────────── */
const ISSUES = [
  {
    id: "ISS-112",
    title: "Cột STR đè ống gió HVAC trục B",
    disc: "str",
    who: "Trần Đức",
    due: "10/06",
    pri: "Cao",
    status: "open",
    guid: "3A$kP2x9QHugABCdef01",
    sheet: "STR-Frame-Station-C",
    desc: "Cột BTCT C-14 giao cắt tuyến ống gió chính cao độ +18.4m. Cần dịch tuyến ống hoặc chỉnh kích thước cột.",
    comments: [
      { who: "Trần Đức", t: "Phát hiện khi tổ hợp tuần 23", time: "2 giờ" },
      { who: "Lê Hồng", t: "Kết cấu không thể dịch cột, đề nghị MEP định tuyến lại", time: "1 giờ" },
    ],
  },
  {
    id: "ISS-111",
    title: "Cao độ ke ga L3 lệch bản vẽ",
    disc: "inf",
    who: "Nguyễn Minh",
    due: "08/06",
    pri: "TB",
    status: "progress",
    guid: "1F$mN4t7RJkxGHIjkl23",
    sheet: "INF-Drainage-L3",
    desc: "Cao độ ke ga chênh 35mm so với bản vẽ phát hành. Đang rà soát mô hình hạ tầng.",
    comments: [
      { who: "Nguyễn Minh", t: "Đang cập nhật lại cao độ", time: "3 giờ" },
    ],
  },
  {
    id: "ISS-110",
    title: "Mặt đứng ga C thiếu thông tin vật liệu",
    disc: "arc",
    who: "Vũ Lan",
    due: "12/06",
    pri: "Thấp",
    status: "open",
    guid: "7C$qR8w2KLmnNOPqrs45",
    sheet: "ARC-Facade-GaC",
    desc: "Một số panel mặt đứng chưa gán vật liệu, cần bổ sung trước khi phát hành.",
    comments: [],
  },
  {
    id: "ISS-108",
    title: "Va chạm máng cáp điện vs dầm B-04",
    disc: "mep",
    who: "Bùi An",
    due: "05/06",
    pri: "Cao",
    status: "reopened",
    guid: "9D$tU3y5MNopPQRtuv67",
    sheet: "MEP-Electrical-L2",
    desc: "Máng cáp xuyên dầm B-04. Lần sửa trước chưa triệt để, mở lại.",
    comments: [
      { who: "Bùi An", t: "Đã hạ cao độ máng 120mm", time: "Hôm qua" },
      { who: "Trần Đức", t: "Vẫn còn chạm 40mm, mở lại issue", time: "4 giờ" },
    ],
  },
  {
    id: "ISS-105",
    title: "Vỏ hầm TBM — chốt thiết kế",
    disc: "inf",
    who: "Đỗ Hải",
    due: "01/06",
    pri: "Cao",
    status: "closed",
    guid: "2B$vW6z8OPqrQRStuw89",
    sheet: "INF-Tunnel-TBM-L3",
    desc: "Thiết kế vỏ hầm đã được duyệt, đóng issue.",
    comments: [
      { who: "Đỗ Hải", t: "Đã chốt và phát hành C01", time: "3 ngày" },
    ],
  },
];

/* ── Component A: faux BCF viewpoint snapshot ─────────────── */
function Viewpoint({ disc }) {
  return (
    <div
      style={{
        height: 180,
        borderRadius: 10,
        overflow: "hidden",
        background: "radial-gradient(120% 120% at 50% 0%, #14323a, #0b1c21)",
        display: "grid",
        placeItems: "center",
        position: "relative",
      }}
    >
      {/* grid overlay */}
      <div
        style={{
          position: "absolute",
          inset: 0,
          backgroundImage:
            "linear-gradient(rgba(120,200,190,.12) 1px,transparent 1px),linear-gradient(90deg,rgba(120,200,190,.12) 1px,transparent 1px)",
          backgroundSize: "22px 22px",
        }}
      />
      <Icon.cube size={48} color={DISC_COL[disc]} />
      {/* marker pin */}
      <div
        style={{
          position: "absolute",
          top: "40%",
          left: "55%",
          width: 22,
          height: 22,
          borderRadius: "50%",
          background: "var(--danger)",
          color: "#fff",
          display: "grid",
          placeItems: "center",
          boxShadow: "0 0 0 6px rgba(239,68,68,.25)",
        }}
      >
        <Icon.pin size={12} />
      </div>
      {/* label */}
      <span
        className="tag-mono"
        style={{
          position: "absolute",
          bottom: 8,
          left: 8,
          background: "rgba(255,255,255,.08)",
          color: "#cfe9e5",
          fontSize: 10,
        }}
      >
        BCF viewpoint
      </span>
    </div>
  );
}

/* ── Component B: right drawer ────────────────────────────── */
function IssueDrawer({ iss, onClose, live, actor, onChanged }) {
  const statusMeta = ISS_STATUS[iss.status];
  const priCls = PRI_CLS[iss.pri] || "idle";
  const IconComp = getIcon(statusMeta.icon);
  const [busy, setBusy] = useState(false);
  const [cmt, setCmt] = useState("");
  const canWrite = live && iss._id;
  const changeStatus = async (s) => {
    setBusy(true);
    try { await cdeData.setIssueStatus(iss._id, s); onChanged && onChanged(); }
    catch (e) { window.alert("Đổi trạng thái thất bại: " + e.message); }
    finally { setBusy(false); }
  };
  const sendComment = async () => {
    if (!cmt.trim()) return;
    setBusy(true);
    try { await cdeData.addComment(iss._id, actor || "Bạn", cmt.trim()); setCmt(""); onChanged && onChanged(); }
    catch (e) { window.alert("Gửi bình luận thất bại: " + e.message); }
    finally { setBusy(false); }
  };

  const initials = (name) => {
    const parts = name.split(" ");
    return parts.length > 1 ? parts[parts.length - 1][0] : name[0];
  };

  return (
    <div
      style={{
        flex: "none",
        width: 420,
        borderLeft: "1px solid var(--line)",
        background: "var(--surface)",
        display: "flex",
        flexDirection: "column",
        position: "absolute",
        top: 0,
        right: 0,
        bottom: 0,
        zIndex: 20,
        boxShadow: "var(--shadow-lg)",
      }}
    >
      {/* header */}
      <div
        style={{
          padding: "16px 18px",
          borderBottom: "1px solid var(--line)",
          display: "flex",
          alignItems: "flex-start",
          gap: 12,
        }}
      >
        <div style={{ flex: 1 }}>
          <span className="tag-mono">{iss.id}</span>
          <div className="t-strong" style={{ fontSize: 14, marginTop: 4 }}>
            {iss.title}
          </div>
        </div>
        <button className="icon-btn" onClick={onClose}>
          <span>✕</span>
        </button>
      </div>

      {/* body */}
      <div style={{ flex: 1, overflowY: "auto", padding: 18 }}>
        <Viewpoint disc={iss.disc} />

        {/* chips row */}
        <div style={{ marginTop: 14, display: "flex", gap: 8 }}>
          {/* status chip */}
          <span className={`chip ${statusMeta.cls}`}>
            <IconComp size={12} /> {statusMeta.label}
          </span>
          {/* priority chip */}
          <span className={`chip ${priCls}`}>
            Ưu tiên {iss.pri}
          </span>
          {/* discipline chip */}
          <span className={`chip ${iss.disc}`}>
            {DISC_NAME[iss.disc]}
          </span>
        </div>

        {/* description */}
        <p
          style={{
            marginTop: 14,
            fontSize: 13,
            color: "var(--ink-2)",
            lineHeight: 1.5,
          }}
        >
          {iss.desc}
        </p>

        {/* meta rows */}
        {[
          { label: "Phụ trách", value: iss.who },
          { label: "Hạn xử lý", value: iss.due },
          {
            label: "Sheet liên kết",
            value: <span className="mono">{iss.sheet}</span>,
          },
          {
            label: "IFC GUID",
            value: <span className="mono" style={{ fontSize: 11 }}>{iss.guid}</span>,
          },
        ].map((row, i) => (
          <div
            key={i}
            style={{
              display: "flex",
              justifyContent: "space-between",
              padding: "11px 0",
              borderBottom: "1px solid var(--line-soft)",
              fontSize: 13,
            }}
          >
            <span style={{ color: "var(--ink-3)" }}>{row.label}</span>
            <span>{row.value}</span>
          </div>
        ))}

        {/* discussion section */}
        <div
          style={{
            fontSize: 11,
            fontWeight: 700,
            letterSpacing: ".06em",
            color: "var(--ink-4)",
            margin: "18px 0 10px",
          }}
        >
          THẢO LUẬN
        </div>

        {iss.comments.length === 0 ? (
          <div style={{ color: "var(--ink-3)", fontSize: 12 }}>
            Chưa có thảo luận
          </div>
        ) : (
          iss.comments.map((c, i) => (
            <div
              key={i}
              style={{
                display: "flex",
                gap: 10,
                padding: "10px 0",
                borderTop: i ? "1px solid var(--line-soft)" : "none",
              }}
            >
              <span
                className="avatar"
                style={{ width: 30, height: 30 }}
              >
                {initials(c.who)}
              </span>
              <div style={{ flex: 1 }}>
                <div className="t-strong" style={{ fontSize: 13 }}>
                  {c.who}
                </div>
                <div
                  style={{
                    fontSize: 12.5,
                    color: "var(--ink-2)",
                    marginTop: 3,
                  }}
                >
                  {c.t}
                </div>
              </div>
              <div
                style={{
                  fontSize: 11,
                  color: "var(--ink-4)",
                  flex: "none",
                }}
              >
                {c.time}
              </div>
            </div>
          ))
        )}
      </div>

      {/* footer */}
      <div style={{ padding: 14, borderTop: "1px solid var(--line)" }}>
        {canWrite && (
          <div style={{ display: "flex", gap: 8, marginBottom: 10 }}>
            <input value={cmt} onChange={(e) => setCmt(e.target.value)} placeholder="Viết bình luận…"
              onKeyDown={(e) => e.key === "Enter" && sendComment()}
              style={{ flex: 1, height: 38, padding: "0 12px", borderRadius: 10, border: "1px solid var(--line)", background: "var(--surface)", color: "var(--ink)", font: "inherit", fontSize: 13, outline: "none" }} />
            <button className="btn sm primary" disabled={busy || !cmt.trim()} onClick={sendComment} style={{ opacity: (busy || !cmt.trim()) ? .6 : 1 }}><Icon.send size={14} /></button>
          </div>
        )}
        <div style={{ display: "flex", gap: 8 }}>
          {canWrite ? (
            iss.status === "closed"
              ? <button className="btn sm" disabled={busy} style={{ flex: 1, justifyContent: "center" }} onClick={() => changeStatus("reopened")}><Icon.alert size={14} /> Mở lại</button>
              : <>
                  {iss.status !== "progress" && <button className="btn sm" disabled={busy} style={{ flex: 1, justifyContent: "center" }} onClick={() => changeStatus("progress")}><Icon.clock size={14} /> Đang xử lý</button>}
                  <button className="btn sm primary" disabled={busy} style={{ flex: 1, justifyContent: "center" }} onClick={() => changeStatus("closed")}><Icon.checkCircle size={14} /> Đóng issue</button>
                </>
          ) : (
            <>
              <button className="btn sm" style={{ flex: 1, justifyContent: "center" }}><Icon.check size={14} /> Đánh dấu xử lý</button>
              <button className="btn sm primary" style={{ flex: 1, justifyContent: "center" }}><Icon.checkCircle size={14} /> Đóng issue</button>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

/* ---------- create issue modal ---------- */
function CreateIssueModal({ live, onClose, onCreated }) {
  const [f, setF] = useState({ title: "", disc: "str", assignee: "", due: "", priority: "TB", sheet: "", descr: "" });
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));
  const submit = async () => {
    if (!f.title.trim()) { setErr("Nhập tiêu đề issue"); return; }
    if (!live) { onClose(); return; }
    setBusy(true); setErr("");
    try { await cdeData.createIssue(f); onCreated && onCreated(); onClose(); }
    catch (e) { setErr(e.message || "Tạo issue thất bại"); }
    finally { setBusy(false); }
  };
  const inp = { width: "100%", height: 38, padding: "0 12px", borderRadius: 10, border: "1px solid var(--line)", background: "var(--surface)", color: "var(--ink)", font: "inherit", fontSize: 13.5, fontWeight: 600, outline: "none", marginTop: 6 };
  const lb = { display: "block", fontSize: 11.5, fontWeight: 700, color: "var(--ink-3)", marginTop: 13 };
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 55, background: "rgba(8,19,23,.5)", backdropFilter: "blur(3px)", display: "grid", placeItems: "center" }}>
      <div onClick={(e) => e.stopPropagation()} className="card" style={{ width: 480, padding: 24, boxShadow: "var(--shadow-lg)", maxHeight: "92vh", overflowY: "auto" }}>
        <div style={{ fontWeight: 800, fontSize: 16, marginBottom: 2 }}>Tạo issue (BCF)</div>
        <div style={{ fontSize: 12.5, color: "var(--ink-3)", fontWeight: 500 }}>{live ? "Lưu vào Supabase" : "Chế độ demo — chưa đăng nhập"}</div>
        <label style={lb}>Tiêu đề</label>
        <input style={inp} value={f.title} onChange={(e) => set("title", e.target.value)} placeholder="VD: Cột STR đè ống gió trục B" />
        <div style={{ display: "flex", gap: 12 }}>
          <div style={{ flex: 1 }}><label style={lb}>Bộ môn</label>
            <select style={inp} value={f.disc} onChange={(e) => set("disc", e.target.value)}>{Object.entries(DISC_NAME).map(([k, v]) => <option key={k} value={k}>{v}</option>)}</select></div>
          <div style={{ flex: 1 }}><label style={lb}>Ưu tiên</label>
            <select style={inp} value={f.priority} onChange={(e) => set("priority", e.target.value)}>{["Cao", "TB", "Thấp"].map(p => <option key={p}>{p}</option>)}</select></div>
        </div>
        <div style={{ display: "flex", gap: 12 }}>
          <div style={{ flex: 1 }}><label style={lb}>Phụ trách</label><input style={inp} value={f.assignee} onChange={(e) => set("assignee", e.target.value)} /></div>
          <div style={{ flex: 1 }}><label style={lb}>Hạn (dd/mm)</label><input style={inp} value={f.due} onChange={(e) => set("due", e.target.value)} placeholder="10/06" /></div>
        </div>
        <label style={lb}>Sheet / mô hình liên kết</label>
        <input style={inp} value={f.sheet} onChange={(e) => set("sheet", e.target.value)} placeholder="STR-Frame-Station-C" />
        <label style={lb}>Mô tả</label>
        <textarea style={{ ...inp, height: 70, padding: "8px 12px" }} value={f.descr} onChange={(e) => set("descr", e.target.value)} />
        {err && <div style={{ marginTop: 12, fontSize: 12.5, color: "var(--danger)", fontWeight: 600 }}>{err}</div>}
        <div style={{ display: "flex", gap: 10, justifyContent: "flex-end", marginTop: 18 }}>
          <button className="btn" onClick={onClose}>Huỷ</button>
          <button className="btn primary" disabled={busy} onClick={submit} style={{ opacity: busy ? .6 : 1 }}><Icon.plus size={14} /> {busy ? "Đang tạo…" : "Tạo issue"}</button>
        </div>
      </div>
    </div>
  );
}

/* ── Component C: main Issues screen ──────────────────────── */
function Issues() {
  const auth = (typeof useAuthCtx === "function") ? useAuthCtx() : null;
  const live = !!(auth && auth.user && window.CDE_READY);
  const actor = (auth && auth.profile && auth.profile.full_name) || "Bạn";
  const [items, setItems] = useState(ISSUES);
  const [sel, setSel] = useState(null);
  const [creating, setCreating] = useState(false);
  const reload = React.useCallback(async () => {
    const data = live ? await cdeData.issues().catch(e => { console.warn("issues live:", e.message); return ISSUES; }) : ISSUES;
    setItems(data);
    setSel(prev => prev ? (data.find(x => x.id === prev.id) || prev) : prev);
  }, [live]);
  React.useEffect(() => { reload(); }, [reload]);
  React.useEffect(() => {
    if (!live || !window.sb) return;
    const ch = window.sb.channel("rt-issues")
      .on("postgres_changes", { event: "*", schema: "public", table: "issues" }, () => reload())
      .on("postgres_changes", { event: "*", schema: "public", table: "issue_comments" }, () => reload())
      .subscribe();
    return () => { try { window.sb.removeChannel(ch); } catch {} };
  }, [live, reload]);

  return (
    <div
      className="content flush"
      style={{
        display: "flex",
        height: "100%",
        minHeight: 0,
        position: "relative",
      }}
    >
      {/* left column */}
      <div style={{ flex: 1, display: "flex", flexDirection: "column", minWidth: 0 }}>
        {/* page head */}
        <div style={{ padding: "22px 22px 0" }}>
          <PageHead
            title="Issues · BCF"
            sub="Quản lý vấn đề dựa trên mô hình · chuẩn BCF"
          >
            <button className="btn sm">
              <Icon.filter size={14} /> Lọc
            </button>
            <button className="btn sm primary" onClick={() => setCreating(true)}>
              <Icon.plus size={14} /> Tạo issue
            </button>
          </PageHead>
        </div>

        {/* table area */}
        <div
          style={{
            padding: "0 22px 22px",
            flex: 1,
            overflowY: "auto",
          }}
        >
          <div className="card" style={{ padding: "8px 10px" }}>
            <table className="tbl">
              <thead>
                <tr>
                  <th>Mã</th>
                  <th>Vấn đề</th>
                  <th>Bộ môn</th>
                  <th>Phụ trách</th>
                  <th>Hạn</th>
                  <th>Ưu tiên</th>
                  <th>Trạng thái</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                {items.map((iss) => {
                  const statusMeta = ISS_STATUS[iss.status];
                  const priCls = PRI_CLS[iss.pri] || "idle";
                  const IconComp = getIcon(statusMeta.icon);
                  return (
                    <tr
                      key={iss.id}
                      onClick={() => setSel(iss)}
                      style={{
                        cursor: "pointer",
                        background:
                          sel?.id === iss.id ? "var(--accent-soft)" : undefined,
                      }}
                    >
                      <td>
                        <span className="tag-mono">{iss.id}</span>
                      </td>
                      <td>
                        <span className="t-strong">{iss.title}</span>
                      </td>
                      <td>
                        <span className={`chip ${iss.disc}`}>
                          {DISC_NAME[iss.disc]}
                        </span>
                      </td>
                      <td>{iss.who}</td>
                      <td>{iss.due}</td>
                      <td>
                        <span className={`chip ${priCls}`}>{iss.pri}</span>
                      </td>
                      <td>
                        <span className={`chip ${statusMeta.cls}`}>
                          <IconComp size={12} /> {statusMeta.label}
                        </span>
                      </td>
                      <td>
                        <span className="icon-btn">›</span>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      </div>

      {/* right drawer */}
      {sel && <IssueDrawer iss={sel} live={live} actor={actor} onClose={() => setSel(null)} onChanged={reload} />}
      {creating && <CreateIssueModal live={live} onClose={() => setCreating(false)} onCreated={reload} />}
    </div>
  );
}

/* ── Expose globally ──────────────────────────────────────── */
window.Issues = Issues;
