// ==========================================
// Transactions page (Receive / Issue / Transfer)
// ==========================================

function TxnPage({ state, setState, mode, user, presetProjectFilter, onClearPreset }) {
  const toast = useToast();
  const stock = useMemo(() => computeStock(state), [state]);
  const [open, setOpen] = useState(false);
  const [editing, setEditing] = useState(null);
  const [catFilter, setCatFilter] = useState("all");
  const [projFilter, setProjFilter] = useState(presetProjectFilter || "all");
  const [statusFilter, setStatusFilter] = useState("all");
  const [search, setSearch] = useState("");
  const isPM = user && user.role === "pm";

  useEffect(() => {
    if (presetProjectFilter) setProjFilter(presetProjectFilter);
  }, [presetProjectFilter]);

  const matMap = Object.fromEntries(state.materials.map((m) => [m.id, m]));
  const projMap = Object.fromEntries(state.projects.map((p) => [p.id, p]));
  const catMap = Object.fromEntries(state.categories.map((c) => [c.id, c]));

  const meta = {
    receive: { title: "รับวัสดุเข้าคลัง", color: "#10b981", icon: "📥", verb: "รับเข้า", desc: "บันทึกการรับวัสดุจากผู้จำหน่ายเข้าหน่วยงาน" },
    issue:   { title: "เบิก / จ่ายวัสดุ",   color: "#ef4444", icon: "📤", verb: "เบิกจ่าย", desc: "บันทึกการเบิกใช้วัสดุจากคลังหน่วยงาน" },
    transfer:{ title: "โอนย้ายข้ามหน่วยงาน",  color: "#8b5cf6", icon: "🔄", verb: "โอนย้าย", desc: "ต้นทางสร้างคำขอ → ปลายทางตรวจสอบและอนุมัติก่อนยอดจะขยับ" },
  }[mode];

  const rows = state.transactions
    .filter((t) => t.type === mode)
    .filter((t) => {
      if (mode === "transfer" && statusFilter !== "all") {
        const s = t.status || "approved";
        if (s !== statusFilter) return false;
      }
      const m = matMap[t.materialId];
      if (!m) return false;
      if (catFilter !== "all" && m.category !== catFilter) return false;
      if (projFilter !== "all") {
        if (mode === "transfer") {
          if (t.fromProjectId !== projFilter && t.toProjectId !== projFilter) return false;
        } else if (t.projectId !== projFilter) return false;
      }
      if (search) {
        const s = search.toLowerCase();
        if (!m.name.toLowerCase().includes(s) && !t.id.toLowerCase().includes(s)) return false;
      }
      return true;
    })
    .sort((a, b) => new Date(b.date) - new Date(a.date));

  // Count pending transfers (for transfer page)
  const pendingCount = mode === "transfer"
    ? state.transactions.filter((t) => t.type === "transfer" && (t.status || "approved") === "pending").length
    : 0;

  function openNew() { setEditing(null); setOpen(true); }
  function openEdit(t) {
    // PM can edit anything; Store can only edit pending transfers.
    if (!isPM && mode === "transfer" && (t.status || "approved") !== "pending") {
      toast("แก้ไขได้เฉพาะรายการที่ยังรออนุมัติ", "warn");
      return;
    }
    if (!isPM && mode !== "transfer") {
      toast("เฉพาะ PM เท่านั้นที่สามารถแก้ไขรายการที่บันทึกแล้ว", "warn");
      return;
    }
    setEditing(t); setOpen(true);
  }

  function onSave(payload) {
    // Validate qty > 0 (reject 0 / NaN / negatives)
    const qty = window.DB.safeQty(payload.qty);
    if (qty === null) {
      toast("จำนวนต้องมากกว่า 0", "warn");
      return;
    }
    payload = { ...payload, qty };

    // Block over-issue / over-transfer that would create negative stock
    if (mode === "issue") {
      const avail = (stock[payload.materialId] || {})[payload.projectId] || 0;
      const prevQty = editing && editing.materialId === payload.materialId && editing.projectId === payload.projectId ? editing.qty : 0;
      if (qty > avail + prevQty) {
        toast(`สต๊อกไม่พอ · คงเหลือ ${avail + prevQty}`, "warn");
        return;
      }
    } else if (mode === "transfer") {
      const avail = (stock[payload.materialId] || {})[payload.fromProjectId] || 0;
      const prevQty = editing && (editing.status || "approved") === "approved" && editing.materialId === payload.materialId && editing.fromProjectId === payload.fromProjectId ? editing.qty : 0;
      if (qty > avail + prevQty) {
        toast(`สต๊อกต้นทางไม่พอ · คงเหลือ ${avail + prevQty}`, "warn");
        return;
      }
      if (payload.fromProjectId === payload.toProjectId) {
        toast("ต้นทางและปลายทางต้องไม่เป็นหน่วยงานเดียวกัน", "warn");
        return;
      }
    }

    const next = { ...state };
    if (editing) {
      next.transactions = state.transactions.map((t) =>
        t.id === editing.id ? window.DB.stampTransaction({ ...t, ...payload }) : t
      );
      toast("แก้ไขรายการเรียบร้อย");
    } else {
      const prefix = mode === "receive" ? "RC" : mode === "issue" ? "IS" : "TR";
      const baseRow = window.DB.stampTransaction({ id: genId(prefix), type: mode, by: user.username, date: todayISO(), ...payload });
      if (mode === "transfer") {
        baseRow.status = "pending";
        baseRow.requestedBy = user.username;
        baseRow.requestedAt = todayISO();
      }
      next.transactions = [...state.transactions, baseRow];
      toast(mode === "transfer" ? "ส่งคำขอโอนย้ายแล้ว — รอปลายทางอนุมัติ" : `บันทึก${meta.verb}เรียบร้อย`);
    }
    setState(next);
    setOpen(false);
  }

  function onDelete(t) {
    if (!isPM) { toast("เฉพาะ PM เท่านั้นที่สามารถลบรายการ", "warn"); return; }
    const next = { ...state, transactions: state.transactions.filter((x) => x.id !== t.id) };
    setState(next);
    toast("ลบรายการแล้ว", "warn");
  }

  function onApprove(t) {
    const next = {
      ...state,
      transactions: state.transactions.map((x) =>
        x.id === t.id ? { ...x, status: "approved", approvedBy: user.username, approvedAt: todayISO() } : x
      ),
    };
    setState(next);
    toast(`✓ อนุมัติโอนย้าย — สต๊อกถูกย้ายไปยัง ${projMap[t.toProjectId]?.code} แล้ว`);
  }

  function onReject(t) {
    const reason = prompt("ระบุเหตุผลที่ปฏิเสธ (ถ้ามี):") || "ปลายทางปฏิเสธ";
    const next = {
      ...state,
      transactions: state.transactions.map((x) =>
        x.id === t.id ? { ...x, status: "rejected", rejectedBy: user.username, rejectedAt: todayISO(), rejectReason: reason } : x
      ),
    };
    setState(next);
    toast("ปฏิเสธคำขอแล้ว", "warn");
  }

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1><span style={{ color: meta.color, marginRight: 8 }}>{meta.icon}</span>{meta.title}</h1>
          <p className="muted">{meta.desc}</p>
        </div>
        <button className="btn-primary" style={{ background: meta.color, borderColor: meta.color }} onClick={openNew}>
          + {mode === "transfer" ? "สร้างคำขอโอนย้าย" : `เพิ่ม${meta.verb}`}
        </button>
      </div>

      {mode === "transfer" && presetProjectFilter && (
        <div className="alert-banner">
          <span>🔔 กำลังกรองเฉพาะ <b>{projMap[presetProjectFilter]?.name}</b></span>
          <button className="link" onClick={() => { setProjFilter("all"); onClearPreset && onClearPreset(); }}>ล้างตัวกรอง ✕</button>
        </div>
      )}

      {mode === "transfer" && pendingCount > 0 && statusFilter !== "pending" && (
        <div className="alert-banner alert-warn">
          <span>⚠ มีคำขอโอนย้ายที่รออนุมัติ <b>{pendingCount}</b> รายการ</span>
          <button className="link" onClick={() => setStatusFilter("pending")}>ดูทั้งหมด →</button>
        </div>
      )}

      <div className="filter-bar">
        <div className="chip-group">
          <button className={`chip ${catFilter === "all" ? "active" : ""}`} onClick={() => setCatFilter("all")}>ทั้งหมด</button>
          {state.categories.map((c) => (
            <button key={c.id} className={`chip ${catFilter === c.id ? "active" : ""}`} onClick={() => setCatFilter(c.id)} style={catFilter === c.id ? { background: c.color, borderColor: c.color, color: "#fff" } : {}}>
              {c.icon} {c.name}
            </button>
          ))}
        </div>
        <div className="filter-right">
          {mode === "transfer" && (
            <select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}>
              <option value="all">ทุกสถานะ</option>
              <option value="pending">⏳ รออนุมัติ</option>
              <option value="approved">✓ อนุมัติแล้ว</option>
              <option value="rejected">✕ ปฏิเสธ</option>
            </select>
          )}
          <select value={projFilter} onChange={(e) => setProjFilter(e.target.value)}>
            <option value="all">ทุกหน่วยงาน</option>
            {state.projects.map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}
          </select>
          <input placeholder="ค้นหา..." value={search} onChange={(e) => setSearch(e.target.value)} />
        </div>
      </div>

      <div className="card no-pad">
        <div className="table-wrap">
          <table className="data-table">
            <thead>
              <tr>
                <th>เลขที่</th>
                <th>วันที่</th>
                <th>วัสดุ</th>
                <th>หมวด</th>
                {mode === "transfer" ? (<>
                  <th>จากหน่วยงาน</th>
                  <th>ไปหน่วยงาน</th>
                </>) : (
                  <th>หน่วยงาน</th>
                )}
                <th className="num-col">จำนวน</th>
                {mode === "transfer" && <th>สถานะ</th>}
                <th>{mode === "receive" ? "ผู้จำหน่าย" : mode === "issue" ? "ผู้ขอเบิก" : "หมายเหตุ"}</th>
                <th>ผู้บันทึก</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {rows.length === 0 && <tr><td colSpan={mode === "transfer" ? 11 : 9}><Empty /></td></tr>}
              {rows.map((t) => {
                const m = matMap[t.materialId];
                const cat = m ? catMap[m.category] : null;
                const status = t.status || "approved";
                const isPending = mode === "transfer" && status === "pending";
                const isRejected = mode === "transfer" && status === "rejected";
                return (
                  <tr key={t.id} className={isPending ? "row-pending" : isRejected ? "row-rejected" : ""}>
                    <td className="mono">{t.id}</td>
                    <td>{fmtDate(t.date)}</td>
                    <td><b>{m?.name || "—"}</b></td>
                    <td><CatBadge cat={cat} /></td>
                    {mode === "transfer" ? (<>
                      <td>{projMap[t.fromProjectId]?.name} <div className="muted small">{projMap[t.fromProjectId]?.code}</div></td>
                      <td>{projMap[t.toProjectId]?.name} <div className="muted small">{projMap[t.toProjectId]?.code}</div></td>
                    </>) : (
                      <td>{projMap[t.projectId]?.name}</td>
                    )}
                    <td className="num-col"><b style={{ color: meta.color }}>{fmtNum(t.qty)}</b> <span className="muted">{m?.unit}</span></td>
                    {mode === "transfer" && (
                      <td><TransferStatusPill status={status} /></td>
                    )}
                    <td>{mode === "receive" ? t.supplier : mode === "issue" ? t.requester : (t.note || (isRejected ? <span className="muted small">เหตุผล: {t.rejectReason}</span> : "—"))}</td>
                    <td className="muted">{t.by}</td>
                    <td>
                      <div className="row-actions">
                        {isPending && (
                          <>
                            <button className="approve-btn" onClick={() => onApprove(t)} title="อนุมัติ">✓ อนุมัติ</button>
                            <button className="reject-btn" onClick={() => onReject(t)} title="ปฏิเสธ">✕</button>
                          </>
                        )}
                        {!isRejected && (isPM || isPending) && (
                          <button className="icon-btn" onClick={() => openEdit(t)} title="แก้ไข">✎</button>
                        )}
                        {isPM && (
                          <ConfirmBtn className="icon-btn danger" onConfirm={() => onDelete(t)}>🗑</ConfirmBtn>
                        )}
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>

      <Modal open={open} onClose={() => setOpen(false)} title={editing ? `แก้ไข${meta.verb}` : (mode === "transfer" ? "สร้างคำขอโอนย้าย" : `เพิ่ม${meta.verb}`)} width={620}>
        <TxnForm
          state={state}
          mode={mode}
          stock={stock}
          editing={editing}
          accent={meta.color}
          onSubmit={onSave}
          onCancel={() => setOpen(false)}
        />
      </Modal>
    </div>
  );
}

function TransferStatusPill({ status }) {
  const map = {
    pending:  { bg: "#fef3c7", color: "#92400e", icon: "⏳", label: "รออนุมัติ" },
    approved: { bg: "#d1fae5", color: "#065f46", icon: "✓",  label: "อนุมัติแล้ว" },
    rejected: { bg: "#fee2e2", color: "#991b1b", icon: "✕",  label: "ปฏิเสธ" },
  };
  const m = map[status] || map.approved;
  return (
    <span className="status-pill" style={{ background: m.bg, color: m.color }}>
      {m.icon} {m.label}
    </span>
  );
}

function TxnForm({ state, mode, stock, editing, accent, onSubmit, onCancel }) {
  const [catId, setCatId] = useState(editing ? state.materials.find((m) => m.id === editing.materialId)?.category : state.categories[0].id);
  const [form, setForm] = useState(editing ? { ...editing } : {
    materialId: "",
    qty: "",
    projectId: state.projects[0]?.id,
    fromProjectId: state.projects[0]?.id,
    toProjectId: state.projects[1]?.id,
    supplier: "",
    requester: "",
    note: "",
    date: todayISO(),
  });

  const matsInCat = state.materials.filter((m) => m.category === catId);
  useEffect(() => {
    if (!editing && matsInCat.length && !matsInCat.some((m) => m.id === form.materialId)) {
      setForm((f) => ({ ...f, materialId: matsInCat[0].id }));
    }
  }, [catId]);

  const selMat = state.materials.find((m) => m.id === form.materialId);
  const projForStock = mode === "transfer" ? form.fromProjectId : form.projectId;
  const available = selMat ? (stock[selMat.id]?.[projForStock] || 0) : 0;

  function update(k, v) { setForm((f) => ({ ...f, [k]: v })); }

  function submit(e) {
    e.preventDefault();
    if (!form.materialId || !form.qty || form.qty <= 0) return alert("กรุณาเลือกวัสดุและระบุจำนวน");
    if (mode === "transfer" && form.fromProjectId === form.toProjectId) return alert("ต้นทางและปลายทางต้องต่างกัน");
    const payload = { ...form, qty: Number(form.qty) };
    onSubmit(payload);
  }

  return (
    <form onSubmit={submit} className="form-grid">
      <Field label="หมวดงาน">
        <div className="chip-group">
          {state.categories.map((c) => (
            <button type="button" key={c.id} className={`chip ${catId === c.id ? "active" : ""}`} onClick={() => setCatId(c.id)} style={catId === c.id ? { background: c.color, borderColor: c.color, color: "#fff" } : {}}>
              {c.icon} {c.name}
            </button>
          ))}
        </div>
      </Field>

      <Field label="วัสดุ">
        <select value={form.materialId} onChange={(e) => update("materialId", e.target.value)} required>
          <option value="">— เลือกวัสดุ —</option>
          {matsInCat.map((m) => <option key={m.id} value={m.id}>{m.name} ({m.unit})</option>)}
        </select>
      </Field>

      {mode === "transfer" ? (
        <>
          <Field label="จากหน่วยงาน">
            <select value={form.fromProjectId} onChange={(e) => update("fromProjectId", e.target.value)} required>
              {state.projects.map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}
            </select>
          </Field>
          <Field label="ไปหน่วยงาน">
            <select value={form.toProjectId} onChange={(e) => update("toProjectId", e.target.value)} required>
              {state.projects.map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}
            </select>
          </Field>
        </>
      ) : (
        <Field label="หน่วยงาน">
          <select value={form.projectId} onChange={(e) => update("projectId", e.target.value)} required>
            {state.projects.map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}
          </select>
        </Field>
      )}

      <Field label={`จำนวน ${selMat ? `(${selMat.unit})` : ""}`} hint={(mode === "issue" || mode === "transfer") && selMat ? `คงเหลือในต้นทาง: ${fmtNum(available)} ${selMat.unit}` : null}>
        <input type="number" min="0" step="any" value={form.qty} onChange={(e) => update("qty", e.target.value)} required />
      </Field>

      <Field label="วันที่">
        <input type="datetime-local" value={form.date ? new Date(form.date).toISOString().slice(0, 16) : ""} onChange={(e) => update("date", new Date(e.target.value).toISOString())} required />
      </Field>

      {mode === "receive" && (
        <Field label="ผู้จำหน่าย">
          <input value={form.supplier || ""} onChange={(e) => update("supplier", e.target.value)} placeholder="ชื่อผู้จำหน่าย / ใบส่งของเลขที่" />
        </Field>
      )}
      {mode === "issue" && (
        <Field label="ผู้ขอเบิก">
          <input value={form.requester || ""} onChange={(e) => update("requester", e.target.value)} placeholder="ชื่อ-ตำแหน่งผู้ขอเบิก" />
        </Field>
      )}

      <Field label="หมายเหตุ">
        <textarea rows="2" value={form.note || ""} onChange={(e) => update("note", e.target.value)} />
      </Field>

      <div className="form-actions">
        <button type="button" className="btn-ghost" onClick={onCancel}>ยกเลิก</button>
        <button type="submit" className="btn-primary" style={{ background: accent, borderColor: accent }}>{editing ? "บันทึกการแก้ไข" : "บันทึก"}</button>
      </div>
    </form>
  );
}

window.TxnPage = TxnPage;
