/* global React, Icon, Modal, Pill, Field, formatBaht, formatDateTH, DB */
const { useState: useStateEx, useMemo: useMemoEx, useEffect: useEffectEx } = React;

const EXP_CATS = [
  "ค่าน้ำ", "ค่าไฟ", "ค่าน้ำ-ไฟส่วนกลาง", "ค่าพนักงาน",
  "ค่าอินเตอร์เน็ต", "ค่าบำรุงรักษา", "ค่าทำความสะอาด", "อื่นๆ",
];
const EXP_METHODS = ["เงินสด", "โอน", "บัตรเครดิต", "เช็ค"];

function compressImage(file) {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onload = (e) => {
      const img = new Image();
      img.onload = () => {
        const maxW = 1200;
        const ratio = Math.min(1, maxW / img.width);
        const canvas = document.createElement("canvas");
        canvas.width = img.width * ratio;
        canvas.height = img.height * ratio;
        canvas.getContext("2d").drawImage(img, 0, 0, canvas.width, canvas.height);
        resolve(canvas.toDataURL("image/jpeg", 0.75));
      };
      img.src = e.target.result;
    };
    reader.readAsDataURL(file);
  });
}

function ExpenseModal({ open, onClose, onSave, initial }) {
  const today = new Date().toISOString().slice(0, 10);
  const blank = { date: today, category: EXP_CATS[0], amount: "", note: "", method: "เงินสด", slip_image: null };
  const [form, setForm] = useStateEx(initial || blank);
  const [saving, setSaving] = useStateEx(false);

  useEffectEx(() => { setForm(initial || blank); }, [open]);

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

  const handleImage = async (e) => {
    const file = e.target.files[0];
    if (!file) return;
    const b64 = await compressImage(file);
    set("slip_image", b64);
  };

  const handleSave = async () => {
    if (!form.amount || !form.date) return;
    setSaving(true);
    try {
      await onSave({ ...form, amount: parseFloat(form.amount) || 0 });
      onClose();
    } finally { setSaving(false); }
  };

  if (!open) return null;
  return (
    <Modal open={open} onClose={onClose} title={initial ? "แก้ไขรายจ่าย" : "บันทึกรายจ่าย"}
      footer={<>
        <button className="btn" onClick={onClose}>ยกเลิก</button>
        <button className="btn primary" onClick={handleSave} disabled={saving || !form.amount}>
          <Icon name="check" size={16}/> {saving ? "กำลังบันทึก..." : "บันทึก"}
        </button>
      </>}>
      <div className="grid" style={{ gap: 14 }}>
        <div className="grid cols-2" style={{ gap: 14 }}>
          <Field label="วันที่">
            <input type="date" className="input" value={form.date} onChange={e => set("date", e.target.value)}/>
          </Field>
          <Field label="หมวดหมู่">
            <select className="select" value={form.category} onChange={e => set("category", e.target.value)}>
              {EXP_CATS.map(c => <option key={c}>{c}</option>)}
            </select>
          </Field>
          <Field label="จำนวนเงิน (บาท)">
            <input type="number" className="input num" placeholder="0" value={form.amount}
              onChange={e => set("amount", e.target.value)}/>
          </Field>
          <Field label="ช่องทางชำระ">
            <select className="select" value={form.method} onChange={e => set("method", e.target.value)}>
              {EXP_METHODS.map(m => <option key={m}>{m}</option>)}
            </select>
          </Field>
        </div>
        <Field label="หมายเหตุ">
          <input className="input" placeholder="รายละเอียดเพิ่มเติม..." value={form.note || ""}
            onChange={e => set("note", e.target.value)}/>
        </Field>
        <Field label="แนบภาพสลิป (ถ้ามี)">
          <input type="file" accept="image/*" id="slip-upload-input" style={{ display: "none" }}
            onChange={handleImage}/>
          <div style={{ display: "flex", gap: 10, alignItems: "flex-start", flexWrap: "wrap" }}>
            <label htmlFor="slip-upload-input" className="btn" style={{ cursor: "pointer" }}>
              <Icon name="camera" size={16}/> เลือกรูปภาพ
            </label>
            {form.slip_image && (
              <div style={{ position: "relative" }}>
                <img src={form.slip_image} alt="slip"
                  style={{ width: 100, height: 80, objectFit: "cover", borderRadius: 8,
                    border: "1px solid var(--line)", cursor: "pointer" }}
                  onClick={() => window.open(form.slip_image)}/>
                <button onClick={() => set("slip_image", null)}
                  style={{ position: "absolute", top: -6, right: -6, background: "var(--danger)",
                    color: "#fff", border: "none", borderRadius: "50%", width: 20, height: 20,
                    cursor: "pointer", fontSize: 12, lineHeight: 1 }}>✕</button>
              </div>
            )}
          </div>
        </Field>
      </div>
    </Modal>
  );
}

function SlipViewer({ src, onClose }) {
  if (!src) return null;
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,0.8)",
      display: "grid", placeItems: "center", zIndex: 9999, cursor: "zoom-out" }}>
      <img src={src} alt="slip" style={{ maxWidth: "90vw", maxHeight: "90vh", borderRadius: 12 }}
        onClick={e => e.stopPropagation()}/>
    </div>
  );
}

function Expenses({ expenses, setExpenses }) {
  const [adding, setAdding] = useStateEx(false);
  const [editing, setEditing] = useStateEx(null);
  const [slipView, setSlipView] = useStateEx(null);
  const [filterMonth, setFilterMonth] = useStateEx(() => new Date().toISOString().slice(0, 7));

  const MONTHS_TH = { "01":"ม.ค","02":"ก.พ","03":"มี.ค","04":"เม.ย","05":"พ.ค","06":"มิ.ย","07":"ก.ค","08":"ส.ค","09":"ก.ย","10":"ต.ค","11":"พ.ย","12":"ธ.ค" };
  const fmtMonth = (ym) => { const [y, m] = ym.split("-"); return `${MONTHS_TH[m] || m}. ${parseInt(y) + 543}`; };

  const months = useMemoEx(() => {
    const s = new Set([new Date().toISOString().slice(0, 7)]);
    expenses.forEach(e => { if (e.date) s.add(e.date.slice(0, 7)); });
    return [...s].sort().reverse();
  }, [expenses]);

  const filtered = useMemoEx(() => {
    if (filterMonth === "all") return expenses;
    return expenses.filter(e => e.date && e.date.startsWith(filterMonth));
  }, [expenses, filterMonth]);

  const total = useMemoEx(() => filtered.reduce((s, e) => s + (e.amount || 0), 0), [filtered]);

  const byCat = useMemoEx(() => {
    const out = {};
    filtered.forEach(e => { out[e.category] = (out[e.category] || 0) + (e.amount || 0); });
    return Object.entries(out).sort((a, b) => b[1] - a[1]);
  }, [filtered]);

  const handleSave = async (form) => {
    if (editing) {
      await DB.updateExpense(editing.id, form);
      setExpenses(prev => prev.map(e => e.id === editing.id ? { ...e, ...form } : e));
      setEditing(null);
    } else {
      const res = await DB.addExpense(form);
      setExpenses(prev => [{ ...form, id: res?.id ?? Date.now() }, ...prev]);
    }
  };

  const handleDelete = (id) => {
    if (!confirm("ลบรายจ่ายนี้?")) return;
    setExpenses(prev => prev.filter(e => e.id !== id));
    DB.deleteExpense(id).catch(console.error);
  };

  return (
    <div className="grid" style={{ gap: 18 }}>
      {/* toolbar */}
      <div className="row" style={{ flexWrap: "wrap", gap: 12 }}>
        <div className="tabs">
          {months.map(m => (
            <button key={m} className={"tab " + (filterMonth === m ? "active" : "")} onClick={() => setFilterMonth(m)}>
              {fmtMonth(m)}
            </button>
          ))}
          <button className={"tab " + (filterMonth === "all" ? "active" : "")} onClick={() => setFilterMonth("all")}>ทั้งหมด</button>
        </div>
        <div className="spacer" style={{ flex: 1 }}/>
        <button className="btn primary" onClick={() => { setEditing(null); setAdding(true); }}>
          <Icon name="plus" size={16}/> บันทึกรายจ่าย
        </button>
      </div>

      {/* summary */}
      <div className="grid cols-2" style={{ gridTemplateColumns: "1fr 1.6fr" }}>
        <div className="card">
          <div className="card-head">
            <h3>สรุปตามหมวดหมู่</h3>
            <div className="spacer"/>
            <Pill tone="warn">รวม {formatBaht(total)}</Pill>
          </div>
          {byCat.length === 0 ? (
            <div style={{ color: "var(--ink-3)", padding: "32px 0", textAlign: "center", fontSize: "0.9rem" }}>
              ยังไม่มีรายจ่าย
            </div>
          ) : (
            <div className="grid" style={{ gap: 12 }}>
              {byCat.map(([cat, amt]) => {
                const pct = total > 0 ? (amt / total) * 100 : 0;
                return (
                  <div key={cat}>
                    <div className="row" style={{ justifyContent: "space-between", marginBottom: 4 }}>
                      <span style={{ fontSize: "0.88rem" }}>{cat}</span>
                      <span className="num" style={{ fontWeight: 600, fontSize: "0.88rem" }}>{formatBaht(amt)}</span>
                    </div>
                    <div style={{ height: 7, background: "var(--surface-2)", borderRadius: 4 }}>
                      <div style={{ height: "100%", width: pct + "%", background: "var(--danger)", borderRadius: 4 }}/>
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>

        <div className="card">
          <div className="card-head">
            <h3>รายการล่าสุด</h3>
            <div className="spacer"/>
            <Pill tone="warn">{filtered.length} รายการ</Pill>
          </div>
          {filtered.length === 0 ? (
            <div style={{ color: "var(--ink-3)", padding: "32px 0", textAlign: "center", fontSize: "0.9rem" }}>
              ยังไม่มีรายจ่าย · กด "บันทึกรายจ่าย" เพื่อเพิ่ม
            </div>
          ) : (
            <div className="table-wrap" style={{ border: "none" }}>
              <table className="table">
                <thead><tr><th>วันที่</th><th>หมวดหมู่</th><th>หมายเหตุ</th><th>ช่องทาง</th><th className="num">จำนวน</th></tr></thead>
                <tbody>
                  {filtered.slice(0, 6).map(e => (
                    <tr key={e.id}>
                      <td className="num">{formatDateTH(e.date)}</td>
                      <td><span style={{ fontSize: "0.83rem", padding: "1px 8px", borderRadius: 20, background: "var(--surface-2)" }}>{e.category}</span></td>
                      <td style={{ color: "var(--ink-3)", fontSize: "0.83rem" }}>{e.note || "—"}</td>
                      <td style={{ color: "var(--ink-3)", fontSize: "0.83rem" }}>{e.method}</td>
                      <td className="num" style={{ fontWeight: 600, color: "var(--danger)" }}>{formatBaht(e.amount)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      </div>

      {/* full table */}
      <div className="card">
        <div className="card-head">
          <h3>รายการจ่ายเงินทั้งหมด</h3>
          <div className="spacer"/>
          <Pill tone="warn">{filtered.length} รายการ</Pill>
          <Pill tone="warn">รวม {formatBaht(total)}</Pill>
        </div>
        {filtered.length === 0 ? (
          <div style={{ color: "var(--ink-3)", padding: "36px 0", textAlign: "center", fontSize: "0.9rem" }}>
            ยังไม่มีรายการจ่ายเงิน · กด "บันทึกรายจ่าย" เพื่อเริ่มต้น
          </div>
        ) : (
          <div className="table-wrap" style={{ border: "none" }}>
            <table className="table">
              <thead><tr><th>วันที่</th><th>หมวดหมู่</th><th>หมายเหตุ</th><th>ช่องทาง</th><th>สลิป</th><th className="num">จำนวน</th><th></th></tr></thead>
              <tbody>
                {filtered.map(e => (
                  <tr key={e.id}>
                    <td className="num">{formatDateTH(e.date)}</td>
                    <td><span style={{ fontSize: "0.88rem", padding: "2px 8px", borderRadius: 20, background: "var(--surface-2)" }}>{e.category}</span></td>
                    <td style={{ color: "var(--ink-3)", fontSize: "0.88rem" }}>{e.note || "—"}</td>
                    <td style={{ color: "var(--ink-3)" }}>{e.method}</td>
                    <td>
                      {e.slip_image
                        ? <img src={e.slip_image} alt="slip"
                            style={{ width: 40, height: 32, objectFit: "cover", borderRadius: 4,
                              cursor: "zoom-in", border: "1px solid var(--line)" }}
                            onClick={() => setSlipView(e.slip_image)}/>
                        : <span style={{ color: "var(--ink-3)", fontSize: "0.8rem" }}>—</span>}
                    </td>
                    <td className="num" style={{ fontWeight: 600, color: "var(--danger)" }}>{formatBaht(e.amount)}</td>
                    <td>
                      <div className="row" style={{ gap: 4, justifyContent: "flex-end" }}>
                        <button className="btn sm ghost" style={{ color: "var(--ok)" }}
                          onClick={() => { setEditing(e); setAdding(true); }}>
                          <Icon name="edit" size={14}/>
                        </button>
                        <button className="btn sm ghost" style={{ color: "var(--danger)" }}
                          onClick={() => handleDelete(e.id)}>
                          <Icon name="trash" size={14}/>
                        </button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>

      <ExpenseModal open={adding} onClose={() => { setAdding(false); setEditing(null); }}
        onSave={handleSave} initial={editing}/>
      <SlipViewer src={slipView} onClose={() => setSlipView(null)}/>
    </div>
  );
}

window.ExpenseModal = ExpenseModal;
window.SlipViewer = SlipViewer;
window.Expenses = Expenses;
