// Supplier / Vendor Master Module — ทะเบียนผู้จำหน่าย
// Pages:
//   • SupplierListPage             — main list with KPIs / filters / actions
//   • SupplierDetailModal          — view + edit (tabs: ข้อมูลพื้นฐาน / ติดต่อ / การชำระเงิน / เอกสาร)
//   • SupplierDocumentUploadModal  — upload or replace one document
// Window globals also expose SupplierSearchablePicker for PC integration.

const SUPPLIER_DOC_TYPES = [
  { code: "affidavit", label: "หนังสือรับรองบริษัท",   short: "Affidavit",    icon: "fileText", required_expiry: false },
  { code: "vat_pp20",  label: "ใบทะเบียนภาษีมูลค่าเพิ่ม (ภ.พ.20)", short: "ภ.พ.20",     icon: "fileText", required_expiry: false },
  { code: "bankbook",  label: "สำเนาสมุดบัญชีธนาคาร",  short: "Bank Book",    icon: "fileText", required_expiry: false },
  { code: "other",     label: "เอกสารอื่นๆ",            short: "อื่นๆ",         icon: "fileText", required_expiry: false },
];
const SUPPLIER_TYPES = [
  { code: "company",    label: "นิติบุคคล" },
  { code: "individual", label: "บุคคลธรรมดา" },
  { code: "other",      label: "อื่นๆ" },
];
const SUPPLIER_CURRENCIES = ["THB", "USD", "EUR", "JPY", "GBP", "CNY", "SGD", "MYR", "HKD", "AUD"];

// formatBytes is provided by src/ui.jsx (canonical implementation, attached to window).
// Local alias kept for readability in JSX below.
const fmtBytes2 = formatBytes;

const canManageSuppliersUi = (role) =>
  role === "procurement" || role === "admin" || role === "super_admin";

// Status badges
const SupStatusBadge = ({ status }) => {
  if (status === "active") return <Badge color="emerald">ใช้งานอยู่</Badge>;
  return <Badge color="slate">ปิดใช้งาน</Badge>;
};
const DocStatusBadge = ({ status }) => {
  const m = {
    valid:          { color: "emerald", label: "✓ ใช้ได้" },
    expiring_soon:  { color: "amber",   label: "⚠ ใกล้หมดอายุ" },
    expired:        { color: "rose",    label: "✕ หมดอายุ" },
    replaced:       { color: "slate",   label: "↻ ถูกแทนที่" },
    no_documents:   { color: "slate",   label: "— ไม่มีเอกสาร" },
  }[status] || { color: "slate", label: status };
  return <Badge color={m.color}>{m.label}</Badge>;
};

// =============================================================================
// LIST PAGE
// =============================================================================
const SupplierListPage = ({ tenant, currentUser, currentRole, users, onOpen }) => {
  const toast = useToast();
  const canManage = canManageSuppliersUi(currentRole);
  const [rows, setRows] = useState([]);
  const [requestRows, setRequestRows] = useState([]);  // pending + rejected + cancelled
  const [loading, setLoading] = useState(false);
  const [q, setQ] = useState("");
  const [filterStatus, setFilterStatus] = useState("__all__");
  const [filterDocStatus, setFilterDocStatus] = useState("__all__");
  const [editFor, setEditFor] = useState(null); // null | "new" | supplier row | { kind:"resubmit", request }
  const [openRequest, setOpenRequest] = useState(null);  // create-request row to view in drawer

  const reload = async () => {
    if (!tenant?.id || !window.apiClient) return;
    setLoading(true);
    try {
      const [list, pendRes, rejRes, cancRes] = await Promise.all([
        window.apiClient.suppliersList(tenant.id),
        window.apiClient.supplierCreateReqList(tenant.id, { status: 'pending'   }).catch(() => []),
        window.apiClient.supplierCreateReqList(tenant.id, { status: 'rejected'  }).catch(() => []),
        window.apiClient.supplierCreateReqList(tenant.id, { status: 'cancelled' }).catch(() => []),
      ]);
      setRows(Array.isArray(list) ? list : []);
      setRequestRows([]
        .concat(Array.isArray(pendRes) ? pendRes : [])
        .concat(Array.isArray(rejRes) ? rejRes : [])
        .concat(Array.isArray(cancRes) ? cancRes : []));
    } catch (e) {
      toast({ kind: "error", msg: e.message || "โหลดรายชื่อผู้จำหน่ายไม่สำเร็จ" });
    } finally { setLoading(false); }
  };
  useEffect(() => { reload(); /* eslint-disable-next-line */ }, [tenant?.id]);

  const pendingCount  = requestRows.filter(r => r.status === 'pending').length;
  const rejectedCount = requestRows.filter(r => r.status === 'rejected').length;

  const counts = useMemo(() => {
    const c = { total: rows.length, active: 0, inactive: 0, valid: 0, expiring: 0, expired: 0, no_docs: 0 };
    rows.forEach(r => {
      if (r.status === "active") c.active++; else c.inactive++;
      if (r.doc_status === "valid") c.valid++;
      else if (r.doc_status === "expiring_soon") c.expiring++;
      else if (r.doc_status === "expired") c.expired++;
      else c.no_docs++;
    });
    return c;
  }, [rows]);

  // Pending / rejected / cancelled requests are merged in as virtual rows so
  // the requester sees their progress without leaving the page.
  const mergedRows = useMemo(() => {
    const reqVirtual = (requestRows || []).map(r => ({
      __pending_request__: true,
      __request_status__: r.status,
      __request__: r,
      id: r.id,
      supplier_code: r.request_number,
      supplier_name: r.supplier_name,
      supplier_name_en: r.supplier_name_en,
      tax_id: r.tax_id, branch_code: r.branch_code, branch_name: r.branch_name,
      contact_person: r.contact_person, contact_phone: r.contact_phone, contact_email: r.contact_email,
      default_currency: r.default_currency,
      status: r.status === 'pending' ? 'pending_request' : r.status === 'rejected' ? 'rejected_request' : 'cancelled_request',
      doc_status: 'no_documents', doc_count: 0,
      updated_at: r.updated_at || r.created_at,
    }));
    return [...reqVirtual, ...rows];
  }, [rows, requestRows]);

  const filtered = useMemo(() => {
    const ql = q.trim().toLowerCase();
    return mergedRows.filter(r => {
      if (filterStatus !== "__all__" && r.status !== filterStatus) return false;
      if (filterDocStatus !== "__all__" && !r.__pending_request__ && r.doc_status !== filterDocStatus) return false;
      if (!ql) return true;
      return (r.supplier_code || "").toLowerCase().includes(ql)
          || (r.supplier_name || "").toLowerCase().includes(ql)
          || (r.tax_id || "").toLowerCase().includes(ql)
          || (r.contact_person || "").toLowerCase().includes(ql)
          || (r.contact_email || "").toLowerCase().includes(ql)
          || (r.contact_phone || "").toLowerCase().includes(ql);
    });
  }, [mergedRows, q, filterStatus, filterDocStatus]);

  const exportExcel = () => {
    const headers = ["รหัสผู้จำหน่าย","ชื่อ","Tax ID","สาขา","ชื่อสาขา","ผู้ติดต่อ","โทรศัพท์","อีเมล","สกุลเงิน","สถานะ","สถานะเอกสาร","วันหมดอายุถัดไป","อัปเดตล่าสุด"];
    const csv = filtered.map(r => [
      r.supplier_code, r.supplier_name, r.tax_id || "",
      r.branch_code || "", r.branch_name || "",
      r.contact_person || "", r.contact_phone || "", r.contact_email || "",
      r.default_currency || "", r.status, r.doc_status,
      r.next_expiry_date || "", formatDateTime(r.updated_at),
    ]);
    window.downloadCsv(`suppliers-${new Date().toISOString().slice(0,10)}.csv`, headers, csv);
  };

  return (
    <div className="p-6 max-w-[1400px] mx-auto">
      <div className="text-[11px] tracking-wider text-emerald-700 font-bold mb-1">↕ ทะเบียนผู้จำหน่าย · VENDOR MASTER</div>
      <div className="flex items-start justify-between gap-3 mb-1">
        <div>
          <div className="text-[24px] font-bold text-ink-900 leading-tight">ทะเบียนผู้จำหน่าย (Vendor Master)</div>
          <div className="text-[13px] text-ink-500 mt-1">
            บันทึกข้อมูลผู้จำหน่าย + เอกสารแนบที่มีวันหมดอายุ · ใช้เป็นข้อมูลหลักสำหรับการสร้างเอกสารเปรียบเทียบราคา
          </div>
        </div>
        <div className="flex items-center gap-2 shrink-0">
          <Button variant="secondary" icon="fileBarChart" onClick={exportExcel}>ส่งออก Excel</Button>
          {canManage ? (
            <Button variant="primary" icon="plus" onClick={() => setEditFor("new")}>สร้างผู้จำหน่ายใหม่</Button>
          ) : (
            <Tip multiline={"การเพิ่ม / แก้ไข / ลบผู้จำหน่าย\nสงวนสิทธิ์เฉพาะ Procurement / Admin / Super Admin"}>
              <span className="inline-flex items-center gap-1 h-9 px-3 rounded-lg bg-ink-100 text-ink-500 text-[12.5px] font-medium">
                <Icon name="ban" size={13}/> เฉพาะผู้ดูแลระบบ
              </span>
            </Tip>
          )}
        </div>
      </div>

      {/* KPI cards */}
      <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3 mt-5">
        <KpiCard icon="building" tone="indigo"  label="ผู้จำหน่ายทั้งหมด" value={counts.total}/>
        <KpiCard icon="check"    tone="emerald" label="ใช้งานอยู่" value={counts.active}/>
        <KpiCard icon="ban"      tone="slate"   label="ปิดใช้งาน" value={counts.inactive}/>
        <KpiCard icon="check"    tone="emerald" label="เอกสารใช้ได้" value={counts.valid}/>
        <KpiCard icon="warning"  tone="amber"   label="ใกล้หมดอายุ" value={counts.expiring} trend="ภายใน 30 วัน"/>
        <KpiCard icon="ban"      tone="rose"    label="หมดอายุ" value={counts.expired} trend="ต้องอัปเดต"/>
      </div>

      {/* Filters */}
      <div className="flex items-center gap-2 mt-5">
        <div className="relative flex-1 max-w-[460px]">
          <Icon name="search" size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-ink-400"/>
          <input type="text" value={q} onChange={e => setQ(e.target.value)}
            placeholder="ค้นหารหัส / ชื่อ / Tax ID / ผู้ติดต่อ / โทร / อีเมล"
            className="w-full h-9 pl-9 pr-3 text-[13px] border border-ink-200 rounded-lg bg-white focus:border-brand-500 ring-focus"/>
        </div>
        <Select className="w-[170px]" value={filterStatus} onChange={e => setFilterStatus(e.target.value)}>
          <option value="__all__">สถานะ: ทั้งหมด</option>
          <option value="pending_request">รออนุมัติ</option>
          <option value="rejected_request">ถูกปฏิเสธ</option>
          <option value="cancelled_request">ยกเลิก</option>
          <option value="active">ใช้งานอยู่</option>
          <option value="inactive">ปิดใช้งาน</option>
        </Select>
        <Select className="w-[180px]" value={filterDocStatus} onChange={e => setFilterDocStatus(e.target.value)}>
          <option value="__all__">เอกสาร: ทั้งหมด</option>
          <option value="valid">ใช้ได้</option>
          <option value="expiring_soon">ใกล้หมดอายุ</option>
          <option value="expired">หมดอายุ</option>
          <option value="no_documents">ไม่มีเอกสาร</option>
        </Select>
        <div className="ml-auto text-[11.5px] text-ink-500 whitespace-nowrap">
          พบ {filtered.length} / {mergedRows.length} ราย
          {pendingCount > 0 && <span className="text-amber-700 font-semibold ml-2">· รออนุมัติ {pendingCount}</span>}
          {rejectedCount > 0 && <span className="text-rose-700 font-semibold ml-2">· ถูกปฏิเสธ {rejectedCount}</span>}
        </div>
      </div>

      {/* Table */}
      <div className="mt-3 bg-white rounded-2xl border border-ink-100 overflow-hidden">
        {loading ? (
          <div className="p-10 text-center text-ink-500 text-sm">กำลังโหลด…</div>
        ) : filtered.length === 0 ? (
          <EmptyState icon="building" title="ยังไม่มีผู้จำหน่าย"
            subtitle="เริ่มต้นโดยกด ‘+ สร้างผู้จำหน่ายใหม่’ — รหัสจะถูกสร้างอัตโนมัติในรูปแบบ SP-YY-NNNN"/>
        ) : (
          <div className="overflow-x-auto thin-scroll">
            <table className="w-full text-[12.5px]">
              <thead className="bg-ink-50/60 text-ink-500 text-[11px] uppercase">
                <tr>
                  <th className="text-left px-4 py-2.5 font-semibold">รหัส / ชื่อ</th>
                  <th className="text-left px-3 py-2.5 font-semibold">Tax ID</th>
                  <th className="text-left px-3 py-2.5 font-semibold">สาขา</th>
                  <th className="text-left px-3 py-2.5 font-semibold">ผู้ติดต่อ</th>
                  <th className="text-left px-3 py-2.5 font-semibold">โทร / อีเมล</th>
                  <th className="text-left px-3 py-2.5 font-semibold">สกุลเงิน</th>
                  <th className="text-left px-3 py-2.5 font-semibold">สถานะ</th>
                  <th className="text-left px-3 py-2.5 font-semibold">เอกสาร</th>
                  <th className="text-left px-3 py-2.5 font-semibold">วันหมดอายุถัดไป</th>
                  <th className="text-left px-3 py-2.5 font-semibold">อัปเดต</th>
                  <th className="text-center px-3 py-2.5 font-semibold">การดำเนินการ</th>
                </tr>
              </thead>
              <tbody>
                {filtered.map(r => {
                  const isReq = r.__pending_request__;
                  const reqStatus = r.__request_status__;
                  const rowBg = reqStatus === 'pending'   ? 'bg-amber-50/40 hover:bg-amber-50/60'
                              : reqStatus === 'rejected'  ? 'bg-rose-50/40 hover:bg-rose-50/60'
                              : reqStatus === 'cancelled' ? 'bg-slate-50/40 hover:bg-slate-50/60'
                              : (r.doc_status === "expired" ? "bg-rose-50/30 hover:bg-rose-50/50"
                                : r.doc_status === "expiring_soon" ? "bg-amber-50/30 hover:bg-amber-50/50"
                                : "hover:bg-emerald-50/30");
                  const onRowClick = () => {
                    if (isReq) setOpenRequest(r.__request__);
                    else setEditFor(r);
                  };
                  const myId = currentUser?.id || currentUser?.api_user_id;
                  const isMyReq = isReq && r.__request__?.created_by_user_id === myId;
                  return (
                    <tr key={(isReq ? "req-" : "sup-") + r.id} onClick={onRowClick}
                      className={`border-t border-ink-100 transition cursor-pointer ${rowBg}`}>
                      <td className="px-4 py-2.5">
                        <div className={`font-mono text-[12px] font-bold ${isReq ? "text-amber-700" : "text-emerald-700"}`}>{r.supplier_code}</div>
                        <div className="text-[12.5px] text-ink-900 truncate max-w-[260px]">{r.supplier_name}</div>
                        {r.supplier_name_en && <div className="text-[10.5px] text-ink-500 italic truncate max-w-[260px]">{r.supplier_name_en}</div>}
                      </td>
                      <td className="px-3 py-2.5 font-mono text-ink-700">{r.tax_id || "—"}</td>
                      <td className="px-3 py-2.5 font-mono text-ink-700">
                        {r.branch_code ? (
                          <>
                            <span>{r.branch_code}</span>
                            {r.branch_name && <div className="text-[10.5px] text-ink-500 font-sans">{r.branch_name}</div>}
                          </>
                        ) : (
                          <span className="text-ink-400">—</span>
                        )}
                      </td>
                      <td className="px-3 py-2.5 text-ink-700">{r.contact_person || "—"}</td>
                      <td className="px-3 py-2.5">
                        <div className="text-ink-700">{r.contact_phone || "—"}</div>
                        <div className="text-[10.5px] text-ink-500 truncate max-w-[200px]">{r.contact_email || ""}</div>
                      </td>
                      <td className="px-3 py-2.5 font-mono text-ink-700">{r.default_currency || "—"}</td>
                      <td className="px-3 py-2.5">
                        {reqStatus === 'pending'  ? <Badge color="amber" icon="clock">รออนุมัติ</Badge>
                       : reqStatus === 'rejected' ? <Badge color="rose"  icon="x">ปฏิเสธ</Badge>
                       : reqStatus === 'cancelled'? <Badge color="slate" icon="ban">ยกเลิก</Badge>
                       : <SupStatusBadge status={r.status}/>}
                      </td>
                      <td className="px-3 py-2.5">
                        {isReq
                          ? <span className="text-ink-400 text-[11px]">—</span>
                          : <>
                              <DocStatusBadge status={r.doc_status}/>
                              {r.doc_count > 0 && <div className="text-[10.5px] text-ink-500 mt-0.5">{r.doc_count} ไฟล์</div>}
                            </>}
                      </td>
                      <td className="px-3 py-2.5 text-ink-700 whitespace-nowrap font-mono">{r.next_expiry_date ? formatDate(r.next_expiry_date) : "—"}</td>
                      <td className="px-3 py-2.5 text-ink-500 whitespace-nowrap">{formatDateTime(r.updated_at)}</td>
                      <td className="px-3 py-2.5">
                        <div className="flex items-center justify-center gap-1">
                          {isReq ? (
                            <>
                              <Tip tip="ดูคำขอ"><button onClick={(e) => { e.stopPropagation(); setOpenRequest(r.__request__); }}
                                className="p-1.5 rounded-md text-ink-500 hover:bg-ink-100 hover:text-amber-700"><Icon name="eye" size={13}/></button></Tip>
                              {(reqStatus === 'rejected' || reqStatus === 'cancelled') && (isMyReq || canManage) && (
                                <>
                                  <Tip tip="แก้ไข & ส่งใหม่"><button onClick={(e) => { e.stopPropagation(); setEditFor({ kind: "resubmit", request: r.__request__ }); }}
                                    className="p-1.5 rounded-md text-ink-500 hover:bg-ink-100 hover:text-emerald-700"><Icon name="edit" size={13}/></button></Tip>
                                  <Tip tip="ลบรายการ"><button onClick={async (e) => {
                                    e.stopPropagation();
                                    if (!confirm(`ลบคำขอ ${r.__request__.request_number} ?`)) return;
                                    try {
                                      await window.apiClient.supplierCreateReqDelete(tenant.id, r.__request__.id);
                                      toast({ kind:"success", msg:"ลบคำขอแล้ว" });
                                      reload();
                                    } catch (err) { toast({ kind:"error", msg: err.message || "ลบไม่สำเร็จ" }); }
                                  }} className="p-1.5 rounded-md text-ink-500 hover:bg-ink-100 hover:text-rose-700"><Icon name="trash" size={13}/></button></Tip>
                                </>
                              )}
                            </>
                          ) : (
                            <Tip tip="ดู / แก้ไข"><button onClick={(e) => { e.stopPropagation(); setEditFor(r); }}
                              className="p-1.5 rounded-md text-ink-500 hover:bg-ink-100 hover:text-emerald-700"><Icon name="edit" size={13}/></button></Tip>
                          )}
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
      </div>

      {editFor && (
        <SupplierDetailModal
          mode={editFor === "new" ? "create" : editFor?.kind === "resubmit" ? "resubmit" : "edit"}
          supplier={editFor === "new" || editFor?.kind === "resubmit" ? null : editFor}
          requestData={editFor?.kind === "resubmit" ? editFor.request : null}
          tenant={tenant} currentUser={currentUser} currentRole={currentRole} users={users}
          onClose={() => setEditFor(null)}
          onChanged={() => { reload(); }}
        />
      )}
      {openRequest && (
        <SupplierCreateRequestDrawer
          request={openRequest}
          tenant={tenant} currentUser={currentUser} currentRole={currentRole} users={users}
          onClose={() => setOpenRequest(null)}
          onChanged={reload}
          onEdit={(req) => { setOpenRequest(null); setEditFor({ kind: "resubmit", request: req }); }}
        />
      )}
    </div>
  );
};

// =============================================================================
// DETAIL MODAL — view + edit + documents
// =============================================================================
const SupplierDetailModal = ({ mode, supplier, requestData, tenant, currentUser, currentRole, users, onClose, onChanged }) => {
  const toast = useToast();
  const canManage = canManageSuppliersUi(currentRole);
  const isCreate   = mode === "create";
  const isResubmit = mode === "resubmit";
  const needsApprover = isCreate || isResubmit;
  const [tab, setTab] = useState("basic");
  const [full, setFull] = useState(null);            // loaded supplier with documents
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [uploadFor, setUploadFor] = useState(null);  // open upload modal for document_type
  const [confirmInactivate, setConfirmInactivate] = useState(false);

  const blank = {
    supplier_name: "", supplier_name_en: "", tax_id: "",
    branch_code: "", branch_name: "", supplier_type: "company",
    contact_person: "", contact_phone: "", contact_email: "",
    address: "", country: "TH",
    bank_name: "", bank_account_number: "", bank_account_name: "",
    payment_term: "", default_currency: "THB", remark: "",
  };
  const initialForm = isResubmit ? { ...blank, ...(requestData || {}) }
                    : isCreate   ? blank
                                 : { ...blank, ...(supplier || {}) };
  const [form, setForm] = useState(initialForm);
  const set = (k, v) => setForm(prev => ({ ...prev, [k]: v }));
  // Approver state — only used in create/resubmit modes
  const myId = currentUser?.id || currentUser?.api_user_id;
  const [approverUserId, setApproverUserId] = useState(requestData?.approver_user_id || "");
  const [requesterComment, setRequesterComment] = useState(requestData?.requester_comment || "");
  // Create/resubmit doc handling — stage files in memory, upload after request is saved
  // stagedDocs[doc_type] = { file: File, expiry: "YYYY-MM-DD", remark: "" }
  const [stagedDocs, setStagedDocs] = useState({});
  // Existing request attachments — only populated in resubmit mode (loaded from API)
  const [reqAttachments, setReqAttachments] = useState([]);
  useEffect(() => {
    if (!isResubmit || !requestData?.id) return;
    window.apiClient.supplierCreateReqGet(tenant.id, requestData.id)
      .then(d => setReqAttachments(Array.isArray(d?.attachments) ? d.attachments : []))
      .catch(() => {});
  }, [isResubmit, requestData?.id, tenant?.id]);
  const approverOptions = useMemo(() => {
    return (users || [])
      .filter(u => u.from_api && u.id !== myId && u.api_user_id !== myId)
      .map(u => ({
        id: u.id,
        label: (typeof displayName === "function" ? displayName(u) : (u.full_name || u.email)),
        email: u.email,
      }));
  }, [users, myId]);

  const reload = async () => {
    if (isCreate || !supplier?.id) return;
    setLoading(true);
    try {
      const d = await window.apiClient.suppliersGet(tenant.id, supplier.id);
      setFull(d);
      setForm(prev => ({ ...prev, ...d }));
    } catch (e) { toast({ kind: "error", msg: e.message || "โหลดข้อมูลไม่สำเร็จ" }); }
    finally { setLoading(false); }
  };
  useEffect(() => { reload(); /* eslint-disable-next-line */ }, [supplier?.id]);

  const handleSave = async () => {
    if (!form.supplier_name?.trim()) { toast({ kind: "warn", msg: "กรุณาระบุชื่อผู้จำหน่าย" }); return; }
    if (form.supplier_type === "company" && !form.tax_id?.trim()) {
      toast({ kind: "warn", msg: "นิติบุคคลต้องระบุ Tax ID" }); return;
    }
    if (form.supplier_type === "company" && !form.branch_code?.trim()) {
      toast({ kind: "warn", msg: "นิติบุคคลต้องระบุรหัสสาขา (00000 = สำนักงานใหญ่)" }); return;
    }
    const tax = String(form.tax_id || "");
    if (tax !== "" && tax.length !== 13) {
      toast({ kind: "warn", msg: "Tax ID ต้องเป็นตัวเลข 13 หลักพอดี" }); return;
    }
    const branch = String(form.branch_code || "");
    if (branch !== "" && branch.length !== 5) {
      toast({ kind: "warn", msg: "รหัสสาขาต้องเป็นตัวเลข 5 หลักพอดี" }); return;
    }
    if (needsApprover) {
      if (!approverUserId) { toast({ kind:"warn", msg:"กรุณาเลือกผู้อนุมัติ" }); return; }
      if (approverUserId === myId) { toast({ kind:"warn", msg:"ไม่สามารถเลือกตัวเองเป็นผู้อนุมัติได้" }); return; }
    }
    setSaving(true);
    try {
      let reqId = requestData?.id || null;
      let reqNumber = requestData?.request_number || "";
      if (isCreate) {
        const r = await window.apiClient.supplierCreateReqSubmit(tenant.id, {
          ...form, approver_user_id: approverUserId, requester_comment: requesterComment || null,
        });
        reqId = r.id;
        reqNumber = r.request_number;
      } else if (isResubmit) {
        await window.apiClient.supplierCreateReqResubmit(tenant.id, requestData.id, {
          ...form, approver_user_id: approverUserId, requester_comment: requesterComment || null,
        });
      } else {
        await window.apiClient.suppliersUpdate(tenant.id, supplier.id, form);
      }

      // Upload any staged docs (create + resubmit) — each is keyed by document_type
      const stagedEntries = Object.entries(stagedDocs).filter(([, v]) => v?.file);
      if (reqId && stagedEntries.length > 0) {
        try {
          await Promise.all(stagedEntries.map(([dtype, v]) =>
            window.apiClient.supplierCreateReqUploadAttachment(tenant.id, reqId, v.file, {
              document_type: dtype,
              expiry_date: v.expiry || null,
              remark: v.remark || null,
            })
          ));
        } catch (uerr) {
          toast({ kind: "error", msg: `บันทึกคำขอแล้ว แต่อัปโหลดไฟล์บางส่วนล้มเหลว: ${uerr.message || ""}` });
          onChanged?.();
          onClose();
          return;
        }
      }

      if (isCreate) toast({ kind: "success", msg: `ส่งคำขอสร้างผู้จำหน่าย ${reqNumber} แล้ว · รออนุมัติ` });
      else if (isResubmit) toast({ kind: "success", msg: `ส่งคำขอ ${requestData.request_number} อีกครั้งแล้ว · รออนุมัติ` });
      else toast({ kind: "success", msg: "บันทึกการเปลี่ยนแปลงแล้ว" });

      onChanged?.();
      onClose();
    } catch (e) { toast({ kind: "error", msg: e.message || "บันทึกไม่สำเร็จ" }); }
    finally { setSaving(false); }
  };

  const handleInactivate = async () => {
    try {
      if (form.status === "active") {
        await window.apiClient.suppliersInactivate(tenant.id, supplier.id);
        toast({ kind: "warn", msg: "ปิดใช้งานผู้จำหน่ายแล้ว" });
      } else {
        await window.apiClient.suppliersReactivate(tenant.id, supplier.id);
        toast({ kind: "success", msg: "เปิดใช้งานผู้จำหน่ายแล้ว" });
      }
      setConfirmInactivate(false);
      onChanged?.();
      await reload();
    } catch (e) { toast({ kind: "error", msg: e.message || "เปลี่ยนสถานะไม่สำเร็จ" }); }
  };

  const footer = (
    <div className="flex items-center justify-between w-full">
      {!isCreate && !isResubmit && canManage && (
        form.status === "active" ? (
          <Button variant="ghost" icon="ban" onClick={() => setConfirmInactivate(true)}>ปิดใช้งานผู้จำหน่าย</Button>
        ) : (
          <Button variant="success" icon="check" onClick={() => setConfirmInactivate(true)}>เปิดใช้งานผู้จำหน่าย</Button>
        )
      )}
      {(isCreate || isResubmit) && <div/>}
      <div className="flex items-center gap-2 ml-auto">
        <Button variant="secondary" onClick={onClose}>ปิด</Button>
        {canManage && (
          <Button variant="primary" icon={isCreate || isResubmit ? "send" : "check"} onClick={handleSave} disabled={saving}>
            {saving ? "กำลังบันทึก…"
             : isCreate   ? "ส่งขออนุมัติ"
             : isResubmit ? "ส่งขออนุมัติอีกครั้ง"
             : "บันทึก"}
          </Button>
        )}
      </div>
    </div>
  );

  return (
    <Modal open onClose={onClose} width={1000}
      title={isCreate ? "สร้างผู้จำหน่ายใหม่"
            : isResubmit ? `แก้ไข & ส่งใหม่ · ${requestData.request_number}`
            : `${form.supplier_code || ""} · ${form.supplier_name || ""}`}
      subtitle={isCreate ? "รหัสจะถูกสร้างอัตโนมัติเมื่อผู้อนุมัติยืนยัน"
              : isResubmit ? "แก้ไขข้อมูล แล้วเลือกผู้อนุมัติเพื่อส่งใหม่"
              : (form.tax_id ? `Tax ID: ${form.tax_id}` : null)}
      footer={footer}
    >
      {/* Tabs — docs/history are visible in create/resubmit but render a "available
          after approval" placeholder. Live upload still needs a real supplier_id. */}
      <div className="flex items-center gap-1 mb-4 border-b border-ink-100">
        {[
          { id: "basic",   label: "ข้อมูลพื้นฐาน" },
          { id: "payment", label: "การชำระเงิน" },
          { id: "docs",    label: `เอกสารแนบ (${
            isCreate
              ? Object.keys(stagedDocs).length
              : isResubmit
                ? (reqAttachments.length + Object.keys(stagedDocs).filter(k => !reqAttachments.find(a => a.document_type === k)).length)
                : (full?.documents_current?.length || 0)
          })` },
          { id: "history", label: "ประวัติเอกสาร" },
        ].map(t => (
          <button key={t.id} onClick={() => setTab(t.id)}
            className={`px-3 py-2 text-[12.5px] font-medium relative transition
              ${tab === t.id ? "text-emerald-700" : "text-ink-500 hover:text-ink-800"}`}>
            {t.label}
            {tab === t.id && <span className="absolute bottom-0 left-0 right-0 h-0.5 bg-emerald-600 rounded-t"/>}
          </button>
        ))}
      </div>

      {/* Basic / Contact */}
      {tab === "basic" && (
        <div className="space-y-4">
          <Section title="ข้อมูลพื้นฐาน">
            <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
              <Field label="รหัสผู้จำหน่าย">
                <div className="h-9 px-3 flex items-center font-mono text-emerald-700 bg-ink-50 border border-ink-200 rounded-lg">
                  {form.supplier_code || "สร้างอัตโนมัติ"}
                </div>
              </Field>
              <Field label="ประเภท" required>
                <Select value={form.supplier_type} onChange={e => set("supplier_type", e.target.value)} disabled={!canManage}>
                  {SUPPLIER_TYPES.map(t => <option key={t.code} value={t.code}>{t.label}</option>)}
                </Select>
              </Field>
              <Field label="สถานะ">
                <div className="h-9 flex items-center gap-2">
                  <SupStatusBadge status={form.status || "active"}/>
                </div>
              </Field>
              <Field label="ชื่อผู้จำหน่าย (ไทย)" required className="col-span-2 md:col-span-3">
                <Input value={form.supplier_name || ""} onChange={e => set("supplier_name", e.target.value)}
                  placeholder="เช่น บจก. สยาม สเตชั่นเนอรี่" disabled={!canManage}/>
              </Field>
              <Field label="ชื่อผู้จำหน่าย (English)" className="col-span-2 md:col-span-3">
                <Input value={form.supplier_name_en || ""} onChange={e => set("supplier_name_en", e.target.value)}
                  placeholder="Optional" disabled={!canManage}/>
              </Field>
              <Field label="Tax ID / เลขผู้เสียภาษี" required={form.supplier_type === "company"}
                hint={(() => {
                  const v = String(form.tax_id || "");
                  if (v === "") return "กรอก 13 หลัก";
                  if (v.length === 13) return "ครบ 13 หลัก ✓";
                  return `${v.length} / 13 หลัก`;
                })()}
                error={(() => {
                  const v = String(form.tax_id || "");
                  if (v === "") return null;
                  if (v.length !== 13) return `Tax ID ต้องครบ 13 หลัก (พิมพ์แล้ว ${v.length})`;
                  return null;
                })()}>
                <Input
                  type="text"
                  inputMode="numeric"
                  maxLength="13"
                  value={form.tax_id || ""}
                  onChange={e => set("tax_id", e.target.value.replace(/\D/g, "").slice(0, 13))}
                  placeholder="0000000000000"
                  className="font-mono"
                  disabled={!canManage}/>
              </Field>
              <Field label="รหัสสาขา"
                required={form.supplier_type === "company"}
                hint={(() => {
                  const v = String(form.branch_code || "");
                  if (v === "") return "00000 = สำนักงานใหญ่";
                  if (v.length === 5) return "ครบ 5 หลัก ✓";
                  return `${v.length} / 5 หลัก`;
                })()}
                error={(() => {
                  const v = String(form.branch_code || "");
                  if (v === "") {
                    if (form.supplier_type === "company") return "นิติบุคคลต้องระบุรหัสสาขา";
                    return null;
                  }
                  if (v.length !== 5) return `รหัสสาขาต้องครบ 5 หลัก (พิมพ์แล้ว ${v.length})`;
                  return null;
                })()}>
                <Input
                  type="text"
                  inputMode="numeric"
                  maxLength="5"
                  value={form.branch_code || ""}
                  onChange={e => set("branch_code", e.target.value.replace(/\D/g, "").slice(0, 5))}
                  placeholder="00000"
                  className="font-mono"
                  disabled={!canManage}/>
              </Field>
              <Field label="ชื่อสาขา">
                <Input value={form.branch_name || ""} onChange={e => set("branch_name", e.target.value)}
                  placeholder="สำนักงานใหญ่" disabled={!canManage}/>
              </Field>
            </div>
          </Section>

          <Section title="ข้อมูลติดต่อ">
            <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
              <Field label="ผู้ติดต่อ">
                <Input value={form.contact_person || ""} onChange={e => set("contact_person", e.target.value)} disabled={!canManage}/>
              </Field>
              <Field label="โทรศัพท์">
                <Input value={form.contact_phone || ""} onChange={e => set("contact_phone", e.target.value)} disabled={!canManage}/>
              </Field>
              <Field label="อีเมล">
                <Input type="email" value={form.contact_email || ""} onChange={e => set("contact_email", e.target.value)} disabled={!canManage}/>
              </Field>
              <Field label="ที่อยู่" className="col-span-2 md:col-span-3">
                <Textarea rows={2} value={form.address || ""} onChange={e => set("address", e.target.value)} disabled={!canManage}/>
              </Field>
              <Field label="ประเทศ">
                <Input value={form.country || "TH"} onChange={e => set("country", e.target.value)} disabled={!canManage}/>
              </Field>
            </div>
          </Section>

          {/* Audit trail — who created / last updated this record */}
          {!isCreate && !isResubmit && (form.created_at || form.created_by_user_id) && (
            <Section title="ประวัติการบันทึก">
              <div className="grid grid-cols-1 md:grid-cols-2 gap-3 text-[12.5px]">
                <div>
                  <div className="text-[10.5px] text-ink-500">สร้างเมื่อ</div>
                  <div className="font-mono">{form.created_at ? formatDateTime(form.created_at) : "—"}</div>
                  <div className="text-[10.5px] text-ink-500 mt-1">โดย</div>
                  <div className="text-ink-800">{form.created_by_user_id || "—"}</div>
                </div>
                <div>
                  <div className="text-[10.5px] text-ink-500">แก้ไขล่าสุด</div>
                  <div className="font-mono">{form.updated_at ? formatDateTime(form.updated_at) : "—"}</div>
                  <div className="text-[10.5px] text-ink-500 mt-1">โดย</div>
                  <div className="text-ink-800">{form.updated_by_user_id || "—"}</div>
                </div>
              </div>
            </Section>
          )}
        </div>
      )}

      {/* Payment */}
      {tab === "payment" && (
        <Section title="ข้อมูลการชำระเงิน">
          <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
            <Field label="ธนาคาร">
              <Input value={form.bank_name || ""} onChange={e => set("bank_name", e.target.value)} placeholder="เช่น กสิกรไทย" disabled={!canManage}/>
            </Field>
            <Field label="เลขที่บัญชี">
              <Input value={form.bank_account_number || ""} onChange={e => set("bank_account_number", e.target.value)} disabled={!canManage}/>
            </Field>
            <Field label="ชื่อบัญชี">
              <Input value={form.bank_account_name || ""} onChange={e => set("bank_account_name", e.target.value)} disabled={!canManage}/>
            </Field>
            <Field label="เงื่อนไขการชำระเงิน">
              <Input value={form.payment_term || ""} onChange={e => set("payment_term", e.target.value)} placeholder="เช่น เครดิต 30 วัน" disabled={!canManage}/>
            </Field>
            <Field label="สกุลเงินค่าเริ่มต้น">
              <Select value={form.default_currency || "THB"} onChange={e => set("default_currency", e.target.value)} disabled={!canManage}>
                {SUPPLIER_CURRENCIES.map(c => <option key={c} value={c}>{c}</option>)}
              </Select>
            </Field>
            <Field label="หมายเหตุ" className="col-span-2 md:col-span-3">
              <Textarea rows={3} value={form.remark || ""} onChange={e => set("remark", e.target.value)} disabled={!canManage}/>
            </Field>
          </div>
        </Section>
      )}

      {/* Documents — staged-upload UI for create/resubmit (carried over on approval) */}
      {(isCreate || isResubmit) && tab === "docs" && (
        <div className="space-y-4">
          <div className="bg-amber-50 border border-amber-200 rounded-xl p-3 text-[12px] text-amber-800">
            <div className="flex items-center gap-1.5">
              <Icon name="warning" size={12}/>
              เอกสารแนบสูงสุด 4 ประเภท · ไฟล์ละไม่เกิน 5 MB · รองรับ PDF / JPG / PNG / DOCX / XLSX
              {isCreate && <span className="ml-1">— ไฟล์จะถูกอัปโหลดเมื่อกด "ส่งขออนุมัติ"</span>}
            </div>
          </div>
          <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
            {SUPPLIER_DOC_TYPES.map(dt => {
              const staged = stagedDocs[dt.code];
              const existing = reqAttachments.find(a => a.document_type === dt.code);
              const has = !!staged || !!existing;
              return (
                <div key={dt.code} className={`rounded-xl border p-3 ${has ? "border-emerald-200 bg-emerald-50/30" : "border-ink-200 bg-white"}`}>
                  <div className="flex items-center gap-2 mb-2">
                    <Icon name={dt.icon} size={14} className="text-emerald-700"/>
                    <div className="text-[12.5px] font-semibold text-ink-900 flex-1">{dt.label}</div>
                    {staged && <Badge color="amber">รออัปโหลด</Badge>}
                    {!staged && existing && <Badge color="emerald">แนบแล้ว</Badge>}
                  </div>
                  {staged ? (
                    <div className="space-y-2">
                      <div className="text-[12px] text-ink-700 truncate">📎 {staged.file.name} · {fmtBytes2(staged.file.size)}</div>
                      <div className="grid grid-cols-2 gap-2">
                        <Field label="วันหมดอายุ (ถ้ามี)" hint="วว-ดด-ปปปป (ค.ศ.)">
                          {window.ThaiDateInput
                            ? <window.ThaiDateInput value={staged.expiry || ""}
                                onChange={(v) => setStagedDocs(p => ({ ...p, [dt.code]: { ...p[dt.code], expiry: v } }))}/>
                            : <Input type="date" value={staged.expiry || ""}
                                onChange={e => setStagedDocs(p => ({ ...p, [dt.code]: { ...p[dt.code], expiry: e.target.value } }))}/>}
                        </Field>
                        <Field label="หมายเหตุ">
                          <Input value={staged.remark || ""}
                            onChange={e => setStagedDocs(p => ({ ...p, [dt.code]: { ...p[dt.code], remark: e.target.value } }))}/>
                        </Field>
                      </div>
                      <button onClick={() => setStagedDocs(p => { const c={...p}; delete c[dt.code]; return c; })}
                        className="text-[11px] text-rose-700 hover:underline">— ลบไฟล์ที่เลือก</button>
                    </div>
                  ) : existing ? (
                    <div className="space-y-1">
                      <div className="text-[12px] text-ink-700 truncate">📎 {existing.filename} · {fmtBytes2(existing.file_size || 0)}</div>
                      {existing.expiry_date && <div className="text-[11px] text-ink-500">หมดอายุ: {formatDate(existing.expiry_date)}</div>}
                      <div className="flex items-center gap-2 mt-1.5">
                        <button onClick={async () => {
                          try {
                            const blob = await window.apiClient.supplierCreateReqDownloadAttachmentBlob(tenant.id, requestData.id, existing.id);
                            const url = URL.createObjectURL(blob);
                            const a = document.createElement("a"); a.href = url; a.download = existing.filename;
                            document.body.appendChild(a); a.click(); a.remove();
                            setTimeout(() => URL.revokeObjectURL(url), 1000);
                          } catch (e) { toast({ kind:"error", msg: e.message }); }
                        }} className="text-[11px] text-emerald-700 hover:underline">⤓ ดาวน์โหลด</button>
                        <button onClick={async () => {
                          if (!confirm(`ลบไฟล์ ${existing.filename} ?`)) return;
                          try {
                            await window.apiClient.supplierCreateReqDeleteAttachment(tenant.id, requestData.id, existing.id);
                            setReqAttachments(prev => prev.filter(a => a.id !== existing.id));
                          } catch (e) { toast({ kind:"error", msg: e.message }); }
                        }} className="text-[11px] text-rose-700 hover:underline">— ลบ</button>
                        <label className="text-[11px] text-blue-700 hover:underline cursor-pointer">
                          ↻ แทนที่
                          <input type="file" accept=".pdf,.jpg,.jpeg,.png,.docx,.xlsx" className="hidden"
                            onChange={e => {
                              const f = e.target.files?.[0]; if (!f) return;
                              if (f.size > 5*1024*1024) { toast({ kind:"error", msg:"ไฟล์เกิน 5MB" }); return; }
                              setStagedDocs(p => ({ ...p, [dt.code]: { file: f, expiry: existing.expiry_date || "", remark: existing.remark || "" } }));
                            }}/>
                        </label>
                      </div>
                    </div>
                  ) : (
                    <div className="space-y-2">
                      <input type="file" accept=".pdf,.jpg,.jpeg,.png,.docx,.xlsx"
                        onChange={e => {
                          const f = e.target.files?.[0]; if (!f) return;
                          if (f.size > 5*1024*1024) { toast({ kind:"error", msg:"ไฟล์เกิน 5MB" }); return; }
                          setStagedDocs(p => ({ ...p, [dt.code]: { file: f, expiry: "", remark: "" } }));
                        }}
                        className="block w-full text-[11.5px] file:mr-3 file:px-3 file:py-1.5 file:rounded-md file:border-0 file:bg-emerald-50 file:text-emerald-700 hover:file:bg-emerald-100"/>
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        </div>
      )}

      {/* Documents — real upload only on existing suppliers */}
      {!isCreate && !isResubmit && tab === "docs" && (
        <div className="space-y-4">
          <div className="bg-amber-50 border border-amber-200 rounded-xl p-3 text-[12px] text-amber-800">
            <div className="flex items-center gap-1.5"><Icon name="warning" size={12}/> เอกสารแนบสูงสุด 4 ประเภท · ไฟล์ละไม่เกิน 5 MB · รองรับ PDF / JPG / PNG / DOCX / XLSX</div>
          </div>
          <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
            {SUPPLIER_DOC_TYPES.map(dt => {
              const doc = (full?.documents_current || []).find(d => d.document_type === dt.code);
              return (
                <DocumentSlot key={dt.code}
                  docType={dt}
                  doc={doc}
                  canManage={canManage}
                  onUpload={() => setUploadFor({ docType: dt, replace: !!doc })}
                  onDownload={() => downloadDoc(tenant, supplier.id, doc, toast)}/>
              );
            })}
          </div>
        </div>
      )}

      {/* Document history — placeholder for create/resubmit (no real history yet) */}
      {(isCreate || isResubmit) && tab === "history" && (
        <div className="rounded-xl border-2 border-dashed border-ink-200 bg-ink-50/40 p-8 text-center">
          <Icon name="history" size={28} className="text-ink-400 mx-auto mb-2"/>
          <div className="text-[14px] font-semibold text-ink-700 mb-1">ยังไม่มีประวัติเอกสาร</div>
          <div className="text-[12.5px] text-ink-500 max-w-md mx-auto leading-relaxed">
            ประวัติจะเริ่มสะสมเมื่อ supplier ถูกอนุมัติแล้วและมีการแนบ/แทนที่ไฟล์ในภายหลัง
          </div>
        </div>
      )}

      {/* Document history — real list only on existing suppliers */}
      {!isCreate && !isResubmit && tab === "history" && (
        <Section title="ประวัติเอกสารทั้งหมด (รวมเอกสารถูกแทนที่)">
          {(!full?.documents_history?.length && !full?.documents_current?.length) ? (
            <div className="text-center py-6 text-[12px] text-ink-500">ยังไม่มีประวัติ</div>
          ) : (
            <table className="w-full text-[12px]">
              <thead className="bg-ink-50/60 text-ink-500 text-[10.5px] uppercase">
                <tr>
                  <th className="text-left px-3 py-2">ประเภท</th>
                  <th className="text-left px-3 py-2">ไฟล์</th>
                  <th className="text-left px-3 py-2">วันหมดอายุ</th>
                  <th className="text-left px-3 py-2">สถานะ</th>
                  <th className="text-left px-3 py-2">อัปโหลดเมื่อ</th>
                  <th className="text-center px-3 py-2">ดาวน์โหลด</th>
                </tr>
              </thead>
              <tbody>
                {[...(full?.documents_current || []), ...(full?.documents_history || [])].map(d => {
                  const dt = SUPPLIER_DOC_TYPES.find(t => t.code === d.document_type);
                  return (
                    <tr key={d.id} className="border-t border-ink-100">
                      <td className="px-3 py-2 text-ink-700">{dt?.label || d.document_type}</td>
                      <td className="px-3 py-2">
                        <div className="text-ink-800 truncate max-w-[260px]">{d.filename}</div>
                        <div className="text-[10.5px] text-ink-500 font-mono">{fmtBytes2(d.file_size)}</div>
                      </td>
                      <td className="px-3 py-2 font-mono text-ink-700">{d.expiry_date ? formatDate(d.expiry_date) : "—"}</td>
                      <td className="px-3 py-2"><DocStatusBadge status={d.doc_status}/></td>
                      <td className="px-3 py-2 text-ink-500 font-mono whitespace-nowrap">{formatDateTime(d.uploaded_at)}</td>
                      <td className="px-3 py-2 text-center">
                        <button onClick={() => downloadDoc(tenant, supplier.id, d, toast)}
                          className="text-emerald-700 hover:underline text-[11.5px]">
                          <Icon name="paperclip" size={11} className="inline mr-0.5"/> ดาวน์โหลด
                        </button>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}
        </Section>
      )}

      {/* Approver picker — always visible at the bottom in create/resubmit modes
          regardless of which tab is active, so the user never loses sight of it. */}
      {needsApprover && (
        <div className="mt-4">
          <Section title="ส่งขออนุมัติ">
            {isResubmit && requestData?.approver_comment && (
              <div className="mb-2 text-[12px] text-rose-800 bg-rose-50/70 border border-rose-200 rounded-lg p-2.5">
                <strong>เหตุผลที่ถูกปฏิเสธ:</strong> {requestData.approver_comment}
              </div>
            )}
            <div className="grid grid-cols-2 gap-3">
              <Field label="ผู้อนุมัติ" required hint="เลือกผู้อื่นในบริษัท — ไม่สามารถอนุมัติเองได้">
                <Select value={approverUserId} onChange={e => setApproverUserId(e.target.value)}>
                  <option value="">— เลือกผู้อนุมัติ —</option>
                  {approverOptions.map(u => <option key={u.id} value={u.id}>{u.label} ({u.email})</option>)}
                </Select>
                {approverOptions.length === 0 && (
                  <div className="text-[11px] text-rose-700 mt-1">⚠ ยังไม่มีสมาชิกอื่นในบริษัทที่อนุมัติได้ — กรุณาเพิ่มสมาชิกใน User Management ก่อน</div>
                )}
              </Field>
              <Field label="ความคิดเห็นถึงผู้อนุมัติ">
                <Input value={requesterComment} onChange={e => setRequesterComment(e.target.value)}
                  placeholder="เหตุผล / บริบทเพิ่มเติม (ถ้ามี)"/>
              </Field>
            </div>
          </Section>
        </div>
      )}

      {/* Modals */}
      {uploadFor && (
        <SupplierDocumentUploadModal
          docType={uploadFor.docType}
          replace={uploadFor.replace}
          tenant={tenant}
          supplierId={supplier.id}
          supplierCode={supplier.supplier_code}
          onClose={() => setUploadFor(null)}
          onDone={() => { setUploadFor(null); reload(); onChanged?.(); }}/>
      )}
      {confirmInactivate && (
        <Modal open onClose={() => setConfirmInactivate(false)}
          title={form.status === "active" ? "ปิดใช้งานผู้จำหน่าย" : "เปิดใช้งานผู้จำหน่าย"}
          subtitle={form.status === "active" ? "ผู้จำหน่ายนี้จะถูกซ่อนจากการเลือกในเอกสารใหม่ · เอกสารเก่ายังคงอ้างอิงได้" : ""}
          footer={<>
            <Button variant="secondary" onClick={() => setConfirmInactivate(false)}>ยกเลิก</Button>
            <Button variant={form.status === "active" ? "danger" : "success"} onClick={handleInactivate}>
              {form.status === "active" ? "ปิดใช้งาน" : "เปิดใช้งาน"}
            </Button>
          </>}>
          <div className="text-[12.5px] text-ink-700">{form.supplier_code} · {form.supplier_name}</div>
        </Modal>
      )}
    </Modal>
  );
};

const Section = ({ title, children }) => (
  <div>
    <div className="text-[12px] uppercase tracking-wider text-ink-500 font-semibold mb-2">{title}</div>
    {children}
  </div>
);

const DocumentSlot = ({ docType, doc, canManage, onUpload, onDownload }) => {
  const has = !!doc;
  const status = doc?.doc_status || "no_documents";
  const bg = status === "expired" ? "border-rose-200 bg-rose-50/40"
           : status === "expiring_soon" ? "border-amber-200 bg-amber-50/40"
           : has ? "border-emerald-200 bg-emerald-50/40" : "border-ink-200 bg-ink-50/40";
  return (
    <div className={`rounded-xl border-2 ${bg} p-3`}>
      <div className="flex items-start gap-3">
        <div className={`w-9 h-9 rounded-lg flex items-center justify-center shrink-0
          ${has ? (status === "expired" ? "bg-rose-100 text-rose-700" : status === "expiring_soon" ? "bg-amber-100 text-amber-700" : "bg-emerald-100 text-emerald-700") : "bg-ink-100 text-ink-400"}`}>
          <Icon name={docType.icon} size={14}/>
        </div>
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 flex-wrap">
            <div className="text-[12.5px] font-semibold text-ink-900">{docType.label}</div>
            {has && <DocStatusBadge status={status}/>}
          </div>
          {has ? (
            <>
              <div className="text-[12px] text-ink-700 truncate mt-0.5">{doc.filename}</div>
              <div className="text-[10.5px] text-ink-500 font-mono">{fmtBytes2(doc.file_size)} · อัปโหลด {formatDateTime(doc.uploaded_at)}</div>
              {doc.expiry_date && (
                <div className="text-[11px] text-ink-600 mt-0.5">หมดอายุ: <span className="font-mono">{formatDate(doc.expiry_date)}</span></div>
              )}
              <div className="flex items-center gap-2 mt-2">
                <button onClick={onDownload}
                  className="text-[11px] text-emerald-700 hover:underline">
                  <Icon name="paperclip" size={11} className="inline mr-0.5"/> ดาวน์โหลด
                </button>
                {canManage && (
                  <button onClick={onUpload}
                    className="text-[11px] text-amber-700 hover:underline">
                    ↻ แทนที่ไฟล์
                  </button>
                )}
              </div>
            </>
          ) : (
            <>
              <div className="text-[11px] text-ink-500 mt-0.5">ยังไม่มีไฟล์</div>
              {canManage && (
                <Button variant="soft" size="sm" icon="plus" className="mt-2" onClick={onUpload}>อัปโหลด</Button>
              )}
            </>
          )}
        </div>
      </div>
    </div>
  );
};

const downloadDoc = async (tenant, supId, doc, toast) => {
  if (!doc) return;
  try {
    const blob = await window.apiClient.suppliersDownloadDocumentBlob(tenant.id, supId, doc.id);
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = doc.filename; a.click();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
  } catch (e) {
    toast({ kind: "error", msg: e.message || "ดาวน์โหลดไม่สำเร็จ" });
  }
};

// =============================================================================
// DOCUMENT UPLOAD MODAL
// =============================================================================
const SupplierDocumentUploadModal = ({ docType, replace, tenant, supplierId, supplierCode, onClose, onDone }) => {
  const toast = useToast();
  const [file, setFile] = useState(null);
  const [expiryDate, setExpiryDate] = useState("");
  const [remark, setRemark] = useState("");
  const [replacementReason, setReplacementReason] = useState("");
  const [busy, setBusy] = useState(false);

  const upload = async () => {
    if (!file) { toast({ kind: "warn", msg: "กรุณาเลือกไฟล์" }); return; }
    if (file.size > 5 * 1024 * 1024) { toast({ kind: "warn", msg: "ไฟล์ใหญ่เกิน 5 MB" }); return; }
    const ext = (file.name.split(".").pop() || "").toLowerCase();
    if (!["pdf","jpg","jpeg","png","docx","xlsx"].includes(ext)) {
      toast({ kind: "warn", msg: "ชนิดไฟล์ไม่รองรับ" }); return;
    }
    setBusy(true);
    try {
      await window.apiClient.suppliersUploadDocument(tenant.id, supplierId, file, {
        document_type: docType.code,
        expiry_date: expiryDate || null,
        remark: remark || null,
        replacement_reason: replace ? replacementReason : null,
      });
      toast({ kind: "success", msg: replace ? "แทนที่ไฟล์เรียบร้อย" : "อัปโหลดเรียบร้อย" });
      onDone();
    } catch (e) { toast({ kind: "error", msg: e.message || "อัปโหลดไม่สำเร็จ" }); }
    finally { setBusy(false); }
  };

  return (
    <Modal open onClose={onClose} width={560}
      title={replace ? `แทนที่ไฟล์: ${docType.label}` : `อัปโหลดเอกสาร: ${docType.label}`}
      subtitle={`${supplierCode} · ไฟล์ไม่เกิน 5 MB`}
      footer={<>
        <Button variant="secondary" onClick={onClose}>ยกเลิก</Button>
        <Button variant="primary" icon="paperclip" onClick={upload} disabled={busy || !file}>
          {busy ? "กำลังอัปโหลด…" : (replace ? "แทนที่" : "อัปโหลด")}
        </Button>
      </>}>
      <div className="space-y-3">
        <Field label="เลือกไฟล์ (PDF / JPG / PNG / DOCX / XLSX · สูงสุด 5 MB)" required>
          <input type="file" accept=".pdf,.jpg,.jpeg,.png,.docx,.xlsx"
            onChange={e => setFile(e.target.files?.[0] || null)}
            className="w-full text-[12.5px] file:mr-3 file:py-1.5 file:px-3 file:rounded-md file:border-0 file:bg-emerald-600 file:text-white file:font-medium hover:file:bg-emerald-700"/>
          {file && <div className="text-[11px] text-ink-500 mt-1.5">{file.name} · {fmtBytes2(file.size)}</div>}
        </Field>
        <Field label="วันหมดอายุของเอกสาร" hint="ไม่บังคับ — ปล่อยว่างถ้าไม่มี">
          <ThaiDateInput value={expiryDate} onChange={setExpiryDate}/>
        </Field>
        <Field label="หมายเหตุ">
          <Textarea rows={2} value={remark} onChange={e => setRemark(e.target.value)} placeholder="ไม่บังคับ"/>
        </Field>
        {replace && (
          <Field label="เหตุผลในการแทนที่" hint="จะถูกบันทึกใน audit log">
            <Textarea rows={2} value={replacementReason} onChange={e => setReplacementReason(e.target.value)}
              placeholder='เช่น "เอกสารเดิมหมดอายุ · ผู้จำหน่ายส่งเอกสารใหม่"'/>
          </Field>
        )}
      </div>
    </Modal>
  );
};

// =============================================================================
// SEARCHABLE SUPPLIER PICKER — for PC integration
// =============================================================================
const SupplierSearchablePicker = ({ tenant, value, onChange, placeholder = "พิมพ์รหัส / ชื่อ / Tax ID เพื่อค้นหา…" }) => {
  const [suppliers, setSuppliers] = useState([]);
  const [q, setQ] = useState("");
  const [open, setOpen] = useState(false);
  const wrapRef = useRef(null);
  useEffect(() => {
    const close = (e) => { if (!wrapRef.current?.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", close);
    return () => document.removeEventListener("mousedown", close);
  }, []);
  useEffect(() => {
    if (!tenant?.id) return;
    window.apiClient.suppliersList(tenant.id, { status: "active" }).then(list => {
      setSuppliers(Array.isArray(list) ? list.filter(s => s.status === "active") : []);
    }).catch(() => setSuppliers([]));
  }, [tenant?.id]);

  const selected = suppliers.find(s => s.id === value);
  const ql = q.trim().toLowerCase();
  const filtered = useMemo(() => {
    const base = ql
      ? suppliers.filter(s =>
          (s.supplier_code || "").toLowerCase().includes(ql) ||
          (s.supplier_name || "").toLowerCase().includes(ql) ||
          (s.supplier_name_en || "").toLowerCase().includes(ql) ||
          (s.tax_id || "").toLowerCase().includes(ql))
      : suppliers;
    return base.slice(0, 60);
  }, [suppliers, ql]);

  return (
    <div ref={wrapRef} className="relative">
      {selected && !open ? (
        <button type="button" onClick={() => { setOpen(true); setQ(""); }}
          className="w-full h-9 px-2.5 flex items-center gap-2 bg-white border border-ink-200 hover:border-emerald-400 rounded-lg text-left transition">
          <span className="w-7 h-7 rounded-md bg-emerald-100 text-emerald-700 flex items-center justify-center"><Icon name="building" size={12}/></span>
          <span className="flex-1 min-w-0">
            <span className="text-[12.5px] text-ink-900 truncate block">{selected.supplier_name}</span>
            <span className="text-[10.5px] text-emerald-700 font-mono truncate block">{selected.supplier_code}{selected.tax_id ? " · " + selected.tax_id : ""}</span>
          </span>
          {selected.doc_status === "expired" && <Badge color="rose">เอกสารหมดอายุ</Badge>}
          {selected.doc_status === "expiring_soon" && <Badge color="amber">ใกล้หมดอายุ</Badge>}
          <Tip tip="ยกเลิก"><span role="button" tabIndex={0}
            onClick={(e) => { e.stopPropagation(); onChange(null, null); setQ(""); }}
            className="p-1 text-ink-400 hover:text-rose-500"><Icon name="x" size={12}/></span></Tip>
          <Icon name="chevronDown" size={13} className="text-ink-400 shrink-0"/>
        </button>
      ) : (
        <div className="relative">
          <Icon name="search" size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-ink-400"/>
          <input autoFocus={open} type="text" value={q} onChange={e => { setQ(e.target.value); setOpen(true); }}
            onFocus={() => setOpen(true)} placeholder={placeholder}
            className="w-full h-9 pl-9 pr-3 text-[13px] border border-ink-200 rounded-lg bg-white focus:border-emerald-500 ring-focus"/>
        </div>
      )}

      {open && (
        <div className="absolute z-30 mt-1 w-full max-h-[300px] overflow-y-auto thin-scroll bg-white border border-ink-200 rounded-lg shadow-lg">
          {filtered.length === 0 ? (
            <div className="px-3 py-4 text-center text-[12px] text-ink-500">
              {ql ? `ไม่พบ "${q}"` : "ยังไม่มีผู้จำหน่าย (active)"}
            </div>
          ) : filtered.map(s => {
            const isSel = s.id === value;
            return (
              <button key={s.id} type="button"
                onClick={() => { onChange(s.id, s); setOpen(false); setQ(""); }}
                className={`w-full px-3 py-2 text-left border-b border-ink-50 last:border-b-0 transition
                  ${isSel ? "bg-emerald-50" : "hover:bg-emerald-50/40"}`}>
                <div className="flex items-center gap-2 flex-wrap">
                  <span className="font-mono text-[11.5px] font-bold text-emerald-700">{s.supplier_code}</span>
                  <span className="text-[12.5px] font-semibold text-ink-900 truncate">{s.supplier_name}</span>
                  {s.doc_status === "expired" && <Badge color="rose">หมดอายุ</Badge>}
                  {s.doc_status === "expiring_soon" && <Badge color="amber">ใกล้หมดอายุ</Badge>}
                  {isSel && <Icon name="check" size={12} className="text-emerald-600 ml-auto"/>}
                </div>
                <div className="text-[10.5px] text-ink-500 mt-0.5">
                  {[s.tax_id, s.contact_person, s.default_currency].filter(Boolean).join(" · ")}
                </div>
              </button>
            );
          })}
          {suppliers.length > filtered.length && (
            <div className="px-3 py-2 text-center text-[10.5px] text-ink-400 italic border-t border-ink-50">
              แสดง {filtered.length} จาก {suppliers.length} · พิมพ์เพื่อค้นหา
            </div>
          )}
        </div>
      )}
    </div>
  );
};

// =============================================================================
// CREATE-REQUEST DETAIL DRAWER — view + approve / reject / cancel + edit-resubmit / delete
// =============================================================================
const SupplierCreateRequestDrawer = ({ request, tenant, currentUser, currentRole, users, onClose, onChanged, onEdit }) => {
  const toast = useToast();
  const [detail, setDetail] = useState(request);
  const [act, setAct] = useState(null);     // null | 'reject' | 'cancel'
  const [comment, setComment] = useState("");
  const [busy, setBusy] = useState(false);
  const [preview, setPreview] = useState(null);  // file preview modal state
  const closePreview = () => {
    if (preview?.url) { try { URL.revokeObjectURL(preview.url); } catch {} }
    setPreview(null);
  };
  const myId = currentUser?.id || currentUser?.api_user_id;
  const reload = async () => {
    try {
      const d = await window.apiClient.supplierCreateReqGet(tenant.id, request.id);
      setDetail(d);
    } catch (e) { toast({ kind:"error", msg: e.message || "โหลดไม่สำเร็จ" }); }
  };
  useEffect(() => { reload(); /* eslint-disable-next-line */ }, [request?.id]);

  const runAct = async (actType, commentValue) => {
    if (actType === "reject" && !(commentValue || "").trim()) {
      toast({ kind:"error", msg:"กรุณาระบุเหตุผลในการปฏิเสธ" }); return;
    }
    setBusy(true);
    try {
      if (actType === "approve") await window.apiClient.supplierCreateReqApprove(tenant.id, request.id, commentValue || "");
      if (actType === "reject")  await window.apiClient.supplierCreateReqReject(tenant.id, request.id, commentValue || "");
      if (actType === "cancel")  await window.apiClient.supplierCreateReqCancel(tenant.id, request.id, commentValue || "");
      toast({ kind:"success", msg: actType === "approve" ? "อนุมัติคำขอแล้ว · ผู้จำหน่ายถูกสร้างเรียบร้อย" : "ดำเนินการแล้ว" });
      onChanged && onChanged();
      onClose && onClose();
    } catch (e) { toast({ kind:"error", msg: e.message || "ดำเนินการไม่สำเร็จ" }); }
    finally { setBusy(false); }
  };

  if (!detail) return null;
  const isOwnRequest = myId && detail.created_by_user_id === myId;

  return (
    <Drawer open onClose={onClose}
      title={`คำขอสร้างผู้จำหน่าย ${detail.request_number}`}
      subtitle={`${detail.supplier_name}${detail.tax_id ? " · Tax ID: " + detail.tax_id : ""}`}
      width={620}>
      <div className="flex items-center gap-2 mb-3">
        <Badge color={
          detail.status === "pending" ? "amber" :
          detail.status === "approved" ? "emerald" :
          detail.status === "rejected" ? "rose" : "slate"
        } icon={
          detail.status === "pending" ? "clock" :
          detail.status === "approved" ? "checkCircle" :
          detail.status === "rejected" ? "x" : "ban"
        }>
          {detail.status === "pending" ? "รออนุมัติ" :
           detail.status === "approved" ? "อนุมัติแล้ว" :
           detail.status === "rejected" ? "ปฏิเสธ" : "ยกเลิก"}
        </Badge>
        <div className="ml-auto text-[11px] text-ink-500">{formatDateTime(detail.created_at)}</div>
      </div>

      <div className="grid grid-cols-2 gap-3 text-[12.5px] mb-3">
        <div className="rounded-lg border border-ink-100 bg-white px-3 py-2">
          <div className="text-[10.5px] uppercase tracking-wider text-ink-400 font-semibold">ชื่อ (ไทย)</div>
          <div className="text-ink-900 mt-0.5">{detail.supplier_name}</div>
        </div>
        <div className="rounded-lg border border-ink-100 bg-white px-3 py-2">
          <div className="text-[10.5px] uppercase tracking-wider text-ink-400 font-semibold">ชื่อ (English)</div>
          <div className="text-ink-900 mt-0.5">{detail.supplier_name_en || "—"}</div>
        </div>
        <div className="rounded-lg border border-ink-100 bg-white px-3 py-2">
          <div className="text-[10.5px] uppercase tracking-wider text-ink-400 font-semibold">ประเภท</div>
          <div className="text-ink-900 mt-0.5">
            {SUPPLIER_TYPES.find(t => t.code === detail.supplier_type)?.label || detail.supplier_type}
          </div>
        </div>
        <div className="rounded-lg border border-ink-100 bg-white px-3 py-2">
          <div className="text-[10.5px] uppercase tracking-wider text-ink-400 font-semibold">Tax ID · สาขา</div>
          <div className="text-ink-900 mt-0.5 font-mono">
            {detail.tax_id || "—"}{detail.branch_code ? ` · ${detail.branch_code}` : ""}
            {detail.branch_name ? <span className="font-sans text-ink-500"> ({detail.branch_name})</span> : null}
          </div>
        </div>
        <div className="rounded-lg border border-ink-100 bg-white px-3 py-2">
          <div className="text-[10.5px] uppercase tracking-wider text-ink-400 font-semibold">ผู้ติดต่อ</div>
          <div className="text-ink-900 mt-0.5">{detail.contact_person || "—"}</div>
        </div>
        <div className="rounded-lg border border-ink-100 bg-white px-3 py-2">
          <div className="text-[10.5px] uppercase tracking-wider text-ink-400 font-semibold">โทร / อีเมล</div>
          <div className="text-ink-900 mt-0.5">{detail.contact_phone || "—"} · {detail.contact_email || "—"}</div>
        </div>
        <div className="rounded-lg border border-ink-100 bg-white px-3 py-2 col-span-2">
          <div className="text-[10.5px] uppercase tracking-wider text-ink-400 font-semibold">ที่อยู่</div>
          <div className="text-ink-900 mt-0.5 whitespace-pre-wrap">{detail.address || "—"}</div>
        </div>
        <div className="rounded-lg border border-ink-100 bg-white px-3 py-2">
          <div className="text-[10.5px] uppercase tracking-wider text-ink-400 font-semibold">ผู้ขอ</div>
          <div className="text-ink-900 mt-0.5">{
            (users || []).find(u => u.id === detail.created_by_user_id || u.api_user_id === detail.created_by_user_id)?.full_name
            || detail.created_by_user_id
          }</div>
        </div>
        <div className="rounded-lg border border-ink-100 bg-white px-3 py-2">
          <div className="text-[10.5px] uppercase tracking-wider text-ink-400 font-semibold">ผู้อนุมัติ</div>
          <div className="text-ink-900 mt-0.5">{
            (users || []).find(u => u.id === detail.approver_user_id || u.api_user_id === detail.approver_user_id)?.full_name
            || detail.approver_user_id
          }</div>
        </div>
        {detail.requester_comment && (
          <div className="col-span-2 rounded-lg border border-blue-100 bg-blue-50/50 p-3 text-blue-900">
            <div className="text-[10.5px] uppercase tracking-wider text-blue-700 font-semibold mb-1">ความคิดเห็นจากผู้ขอ</div>
            <div className="whitespace-pre-wrap">{detail.requester_comment}</div>
          </div>
        )}
        {detail.approver_comment && (
          <div className="col-span-2 rounded-lg border border-amber-200 bg-amber-50/50 p-3 text-amber-900">
            <div className="text-[10.5px] uppercase tracking-wider text-amber-700 font-semibold mb-1">ความคิดเห็นจากผู้อนุมัติ</div>
            <div className="whitespace-pre-wrap">{detail.approver_comment}</div>
          </div>
        )}
      </div>

      {/* Attachments — files the requester uploaded */}
      <div className="text-[11px] uppercase tracking-wider text-ink-500 font-semibold mb-1.5 mt-3">
        ไฟล์แนบ ({(detail.attachments || []).length})
      </div>
      {(detail.attachments || []).length === 0 ? (
        <div className="rounded-xl border-2 border-dashed border-ink-200 bg-ink-50/30 p-4 text-center text-[12px] text-ink-500">
          — ผู้ขอไม่ได้แนบไฟล์มา —
        </div>
      ) : (detail.attachments).map(att => {
        const docMeta = SUPPLIER_DOC_TYPES.find(d => d.code === att.document_type);
        return (
          <div key={att.id} className="flex items-center gap-3 px-3 py-2 mb-1.5 rounded-lg border border-ink-100 bg-white">
            <Icon name="paperclip" size={14} className="text-ink-500"/>
            <div className="flex-1 min-w-0">
              <div className="text-[12.5px] text-ink-900 truncate">{att.filename}</div>
              <div className="text-[10.5px] text-ink-500">
                {docMeta?.label || att.document_type}
                {" · "}{fmtBytes2(att.file_size || 0)}
                {att.expiry_date && (<> · หมดอายุ <span className="font-mono">{formatDate(att.expiry_date)}</span></>)}
              </div>
            </div>
            <Button variant="ghost" icon="eye" onClick={async () => {
              try {
                const blob = await window.apiClient.supplierCreateReqDownloadAttachmentBlob(tenant.id, detail.id, att.id);
                const url = URL.createObjectURL(blob);
                if (window.FAFilePreviewModal) {
                  setPreview({ url, contentType: att.content_type || blob.type, filename: att.filename, att });
                } else {
                  window.open(url, "_blank");
                }
              } catch (e) { toast({ kind:"error", msg: e.message }); }
            }}>ดูตัวอย่าง</Button>
            <Button variant="ghost" icon="download" onClick={async () => {
              try {
                const blob = await window.apiClient.supplierCreateReqDownloadAttachmentBlob(tenant.id, detail.id, att.id);
                const url = URL.createObjectURL(blob);
                const a = document.createElement("a"); a.href = url; a.download = att.filename;
                document.body.appendChild(a); a.click(); a.remove();
                setTimeout(() => URL.revokeObjectURL(url), 1000);
              } catch (e) { toast({ kind:"error", msg: e.message }); }
            }}>โหลด</Button>
          </div>
        );
      })}

      {/* Pending — approver action */}
      {detail.status === "pending" && (
        <div className="mt-4 border-t border-ink-100 pt-3">
          {act ? (
            <div className="space-y-2">
              <Field label={`ความคิดเห็น ${act === "reject" ? "*" : "(ถ้ามี)"}`}>
                <Textarea rows={3} value={comment} onChange={e=>setComment(e.target.value)}/>
              </Field>
              <div className="flex justify-end gap-2">
                <Button variant="ghost" onClick={()=>{ setAct(null); setComment(""); }}>ยกเลิก</Button>
                <Button variant="danger" icon={act === "reject" ? "x" : "ban"}
                  onClick={()=>runAct(act, comment)} disabled={busy}>
                  {busy ? "กำลังบันทึก…" : act === "reject" ? "ยืนยันปฏิเสธ" : "ยืนยันยกเลิก"}
                </Button>
              </div>
            </div>
          ) : isOwnRequest ? (
            <div className="flex items-center gap-2 justify-end">
              <span className="mr-auto text-[11.5px] text-ink-500">
                ℹ คุณเป็นผู้สร้างคำขอนี้ — ยกเลิกได้ แต่อนุมัติ/ปฏิเสธไม่ได้
              </span>
              <Button variant="ghost" icon="ban" onClick={()=>setAct("cancel")}>ยกเลิกคำขอ</Button>
            </div>
          ) : (
            <div className="flex items-center gap-2 justify-end">
              <Button variant="ghost" icon="x" onClick={()=>setAct("reject")} disabled={busy}>ปฏิเสธ</Button>
              <Button variant="primary" icon="checkCircle" onClick={()=>runAct("approve", "")} disabled={busy}>
                {busy ? "กำลังอนุมัติ…" : "อนุมัติ"}
              </Button>
            </div>
          )}
        </div>
      )}

      {/* Rejected/Cancelled — requester action */}
      {(detail.status === "rejected" || detail.status === "cancelled") && isOwnRequest && (
        <div className="mt-4 border-t border-ink-100 pt-3 flex items-center gap-2 justify-end">
          <span className="mr-auto text-[11.5px] text-ink-500">
            ℹ คำขอนี้{detail.status === "rejected" ? "ถูกปฏิเสธ" : "ถูกยกเลิก"} — แก้ไขแล้วส่งใหม่ หรือลบทิ้ง
          </span>
          <Button variant="ghost" icon="trash" onClick={async ()=>{
            if (!confirm(`ลบคำขอ ${detail.request_number} ?`)) return;
            try {
              await window.apiClient.supplierCreateReqDelete(tenant.id, detail.id);
              toast({ kind:"success", msg:"ลบคำขอแล้ว" });
              onChanged && onChanged();
              onClose && onClose();
            } catch (e) { toast({ kind:"error", msg: e.message || "ลบไม่สำเร็จ" }); }
          }}>ลบรายการ</Button>
          <Button variant="primary" icon="edit" onClick={()=>onEdit && onEdit(detail)}>แก้ไข & ส่งใหม่</Button>
        </div>
      )}

      {/* Inline file preview — reuses the FA preview modal exported on window */}
      {window.FAFilePreviewModal && (
        <window.FAFilePreviewModal preview={preview} onClose={closePreview}
          onDownload={async () => {
            if (!preview?.att) return;
            try {
              const blob = await window.apiClient.supplierCreateReqDownloadAttachmentBlob(tenant.id, detail.id, preview.att.id);
              const url = URL.createObjectURL(blob);
              const a = document.createElement("a"); a.href = url; a.download = preview.att.filename;
              document.body.appendChild(a); a.click(); a.remove();
              setTimeout(() => URL.revokeObjectURL(url), 1000);
            } catch (e) { toast({ kind:"error", msg: e.message }); }
          }}/>
      )}
    </Drawer>
  );
};

// =============================================================================
// MY SP APPROVAL PAGE — supplier create-requests pending the current user's approval
// =============================================================================
const MySPApprovalPage = ({ tenant, currentUser, currentRole, users }) => {
  const toast = useToast();
  const [reqs, setReqs] = useState([]);
  const [loading, setLoading] = useState(false);
  const [filterStatus, setFilterStatus] = useState("pending");
  const [openReq, setOpenReq] = useState(null);
  const reload = async () => {
    if (!tenant?.id) return;
    setLoading(true);
    try {
      const list = await window.apiClient.supplierCreateReqList(tenant.id, {
        scope: "approver",
        status: filterStatus === "__all__" ? "" : filterStatus,
      });
      setReqs(Array.isArray(list) ? list : []);
    } catch (e) { toast({ kind:"error", msg: e.message || "โหลดไม่สำเร็จ" }); }
    finally { setLoading(false); }
  };
  useEffect(() => { reload(); /* eslint-disable-next-line */ }, [tenant?.id, filterStatus]);

  const pendingCount = reqs.filter(r => r.status === "pending").length;

  return (
    <div className="p-6 max-w-[1400px] mx-auto">
      <div className="text-[11px] tracking-wider text-emerald-700 font-bold mb-1">✓ MY SP APPROVAL</div>
      <div className="flex items-start justify-between gap-3 mb-3">
        <div>
          <div className="text-[24px] font-bold text-ink-900 leading-tight">My SP Approval</div>
          <div className="text-[13px] text-ink-500 mt-1">คำขอสร้างผู้จำหน่ายที่รออนุมัติของคุณ</div>
        </div>
        <div className="flex items-center gap-2">
          <Select value={filterStatus} onChange={e=>setFilterStatus(e.target.value)} className="!w-44">
            <option value="pending">เฉพาะรออนุมัติ</option>
            <option value="__all__">ทุกสถานะ</option>
            <option value="approved">อนุมัติแล้ว</option>
            <option value="rejected">ปฏิเสธ</option>
            <option value="cancelled">ยกเลิก</option>
          </Select>
          <Button variant="secondary" icon="refresh" onClick={reload} disabled={loading}>รีเฟรช</Button>
        </div>
      </div>

      <div className="grid grid-cols-1 gap-3 mb-4">
        <KpiCard tone="amber" label="คำขอสร้างผู้จำหน่ายรออนุมัติ" value={pendingCount}/>
      </div>

      <div className="rounded-xl border border-ink-100 bg-white overflow-hidden">
        <div className="px-4 py-2.5 border-b border-ink-100 flex items-center gap-2">
          <Icon name="building" size={14} className="text-emerald-700"/>
          <div className="text-[13px] font-semibold text-ink-900">คำขอสร้างผู้จำหน่ายใหม่ (Create Supplier Requests)</div>
          <span className="text-[11px] text-ink-500">— ที่คุณเป็นผู้อนุมัติ</span>
          <span className="ml-auto text-[11px] text-ink-500">{reqs.length} รายการ</span>
        </div>
        <div className="overflow-x-auto">
          <table className="w-full text-[12.5px]">
            <thead className="bg-ink-50 text-ink-600 text-[11px] uppercase tracking-wider">
              <tr>
                <th className="px-3 py-2 text-left">เลขที่คำขอ</th>
                <th className="px-3 py-2 text-left">วันที่</th>
                <th className="px-3 py-2 text-left">ชื่อผู้จำหน่าย</th>
                <th className="px-3 py-2 text-left">Tax ID</th>
                <th className="px-3 py-2 text-left">ผู้ขอ</th>
                <th className="px-3 py-2 text-center">สถานะ</th>
                <th className="px-3 py-2 text-right">Action</th>
              </tr>
            </thead>
            <tbody>
              {loading && <tr><td colSpan={7} className="px-3 py-6 text-center text-ink-500">กำลังโหลด…</td></tr>}
              {!loading && reqs.length === 0 && (
                <tr><td colSpan={7} className="px-3 py-8 text-center text-ink-500">ไม่มีคำขอ</td></tr>
              )}
              {reqs.map(r => {
                const requesterName = (users || []).find(u => u.id === r.created_by_user_id || u.api_user_id === r.created_by_user_id)?.full_name || r.created_by_user_id;
                return (
                  <tr key={r.id} className="border-t border-ink-100 hover:bg-ink-50/50">
                    <td className="px-3 py-2 font-mono font-semibold text-ink-900">{r.request_number}</td>
                    <td className="px-3 py-2 font-mono text-ink-600">{r.created_at?.slice(0,10)}</td>
                    <td className="px-3 py-2 text-ink-900 truncate max-w-[260px]">{r.supplier_name}</td>
                    <td className="px-3 py-2 font-mono text-ink-700">{r.tax_id || "—"}</td>
                    <td className="px-3 py-2 text-ink-700">{requesterName}</td>
                    <td className="px-3 py-2 text-center">
                      <Badge color={
                        r.status === "pending" ? "amber" :
                        r.status === "approved" ? "emerald" :
                        r.status === "rejected" ? "rose" : "slate"
                      }>
                        {r.status === "pending" ? "รออนุมัติ" :
                         r.status === "approved" ? "อนุมัติแล้ว" :
                         r.status === "rejected" ? "ปฏิเสธ" : "ยกเลิก"}
                      </Badge>
                    </td>
                    <td className="px-3 py-2 text-right">
                      <Button variant={r.status === "pending" ? "primary" : "ghost"} icon="eye" onClick={()=>setOpenReq(r)}>
                        {r.status === "pending" ? "ตรวจ / อนุมัติ" : "ดู"}
                      </Button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>

      {openReq && (
        <SupplierCreateRequestDrawer request={openReq}
          tenant={tenant} currentUser={currentUser} currentRole={currentRole} users={users}
          onClose={()=>setOpenReq(null)} onChanged={reload}/>
      )}
    </div>
  );
};

// EXPORT
window.SupplierListPage = SupplierListPage;
window.SupplierDetailModal = SupplierDetailModal;
window.SupplierSearchablePicker = SupplierSearchablePicker;
window.SupplierCreateRequestDrawer = SupplierCreateRequestDrawer;
window.MySPApprovalPage = MySPApprovalPage;
