/* global React, Icon, fmt, fmtMoney, fmtDate, useToast */
const { useState, useEffect, useRef } = React;

// ---------- Generic Modal shell ----------
function Modal({ title, icon, onClose, children, foot, size = "" }) {
  useEffect(() => {
    const h = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, [onClose]);
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className={`modal ${size}`} onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          {icon && <div className="ico"><Icon name={icon} size={18} /></div>}
          <h2>{title}</h2>
          <button className="ico-btn" onClick={onClose}><Icon name="x" size={14} /></button>
        </div>
        <div className="modal-body">{children}</div>
        {foot && <div className="modal-foot">{foot}</div>}
      </div>
    </div>
  );
}

// ---------- Delete Confirm (requires typing DELETE) ----------
function DeleteConfirmModal({ title, message, onClose, onConfirm, loading }) {
  const [input, setInput] = useState("");
  const ok = input.trim().toUpperCase() === "DELETE";
  return (
    <Modal title="ยืนยันการลบข้อมูล" icon="trash" onClose={onClose} foot={
      <>
        <button className="btn" onClick={onClose} disabled={loading}>ยกเลิก</button>
        <button
          className="btn"
          style={{ background: ok ? "var(--danger)" : "var(--border)", color: ok ? "#fff" : "var(--text-3)", cursor: ok ? "pointer" : "not-allowed" }}
          disabled={!ok || loading}
          onClick={onConfirm}
        >
          {loading ? <><span className="spinner" /> กำลังลบ...</> : <><Icon name="trash" size={13} /> ลบถาวร</>}
        </button>
      </>
    }>
      <div style={{ background: "#FEF2F2", border: "1px solid #FECACA", borderRadius: 8, padding: 12, marginBottom: 16 }}>
        <div style={{ fontWeight: 600, color: "#B91C1C", marginBottom: 4 }}>⚠️ คำเตือน: การลบนี้ไม่สามารถกู้คืนได้</div>
        <div style={{ fontSize: 13, color: "#7F1D1D" }}>{message || title}</div>
      </div>
      <div className="field">
        <label>พิมพ์ <code style={{ background: "var(--surface-2)", padding: "1px 7px", borderRadius: 3, fontWeight: 700, letterSpacing: 1 }}>DELETE</code> เพื่อยืนยัน</label>
        <input
          className="input"
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="DELETE"
          autoFocus
          style={{ fontFamily: "monospace", letterSpacing: 2, fontSize: 15 }}
        />
      </div>
    </Modal>
  );
}

// ---------- Edit Project ----------
function EditProjectModal({ project, onClose, onSave }) {
  const [form, set] = useState({
    name: project.name || "",
    client: project.client || "",
    start_date: project.start_date || "",
    status: project.status || "active",
  });
  const [loading, setLoading] = useState(false);
  const valid = form.name.trim().length > 0;
  const save = async () => {
    setLoading(true);
    try { await onSave(form); onClose(); } catch(e) { setLoading(false); }
  };
  return (
    <Modal title="แก้ไขโครงการ" icon="building" onClose={onClose} foot={
      <>
        <button className="btn" onClick={onClose} disabled={loading}>ยกเลิก</button>
        <button className="btn primary" disabled={!valid || loading} onClick={save}>
          {loading ? <><span className="spinner" /> กำลังบันทึก...</> : <><Icon name="check" size={13} /> บันทึก</>}
        </button>
      </>
    }>
      <div className="vstack" style={{ gap: 12 }}>
        <div className="field">
          <label>ชื่อโครงการ <span style={{ color: "var(--danger)" }}>*</span></label>
          <input className="input" value={form.name} onChange={(e) => set({ ...form, name: e.target.value })} autoFocus />
        </div>
        <div className="field">
          <label>ลูกค้า / Developer</label>
          <input className="input" value={form.client} onChange={(e) => set({ ...form, client: e.target.value })} />
        </div>
        <div className="field">
          <label>วันที่เริ่มโครงการ</label>
          <input className="input" type="date" value={form.start_date} onChange={(e) => set({ ...form, start_date: e.target.value })} />
        </div>
        <div className="field">
          <label>สถานะ</label>
          <select className="select" value={form.status} onChange={(e) => set({ ...form, status: e.target.value })}>
            <option value="active">กำลังดำเนินการ</option>
            <option value="pending">รอเริ่มงาน</option>
            <option value="completed">เสร็จสิ้น</option>
          </select>
        </div>
      </div>
    </Modal>
  );
}

// ---------- Edit Contract ----------
function EditContractModal({ contract, onClose, onSave }) {
  const [form, set] = useState({
    contract_number: contract.contract_number || "",
    contract_date: contract.contract_date || "",
    description: contract.description || "",
  });
  const [loading, setLoading] = useState(false);
  const valid = form.contract_number && form.contract_date && form.description;
  const save = async () => {
    setLoading(true);
    try { await onSave(form); onClose(); } catch(e) { setLoading(false); }
  };
  return (
    <Modal title="แก้ไขสัญญา" icon="contract" onClose={onClose} foot={
      <>
        <button className="btn" onClick={onClose} disabled={loading}>ยกเลิก</button>
        <button className="btn primary" disabled={!valid || loading} onClick={save}>
          {loading ? <><span className="spinner" /> กำลังบันทึก...</> : <><Icon name="check" size={13} /> บันทึก</>}
        </button>
      </>
    }>
      <div className="vstack" style={{ gap: 12 }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
          <div className="field">
            <label>เลขที่สัญญา *</label>
            <input className="input mono" value={form.contract_number} onChange={(e) => set({ ...form, contract_number: e.target.value })} autoFocus />
          </div>
          <div className="field">
            <label>วันที่สัญญา *</label>
            <input className="input mono" value={form.contract_date} onChange={(e) => set({ ...form, contract_date: e.target.value })} />
          </div>
        </div>
        <div className="field">
          <label>รายละเอียดงาน *</label>
          <input className="input" value={form.description} onChange={(e) => set({ ...form, description: e.target.value })} />
        </div>
      </div>
    </Modal>
  );
}

// ---------- Edit House ----------
function EditHouseModal({ house, onClose, onSave }) {
  const [form, set] = useState({
    house_code: house.house_code || "",
    price: String(house.price || ""),
    notes: house.notes || "",
  });
  const [loading, setLoading] = useState(false);
  const valid = form.house_code && form.price && Number(form.price) > 0;
  const priceChanged = Number(form.price) !== house.price;
  const save = async () => {
    setLoading(true);
    try {
      await onSave({ house_code: form.house_code, price: Number(form.price), notes: form.notes }, house.price);
      onClose();
    } catch(e) { setLoading(false); }
  };
  return (
    <Modal title="แก้ไขบ้าน / ยูนิต" icon="house" onClose={onClose} foot={
      <>
        <button className="btn" onClick={onClose} disabled={loading}>ยกเลิก</button>
        <button className="btn primary" disabled={!valid || loading} onClick={save}>
          {loading ? <><span className="spinner" /> กำลังบันทึก...</> : <><Icon name="check" size={13} /> บันทึก</>}
        </button>
      </>
    }>
      <div className="vstack" style={{ gap: 12 }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
          <div className="field">
            <label>รหัสบ้าน *</label>
            <input className="input mono" value={form.house_code} onChange={(e) => set({ ...form, house_code: e.target.value })} autoFocus />
          </div>
          <div className="field">
            <label>ราคา (บาท) *</label>
            <input className="input num" type="number" value={form.price} onChange={(e) => set({ ...form, price: e.target.value })} />
          </div>
        </div>
        {priceChanged && (
          <div style={{ background: "#FFFBEB", border: "1px solid #FDE68A", borderRadius: 7, padding: "8px 12px", fontSize: 12.5, color: "#92400E" }}>
            ⚠️ การเปลี่ยนราคาจะปรับยอดมูลค่ารวมในสัญญาและโครงการโดยอัตโนมัติ
          </div>
        )}
        <div className="field">
          <label>หมายเหตุ</label>
          <input className="input" value={form.notes} onChange={(e) => set({ ...form, notes: e.target.value })} />
        </div>
      </div>
    </Modal>
  );
}

// ---------- New Contract ----------
function NewContractModal({ onClose, onCreate }) {
  const [form, set] = useState({ contract_number: "", contract_date: "", description: "", file: null });
  const fileRef = useRef();
  const valid = form.contract_number && form.contract_date && form.description;
  return (
    <Modal title="เพิ่มสัญญาใหม่" icon="contract" onClose={onClose} foot={
      <>
        <button className="btn" onClick={onClose}>ยกเลิก</button>
        <button className="btn primary" disabled={!valid} onClick={() => onCreate(form)}><Icon name="check" size={13} /> บันทึก</button>
      </>
    }>
      <div className="vstack" style={{ gap: 12 }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
          <div className="field">
            <label>เลขที่สัญญา *</label>
            <input className="input mono" placeholder="เช่น JS-2568/007" value={form.contract_number} onChange={(e) => set({ ...form, contract_number: e.target.value })} autoFocus />
          </div>
          <div className="field">
            <label>วันที่ (พ.ศ.) *</label>
            <input className="input mono" placeholder="25/03/2569" value={form.contract_date} onChange={(e) => set({ ...form, contract_date: e.target.value })} />
          </div>
        </div>
        <div className="field">
          <label>รายละเอียดงาน *</label>
          <input className="input" placeholder="เช่น งานสถาปัตยกรรม Type A+B" value={form.description} onChange={(e) => set({ ...form, description: e.target.value })} />
        </div>
        <div className="field">
          <label>ไฟล์สัญญา (ถ้ามี)</label>
          <input ref={fileRef} type="file" accept=".pdf,.jpg,.jpeg,.png" style={{ display: "none" }} onChange={(e) => set({ ...form, file: e.target.files[0] || null })} />
          <div className="file-drop" onClick={() => fileRef.current.click()} style={{ cursor: "pointer" }}>
            <div className="ico"><Icon name="upload" size={16} /></div>
            <div style={{ flex: 1 }}>
              <div className="t">{form.file ? form.file.name : "คลิกเพื่ออัปโหลด PDF / รูปภาพ"}</div>
              <div className="s">PDF, JPG, PNG · สูงสุด 10MB</div>
            </div>
            {form.file && (
              <button className="btn sm" type="button" onClick={(e) => { e.stopPropagation(); set({ ...form, file: null }); }}>ลบ</button>
            )}
          </div>
        </div>
      </div>
    </Modal>
  );
}

// ---------- Add House Range ----------
function AddRangeModal({ onClose, onSave }) {
  const [form, set] = useState({ prefix: "A-", pattern: "001-010", price: "775000", note: "" });
  const parsePattern = (pat) => {
    if (!pat) return [];
    const codes = [];
    pat.split(",").forEach((seg) => {
      seg = seg.trim();
      if (seg.includes("-")) {
        const [a, b] = seg.split("-").map((s) => s.trim());
        const len = Math.max(a.length, b.length);
        const start = parseInt(a, 10), end = parseInt(b, 10);
        if (!isNaN(start) && !isNaN(end)) {
          for (let i = start; i <= end; i++) codes.push(String(i).padStart(len, "0"));
        }
      } else codes.push(seg);
    });
    return codes;
  };
  const codes = parsePattern(form.pattern);
  const total = codes.length * (parseFloat(form.price) || 0);

  return (
    <Modal title="เพิ่มบ้านแบบกลุ่ม" icon="house" size="lg" onClose={onClose} foot={
      <>
        <button className="btn" onClick={onClose}>ยกเลิก</button>
        <button className="btn primary" disabled={codes.length === 0 || !form.price} onClick={() => onSave({ count: codes.length, total, codes, form })}>
          <Icon name="plus" size={13} /> เพิ่ม {codes.length} หลัง
        </button>
      </>
    }>
      <div className="vstack" style={{ gap: 14 }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 2fr", gap: 12 }}>
          <div className="field">
            <label>Prefix (คำนำหน้า)</label>
            <input className="input mono" placeholder="A-" value={form.prefix} onChange={(e) => set({ ...form, prefix: e.target.value })} />
          </div>
          <div className="field">
            <label>รหัส/ช่วง (คั่นด้วย , หรือ -)</label>
            <input className="input mono" placeholder="001-010, 015, 020-022" value={form.pattern} onChange={(e) => set({ ...form, pattern: e.target.value })} />
          </div>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 2fr", gap: 12 }}>
          <div className="field">
            <label>ราคาต่อหลัง (บาท) *</label>
            <input className="input num" type="number" value={form.price} onChange={(e) => set({ ...form, price: e.target.value })} />
          </div>
          <div className="field">
            <label>หมายเหตุ (ทั้งกลุ่ม)</label>
            <input className="input" placeholder="เช่น งวดที่ 1 - ฐานราก" value={form.note} onChange={(e) => set({ ...form, note: e.target.value })} />
          </div>
        </div>
        <div style={{ borderTop: "1px solid var(--border)", paddingTop: 12 }}>
          <div className="hstack" style={{ marginBottom: 8 }}>
            <span style={{ fontWeight: 500, fontSize: 13 }}>ตัวอย่างที่จะสร้าง</span>
            <span style={{ flex: 1 }}></span>
            <span className="dim" style={{ fontSize: 12 }}>{codes.length} หลัง · รวม ฿{fmt(total)}</span>
          </div>
          <div style={{ background: "var(--surface-2)", border: "1px solid var(--border)", borderRadius: 8, padding: 10, maxHeight: 140, overflow: "auto" }}>
            {codes.length === 0 ? (
              <div className="dim" style={{ fontSize: 12, textAlign: "center", padding: 8 }}>ใส่รหัสหรือช่วง — เช่น <code>001-010</code></div>
            ) : (
              <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
                {codes.slice(0, 50).map((c) => (
                  <span key={c} className="pill mono" style={{ background: "var(--surface)", fontSize: 11.5 }}>{form.prefix}{c}</span>
                ))}
                {codes.length > 50 && <span className="pill dim" style={{ fontSize: 11.5 }}>+{codes.length - 50} อื่นๆ</span>}
              </div>
            )}
          </div>
        </div>
      </div>
    </Modal>
  );
}

// ---------- Bulk Text ----------
function BulkTextModal({ onClose, onSave }) {
  const [txt, setTxt] = useState("A-001,775000,งวดที่ 1\nA-002,775000,งวดที่ 1\nA-003,775000\nA-004,775000");
  const rows = txt.split("\n").filter((l) => l.trim()).length;
  return (
    <Modal title="เพิ่มบ้านแบบ Text" icon="upload" onClose={onClose} foot={
      <>
        <button className="btn" onClick={onClose}>ยกเลิก</button>
        <button className="btn primary" disabled={rows === 0} onClick={() => {
          const parsed = txt.split('\n').filter(l => l.trim()).map(l => { const [code,price,note] = l.split(','); return { house_code: (code||'').trim(), price: Number(price)||0, notes: (note||'').trim() }; }).filter(r => r.house_code && r.price);
          onSave(parsed);
        }}><Icon name="check" size={13} /> เพิ่ม {rows} หลัง</button>
      </>
    }>
      <div className="dim" style={{ fontSize: 12.5, marginBottom: 8 }}>รูปแบบ: <code style={{ background: "var(--surface-2)", padding: "1px 5px", borderRadius: 3 }}>รหัสบ้าน, ราคา, หมายเหตุ</code> — บรรทัดละหลัง</div>
      <textarea className="input" value={txt} onChange={(e) => setTxt(e.target.value)} rows={10} />
      <div className="dim" style={{ fontSize: 12, marginTop: 8 }}>{rows} บรรทัด พร้อมบันทึก</div>
    </Modal>
  );
}

// ---------- Payment ----------
function PaymentModal({ house, onClose, onSave }) {
  const fileRef = useRef();
  const [form, set] = useState({
    date: new Date().toISOString().split("T")[0],
    inv: "",
    amount: "",
    notes: "",
    file: null,
  });
  const remain = house.price - house.paid_total;
  const amt = parseFloat(form.amount) || 0;
  const over = amt > remain;
  return (
    <Modal title={`บันทึกเบิกจ่าย — บ้าน ${house.house_code}`} icon="wallet" onClose={onClose} foot={
      <>
        <button className="btn" onClick={onClose}>ยกเลิก</button>
        <button className="btn primary" disabled={!amt || amt <= 0 || over} onClick={() => onSave(form)}><Icon name="check" size={13} /> บันทึกการเบิก</button>
      </>
    }>
      <div className="card" style={{ background: "var(--brand-50)", border: "1px solid #BFDBFE", padding: 12, marginBottom: 14 }}>
        <div className="hstack" style={{ gap: 16 }}>
          <div><div style={{ fontSize: 11, color: "var(--brand-700)" }}>ราคาบ้าน</div><div className="num" style={{ fontWeight: 600 }}>฿{fmt(house.price)}</div></div>
          <div><div style={{ fontSize: 11, color: "var(--brand-700)" }}>เบิกแล้ว</div><div className="num" style={{ fontWeight: 600 }}>฿{fmt(house.paid_total)}</div></div>
          <div><div style={{ fontSize: 11, color: "var(--brand-700)" }}>เบิกได้สูงสุด</div><div className="num" style={{ fontWeight: 700, color: "var(--brand-700)", fontSize: 17 }}>฿{fmt(remain)}</div></div>
        </div>
      </div>
      <div className="vstack" style={{ gap: 12 }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
          <div className="field">
            <label>วันที่เบิก *</label>
            <input className="input" type="date" value={form.date} onChange={(e) => set({ ...form, date: e.target.value })} />
          </div>
          <div className="field">
            <label>เลขที่ใบกำกับ</label>
            <input className="input mono" placeholder="INV-69/0123" value={form.inv} onChange={(e) => set({ ...form, inv: e.target.value })} />
          </div>
        </div>
        <div className="field">
          <label>ยอดเงินเบิก (บาท) *</label>
          <input className="input num" type="number" placeholder="0" value={form.amount} onChange={(e) => set({ ...form, amount: e.target.value })} style={{ fontSize: 16 }} autoFocus />
          {over && <div style={{ color: "var(--danger)", fontSize: 12 }}><Icon name="info" size={11} /> ยอดเกินคงเหลือ (สูงสุด ฿{fmt(remain)})</div>}
          <div className="hstack" style={{ gap: 4, marginTop: 4 }}>
            <button className="btn sm" type="button" onClick={() => set({ ...form, amount: String(Math.round(remain * 0.25)) })}>25%</button>
            <button className="btn sm" type="button" onClick={() => set({ ...form, amount: String(Math.round(remain * 0.5)) })}>50%</button>
            <button className="btn sm" type="button" onClick={() => set({ ...form, amount: String(remain) })}>ทั้งหมด ({fmt(remain)})</button>
          </div>
        </div>
        <div className="field">
          <label>หมายเหตุ</label>
          <input className="input" placeholder="เช่น งวดที่ 3 - งานหลังคา 80%" value={form.notes} onChange={(e) => set({ ...form, notes: e.target.value })} />
        </div>
        <div className="field">
          <label>แนบใบเสร็จ / ใบกำกับ</label>
          <input ref={fileRef} type="file" accept=".pdf,.jpg,.jpeg,.png" style={{ display: "none" }} onChange={(e) => set({ ...form, file: e.target.files[0] || null })} />
          <div className="file-drop" onClick={() => fileRef.current.click()} style={{ cursor: "pointer" }}>
            <div className="ico"><Icon name="paperclip" size={14} /></div>
            <div style={{ flex: 1 }}>
              <div className="t">{form.file ? form.file.name : "คลิกเพื่อแนบไฟล์"}</div>
              <div className="s">PDF หรือรูปภาพ</div>
            </div>
            {form.file && <button className="btn sm" type="button" onClick={(e) => { e.stopPropagation(); set({ ...form, file: null }); }}>ลบ</button>}
          </div>
        </div>
      </div>
    </Modal>
  );
}

// ---------- Payment History ----------
function HistoryModal({ house, payments, onClose, onDeletePayment, onLoad }) {
  const [deleting, setDeleting] = useState(null);
  const [loadingDel, setLoadingDel] = useState(false);
  const [loadingPays, setLoadingPays] = useState(true);
  const toast = useToast();

  useEffect(() => {
    if (!onLoad) { setLoadingPays(false); return; }
    setLoadingPays(true);
    Promise.resolve(onLoad()).finally(() => setLoadingPays(false));
  }, []);

  const handleDelete = async () => {
    setLoadingDel(true);
    try {
      await onDeletePayment(deleting.id, deleting.amount, deleting.receipt_path);
      toast({ t: "ลบรายการเบิกสำเร็จ", s: `฿${fmt(deleting.amount)}` });
      setDeleting(null);
    } catch(e) {
      toast({ t: "ลบไม่สำเร็จ", s: e.message });
    }
    setLoadingDel(false);
  };

  const handleExcelExport = () => {
    if (!payments.length) return;
    const rows = payments.map((p, i) => ({
      "ลำดับ": i + 1,
      "วันที่": p.date || "",
      "เลขใบกำกับ": p.inv || "",
      "ยอด (บาท)": p.amount,
      "หมายเหตุ": p.notes || "",
    }));
    window.exportExcel([{ name: `บ้าน ${house.house_code}`, rows }], `ประวัติเบิก_${house.house_code}`);
  };

  return (
    <>
      <Modal title={`ประวัติการเบิก — บ้าน ${house.house_code}`} icon="history" size="xl" onClose={onClose} foot={
        <>
          <button className="btn" onClick={handleExcelExport} disabled={!payments.length}><Icon name="excel" size={13} /> ส่งออก Excel</button>
          <button className="btn primary" onClick={onClose}>ปิด</button>
        </>
      }>
        {loadingPays ? (
          <div style={{ display: "flex", flexDirection: "column", alignItems: "center", padding: 48, gap: 14, color: "var(--text-2)" }}>
            <span className="spinner" style={{ width: 28, height: 28 }}></span>
            <div style={{ fontSize: 13 }}>กำลังโหลดประวัติการเบิก...</div>
          </div>
        ) : payments.length === 0 ? (
          <div className="detail-empty"><div className="ico"><Icon name="wallet" size={32} /></div><div style={{ fontWeight: 500, color: "var(--text-2)" }}>ยังไม่มีรายการเบิก</div></div>
        ) : (
          <div className="tbl-wrap" style={{ border: "1px solid var(--border)", borderRadius: 8 }}>
            <table className="tbl">
              <thead>
                <tr>
                  <th>วันที่</th>
                  <th>เลขใบกำกับ</th>
                  <th className="r">ยอดเงิน</th>
                  <th>หมายเหตุ</th>
                  <th className="c">หลักฐาน</th>
                  <th className="c">จัดการ</th>
                </tr>
              </thead>
              <tbody>
                {payments.map((p) => (
                  <tr key={p.id} style={{ cursor: "default" }}>
                    <td className="mono">{fmtDate(p.date)}</td>
                    <td className="mono">{p.inv || "—"}</td>
                    <td className="r num strong" style={{ color: "var(--success)" }}>฿{fmt(p.amount)}</td>
                    <td>{p.notes || "—"}</td>
                    <td className="c">
                      {p.receipt_url
                        ? <button className="btn sm" onClick={() => window.open(p.receipt_url, "_blank")}><Icon name="eye" size={11} /> ดู</button>
                        : <span className="dim">—</span>}
                    </td>
                    <td className="c">
                      <button className="ico-btn danger" title="ลบรายการนี้" onClick={() => setDeleting(p)}><Icon name="trash" size={13} /></button>
                    </td>
                  </tr>
                ))}
              </tbody>
              <tfoot>
                <tr style={{ background: "var(--surface-2)" }}>
                  <td colSpan={2} className="strong">รวมทั้งสิ้น</td>
                  <td className="r num strong" style={{ fontSize: 14 }}>฿{fmt(payments.reduce((s, p) => s + p.amount, 0))}</td>
                  <td colSpan={3}></td>
                </tr>
              </tfoot>
            </table>
          </div>
        )}
      </Modal>
      {deleting && (
        <DeleteConfirmModal
          title="ลบรายการเบิกจ่าย"
          message={`ลบรายการ ฿${fmt(deleting.amount)} วันที่ ${fmtDate(deleting.date)} — ยอดนี้จะถูกหักออกจากยอดเบิกของบ้านและสัญญา`}
          loading={loadingDel}
          onClose={() => setDeleting(null)}
          onConfirm={handleDelete}
        />
      )}
    </>
  );
}

// ---------- Bulk Payment ----------
function BulkPaymentModal({ data, projectId, onClose, onSave }) {
  const fileRef = useRef();
  const [items, setItems] = useState([]);
  const [meta, setMeta] = useState({ inv: "", date: new Date().toISOString().split("T")[0], file: null });
  const [showPicker, setShowPicker] = useState(false);
  const [loading, setLoading] = useState(false);
  const toast = useToast();

  const total = items.reduce((s, it) => s + (parseFloat(it.amount) || 0), 0);
  const removeItem = (id) => setItems(items.filter((i) => i.id !== id));
  const updateAmount = (id, v) => setItems(items.map((i) => i.id === id ? { ...i, amount: v } : i));

  const save = async () => {
    if (!onSave) return;
    setLoading(true);
    try {
      await onSave(items, meta);
    } catch(e) {
      toast({ t: "บันทึกไม่สำเร็จ", s: e.message });
    }
    setLoading(false);
  };

  return (
    <Modal title="บันทึกเบิกจ่ายหลายรายการ" icon="layers" size="xl" onClose={onClose} foot={
      <>
        <div style={{ flex: 1 }}>
          <span className="dim" style={{ fontSize: 13 }}>ยอดรวม:</span>
          <span className="num" style={{ marginLeft: 8, fontSize: 18, fontWeight: 700, color: "var(--brand-700)" }}>฿{fmt(total)}</span>
        </div>
        <button className="btn" onClick={onClose} disabled={loading}>ยกเลิก</button>
        <button className="btn primary" disabled={items.length === 0 || loading} onClick={save}>
          {loading ? <><span className="spinner" /> กำลังบันทึก...</> : <><Icon name="check" size={13} /> บันทึก {items.length} รายการ</>}
        </button>
      </>
    }>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 2fr", gap: 10, marginBottom: 14 }}>
        <div className="field">
          <label>เลขใบกำกับ (ใบรวม)</label>
          <input className="input mono" placeholder="INV-รวม-001" value={meta.inv} onChange={(e) => setMeta({ ...meta, inv: e.target.value })} />
        </div>
        <div className="field">
          <label>วันที่</label>
          <input className="input" type="date" value={meta.date} onChange={(e) => setMeta({ ...meta, date: e.target.value })} />
        </div>
        <div className="field">
          <label>แนบไฟล์รวม</label>
          <input ref={fileRef} type="file" accept=".pdf,.jpg,.jpeg,.png" style={{ display: "none" }} onChange={(e) => setMeta({ ...meta, file: e.target.files[0] || null })} />
          <div className="file-drop" style={{ padding: 7, cursor: "pointer" }} onClick={() => fileRef.current.click()}>
            <div className="ico" style={{ width: 28, height: 28 }}><Icon name="paperclip" size={12} /></div>
            <div className="t" style={{ flex: 1, fontSize: 12 }}>{meta.file ? meta.file.name : "เลือกไฟล์"}</div>
          </div>
        </div>
      </div>

      <div className="hstack" style={{ marginBottom: 8 }}>
        <span style={{ fontWeight: 500 }}>รายการที่จะเบิก</span>
        <span className="pill">{items.length} หลัง</span>
        <div style={{ flex: 1 }}></div>
        <button className="btn primary sm" onClick={() => setShowPicker(true)}><Icon name="plus" size={12} /> เลือกบ้านที่ค้างจ่าย</button>
      </div>

      <div className="tbl-wrap" style={{ border: "1px solid var(--border)", borderRadius: 8, maxHeight: 320, overflow: "auto" }}>
        <table className="tbl">
          <thead>
            <tr>
              <th>สัญญา</th>
              <th>รหัสบ้าน</th>
              <th className="r">คงเหลือ</th>
              <th className="r" style={{ width: 180 }}>ยอดเบิก</th>
              <th className="c" style={{ width: 50 }}></th>
            </tr>
          </thead>
          <tbody>
            {items.length === 0 ? (
              <tr><td colSpan={5} className="c dim" style={{ padding: 32 }}>ยังไม่ได้เพิ่มบ้าน — คลิก "เลือกบ้านที่ค้างจ่าย"</td></tr>
            ) : items.map((it) => (
              <tr key={it.id} style={{ cursor: "default" }}>
                <td className="mono">{it.contract}</td>
                <td className="mono strong">{it.house_code}</td>
                <td className="r num dim">฿{fmt(it.remain)}</td>
                <td>
                  <input className="input num" type="number" value={it.amount} onChange={(e) => updateAmount(it.id, e.target.value)} style={{ textAlign: "right", padding: "4px 8px" }} />
                </td>
                <td className="c"><button className="ico-btn danger" onClick={() => removeItem(it.id)}><Icon name="x" size={13} /></button></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {showPicker && (
        <BulkHousePicker data={data} projectId={projectId} onClose={() => setShowPicker(false)}
          onAdd={(rows) => { setItems([...items, ...rows.filter(r => !items.find(i => i.id === r.id))]); setShowPicker(false); }} />
      )}
    </Modal>
  );
}

function BulkHousePicker({ data, projectId, onClose, onAdd }) {
  const contracts = data.contracts[projectId] || [];
  const [cid, setCid] = useState(contracts[0]?.id || "");
  const [selected, setSelected] = useState(new Set());
  const [amt, setAmt] = useState("");

  const houses = (data.houses[cid] || []).filter((h) => h.price - h.paid_total > 0);
  const contract = contracts.find((c) => c.id === cid);

  const toggle = (id) => {
    const ns = new Set(selected);
    if (ns.has(id)) ns.delete(id); else ns.add(id);
    setSelected(ns);
  };
  const toggleAll = () => {
    if (selected.size === houses.length) setSelected(new Set());
    else setSelected(new Set(houses.map((h) => h.id)));
  };

  const add = () => {
    const fixedAmt = parseFloat(amt);
    const rows = houses.filter((h) => selected.has(h.id)).map((h) => {
      const remain = h.price - h.paid_total;
      return {
        id: h.id,
        cid,
        contract: contract.contract_number,
        house_code: h.house_code,
        remain,
        amount: !isNaN(fixedAmt) && fixedAmt > 0 ? Math.min(fixedAmt, remain) : remain,
      };
    });
    onAdd(rows);
  };

  return (
    <Modal title="เลือกบ้านที่ค้างจ่าย" icon="house" size="lg" onClose={onClose} foot={
      <>
        <button className="btn" onClick={onClose}>ยกเลิก</button>
        <button className="btn primary" disabled={selected.size === 0} onClick={add}>เพิ่ม {selected.size} รายการ</button>
      </>
    }>
      <div className="field" style={{ marginBottom: 12 }}>
        <label>สัญญา</label>
        <select className="select" value={cid} onChange={(e) => { setCid(e.target.value); setSelected(new Set()); }}>
          {contracts.map((c) => <option key={c.id} value={c.id}>{c.contract_number} — {c.description}</option>)}
        </select>
      </div>
      <div className="hstack" style={{ marginBottom: 8 }}>
        <button className="btn sm" onClick={toggleAll}>{selected.size === houses.length ? "ยกเลิกทั้งหมด" : "เลือกทั้งหมด"}</button>
        <span className="dim" style={{ fontSize: 12, marginLeft: 8 }}>{selected.size} / {houses.length} ที่เลือก</span>
      </div>
      <div className="tbl-wrap" style={{ border: "1px solid var(--border)", borderRadius: 8, maxHeight: 280, overflow: "auto" }}>
        <table className="tbl">
          <thead>
            <tr>
              <th className="c" style={{ width: 40 }}></th>
              <th>รหัสบ้าน</th>
              <th className="r">ราคา</th>
              <th className="r">เบิกแล้ว</th>
              <th className="r">คงเหลือ</th>
            </tr>
          </thead>
          <tbody>
            {houses.map((h) => (
              <tr key={h.id} onClick={() => toggle(h.id)} className={selected.has(h.id) ? "selected" : ""}>
                <td className="c"><input type="checkbox" checked={selected.has(h.id)} onChange={() => toggle(h.id)} onClick={(e) => e.stopPropagation()} /></td>
                <td className="mono strong">{h.house_code}</td>
                <td className="r num dim">{fmt(h.price)}</td>
                <td className="r num dim">{fmt(h.paid_total)}</td>
                <td className="r num strong" style={{ color: "var(--warn)" }}>{fmt(h.price - h.paid_total)}</td>
              </tr>
            ))}
            {houses.length === 0 && (
              <tr><td colSpan={5} className="c dim" style={{ padding: 32 }}>ไม่มีบ้านที่ค้างจ่ายในสัญญานี้</td></tr>
            )}
          </tbody>
        </table>
      </div>
      <div style={{ marginTop: 12, padding: 12, background: "var(--brand-50)", border: "1px solid #BFDBFE", borderRadius: 8 }}>
        <div className="field">
          <label style={{ color: "var(--brand-700)" }}>กำหนดยอดที่จะเบิก (บาท/หลัง)</label>
          <input className="input num" type="number" placeholder="ปล่อยว่างเพื่อเบิกเต็มจำนวนคงเหลือ" value={amt} onChange={(e) => setAmt(e.target.value)} />
        </div>
      </div>
    </Modal>
  );
}

Object.assign(window, {
  Modal, DeleteConfirmModal,
  EditProjectModal, EditContractModal, EditHouseModal,
  NewContractModal, AddRangeModal, BulkTextModal,
  PaymentModal, HistoryModal, BulkPaymentModal,
});
