/* global React, Icon, Chip, Button, Avatar, Pagination, api */

const LIMIT = 20;

const PAYMENT_STATUS = {
  paid:     { label: "Paid",     kind: "success" },
  pending:  { label: "Pending",  kind: "warning" },
  overdue:  { label: "Overdue",  kind: "danger"  },
  refunded: { label: "Refunded", kind: "default" },
};

const METHOD_LABEL = {
  stripe:        "Stripe",
  bank_transfer: "Bank transfer",
  cash:          "Cash",
  cheque:        "Cheque",
};

function fmtAED(n, currency) {
  if (!n) return (currency || "AED") + " 0";
  return (currency || "AED") + " " + Number(n).toLocaleString("en-AE");
}

/* ── New invoice modal ─────────────────────────────── */
function NewInvoiceModal({ onClose, onCreated }) {
  const [engagements, setEngagements] = React.useState([]);
  const [form, setForm]   = React.useState({ engagementId: "", amount: "", method: "bank_transfer", dueDate: "", notes: "" });
  const [saving, setSaving] = React.useState(false);
  const [error, setError]   = React.useState("");

  React.useEffect(() => {
    api.get("/engagements?status=in_progress&limit=100")
      .then(res => setEngagements(res.data || []))
      .catch(() => {});
  }, []);

  const set = key => ev => setForm(f => ({ ...f, [key]: ev.target.value }));

  async function handleSubmit(ev) {
    ev.preventDefault();
    if (!form.engagementId) { setError("Select an engagement."); return; }
    if (!form.amount || isNaN(Number(form.amount)) || Number(form.amount) <= 0) { setError("Enter a valid amount."); return; }
    setSaving(true); setError("");
    try {
      const eng = engagements.find(e => e._id === form.engagementId);
      await api.post("/payments", {
        engagement: form.engagementId,
        customer:   eng ? (eng.customer._id || eng.customer) : undefined,
        amount:     Number(form.amount),
        method:     form.method,
        dueDate:    form.dueDate || undefined,
        notes:      form.notes,
      });
      onCreated();
      onClose();
    } catch (err) {
      setError(err.message || "Failed to create invoice.");
    } finally { setSaving(false); }
  }

  function engLabel(e) {
    const c = e.customer;
    const cName = c ? (c.type === "organisation" ? c.companyName : [c.firstName, c.lastName].filter(Boolean).join(" ")) : "—";
    const sName = e.service ? e.service.name : "—";
    return cName + " · " + sName;
  }

  return (
    <>
      <div className="scrim" onClick={onClose} />
      <div className="modal" role="dialog" aria-modal="true">
        <div className="modal-head">
          <div>
            <div className="eyebrow" style={{ marginBottom: 4 }}>Finance</div>
            <h2 style={{ margin: 0, fontSize: 18, fontWeight: 600 }}>New invoice</h2>
          </div>
          <button className="icon-btn" onClick={onClose}><Icon name="x" size={18} /></button>
        </div>
        <form onSubmit={handleSubmit} className="modal-body">
          {error && (
            <div style={{ background: "var(--danger-50)", color: "var(--danger-700)", border: "1px solid var(--danger-200)", borderRadius: 6, padding: "8px 12px", fontSize: 13 }}>
              {error}
            </div>
          )}
          <div className="field">
            <label>Engagement</label>
            <select value={form.engagementId} onChange={set("engagementId")} autoFocus>
              <option value="">Select active engagement…</option>
              {engagements.map(e => (
                <option key={e._id} value={e._id}>{engLabel(e)}</option>
              ))}
            </select>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            <div className="field">
              <label>Amount (AED)</label>
              <input type="number" min="1" placeholder="e.g. 4500" value={form.amount} onChange={set("amount")} />
            </div>
            <div className="field">
              <label>Payment method</label>
              <select value={form.method} onChange={set("method")}>
                <option value="bank_transfer">Bank transfer</option>
                <option value="stripe">Stripe</option>
                <option value="cash">Cash</option>
                <option value="cheque">Cheque</option>
              </select>
            </div>
          </div>
          <div className="field">
            <label>Due date</label>
            <input type="date" value={form.dueDate} onChange={set("dueDate")} />
          </div>
          <div className="field">
            <label>Notes</label>
            <textarea rows={2} placeholder="Payment notes…" value={form.notes} onChange={set("notes")} style={{ resize: "vertical" }} />
          </div>
          <div className="modal-footer">
            <Button variant="secondary" type="button" onClick={onClose}>Cancel</Button>
            <Button type="submit" icon="file-plus" disabled={saving}>{saving ? "Creating…" : "Create invoice"}</Button>
          </div>
        </form>
      </div>
    </>
  );
}

/* ── Main page ─────────────────────────────────────── */
function PaymentsPage() {
  const [payments,     setPayments]     = React.useState([]);
  const [stats,        setStats]        = React.useState({ total: 0, paid: 0, pending: 0, overdue: 0, refunded: 0 });
  const [loading,      setLoading]      = React.useState(true);
  const [searchInput,  setSearchInput]  = React.useState("");
  const [search,       setSearch]       = React.useState("");
  const [statusFilter, setStatus]       = React.useState("all");
  const [page,         setPage]         = React.useState(1);
  const [pages,        setPages]        = React.useState(1);
  const [total,        setTotal]        = React.useState(0);
  const [counts,       setCounts]       = React.useState({ paid: 0, pending: 0, overdue: 0, refunded: 0 });
  const [updatingId,   setUpdatingId]   = React.useState(null);
  const [showModal,    setShowModal]    = React.useState(false);
  const [refreshKey,   setRefreshKey]   = React.useState(0);
  const [isSuperAdmin, setIsSuperAdmin] = React.useState(null);

  /* Debounce search — 400 ms */
  React.useEffect(() => {
    const t = setTimeout(() => { setSearch(searchInput); setPage(1); }, 400);
    return () => clearTimeout(t);
  }, [searchInput]);

  /* Fetch stats (global totals — always unfiltered) */
  React.useEffect(() => {
    api.get("/payments/stats/summary")
      .then(res => setStats(res.data || { total: 0, paid: 0, pending: 0, overdue: 0, refunded: 0 }))
      .catch(() => {});
  }, [refreshKey]);

  /* Fetch page */
  React.useEffect(() => {
    setLoading(true);
    const params = new URLSearchParams({ page, limit: LIMIT });
    if (statusFilter !== "all") params.set("status", statusFilter);
    if (search)                 params.set("q",      search);
    api.get("/payments?" + params.toString())
      .then(res => {
        setPayments((res.data || []).map(api.map.payment));
        setTotal(res.total  || 0);
        setPages(res.pages  || 1);
        if (res.counts) setCounts(res.counts);
        if (res.isSuperAdmin !== undefined) setIsSuperAdmin(res.isSuperAdmin);
      })
      .catch(() => {})
      .finally(() => setLoading(false));
  }, [statusFilter, search, page, refreshKey]);

  function handleStatusChange(val) { setStatus(val); setPage(1); }

  async function markPaid(payment) {
    setUpdatingId(payment._id);
    try {
      await api.put("/payments/" + payment._id, { status: "paid", paidAt: new Date().toISOString() });
      /* optimistic: update this payment in the current page */
      setPayments(prev => prev.map(p =>
        p._id === payment._id ? { ...p, status: "paid", outstanding: 0, date: new Date().toLocaleDateString("en-AE", { day: "2-digit", month: "short", year: "numeric" }) } : p
      ));
      setCounts(prev => ({
        ...prev,
        [payment.status]: Math.max(0, (prev[payment.status] || 0) - 1),
        paid: (prev.paid || 0) + 1,
      }));
      /* refresh stats KPIs */
      setRefreshKey(k => k + 1);
    } catch (_) {}
    finally { setUpdatingId(null); }
  }

  const outstanding = stats.pending + stats.overdue;
  const countUnpaid = counts.pending + counts.overdue;

  const STATUS_TABS = [
    { val: "all",      label: "All"      },
    { val: "pending",  label: "Pending"  },
    { val: "overdue",  label: "Overdue"  },
    { val: "paid",     label: "Paid"     },
    { val: "refunded", label: "Refunded" },
  ];

  return (
    <div className="page">
      {showModal && (
        <NewInvoiceModal
          onClose={() => setShowModal(false)}
          onCreated={() => setRefreshKey(k => k + 1)}
        />
      )}

      <div className="page-head">
        <div>
          <div className="eyebrow">Finance</div>
          <h1 className="page-title">Payments</h1>
          <div className="page-sub">
            {isSuperAdmin === false
              ? "Showing payments for engagements assigned to you."
              : "All invoices and payment records across active engagements."}
          </div>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <Button variant="secondary" icon="download">Export</Button>
          <Button icon="file-plus" onClick={() => setShowModal(true)}>New invoice</Button>
        </div>
      </div>

      {/* KPI strip */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 14, marginBottom: 22 }}>
        {[
          { label: "Total invoiced",  value: fmtAED(stats.total),  color: "var(--fg-1)",          bg: "#fff" },
          { label: "Collected",       value: fmtAED(stats.paid),   color: "var(--success-700)",    bg: "var(--success-50)" },
          { label: "Outstanding",     value: fmtAED(outstanding),  color: outstanding > 0 ? "var(--warning-700)" : "var(--fg-1)", bg: outstanding > 0 ? "var(--warning-50)" : "#fff" },
          { label: "Unpaid invoices", value: String(countUnpaid),  color: countUnpaid > 0 ? "var(--danger-700)" : "var(--fg-1)",  bg: countUnpaid > 0  ? "var(--danger-50)"  : "#fff" },
        ].map((k, i) => (
          <div key={i} className="kpi" style={{ background: k.bg }}>
            <div className="lbl">{k.label}</div>
            <div className="val" style={{ fontSize: 24, color: k.color }}>{k.value}</div>
          </div>
        ))}
      </div>

      {/* Filters */}
      <div style={{ display: "flex", gap: 10, marginBottom: 16, alignItems: "center", flexWrap: "wrap" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8, background: "#fff", border: "1px solid var(--border-subtle)", borderRadius: 6, padding: "7px 12px", flex: 1, maxWidth: 360 }}>
          <Icon name="search" size={15} />
          <input
            placeholder="Search by customer, invoice no, notes…"
            value={searchInput}
            onChange={e => setSearchInput(e.target.value)}
            style={{ border: 0, outline: "none", fontFamily: "inherit", fontSize: 13.5, flex: 1, background: "transparent", color: "var(--fg-1)" }}
          />
          {searchInput && (
            <button onClick={() => { setSearchInput(""); setSearch(""); setPage(1); }}
              style={{ border: 0, background: "transparent", cursor: "pointer", color: "var(--fg-3)", padding: 0, display: "flex" }}>
              <Icon name="x" size={14} />
            </button>
          )}
        </div>

        <div style={{ display: "flex", gap: 4, flexWrap: "wrap" }}>
          {STATUS_TABS.map(({ val, label }) => (
            <button key={val} onClick={() => handleStatusChange(val)} style={{
              padding: "7px 13px", borderRadius: 6, border: "1px solid", cursor: "pointer",
              fontSize: 13, fontFamily: "inherit", fontWeight: 500,
              background:  statusFilter === val ? "var(--brand-burgundy)" : "#fff",
              color:       statusFilter === val ? "#fff" : "var(--fg-2)",
              borderColor: statusFilter === val ? "var(--brand-burgundy)" : "var(--border-strong)",
            }}>
              {label}
              {val !== "all" && counts[val] > 0 && (
                <span style={{ marginLeft: 5, opacity: 0.8, fontSize: 11.5 }}>{counts[val]}</span>
              )}
            </button>
          ))}
        </div>
      </div>

      <div className="card" style={{ padding: 0 }}>
        <table className="tbl">
          <thead>
            <tr>
              <th>Invoice</th>
              <th>Customer</th>
              <th>Service</th>
              <th style={{ textAlign: "right" }}>Amount</th>
              <th style={{ textAlign: "right" }}>Outstanding</th>
              <th>Method</th>
              <th>Due</th>
              <th>Paid on</th>
              <th>Status</th>
              <th style={{ textAlign: "right" }}>Actions</th>
            </tr>
          </thead>
          <tbody>
            {loading ? (
              <tr><td colSpan="10" style={{ textAlign: "center", padding: "56px 0", color: "var(--fg-3)" }}>Loading…</td></tr>
            ) : payments.length === 0 ? (
              <tr><td colSpan="10" style={{ textAlign: "center", padding: "56px 0", color: "var(--fg-3)" }}>
                {search ? "No payments match your search." : "No payments found."}
              </td></tr>
            ) : payments.map(p => {
              const sm   = PAYMENT_STATUS[p.status] || PAYMENT_STATUS.pending;
              const busy = updatingId === p._id;
              const canPay = p.status === "pending" || p.status === "overdue";
              return (
                <tr key={p._id || p.id}>
                  <td className="cell-mono" style={{ fontSize: 12 }}>{p.id}</td>
                  <td>
                    <div className="av-row">
                      <Avatar name={p.customer} />
                      <span style={{ fontSize: 13.5 }}>{p.customer}</span>
                    </div>
                  </td>
                  <td style={{ fontSize: 13, color: "var(--fg-2)", maxWidth: 200, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{p.service}</td>
                  <td className="cell-mono" style={{ textAlign: "right", fontSize: 13 }}>{fmtAED(p.amount, p.currency)}</td>
                  <td className="cell-mono" style={{ textAlign: "right", fontSize: 13,
                    color: p.outstanding > 0 ? "var(--warning-700)" : "var(--fg-4)",
                    fontWeight: p.outstanding > 0 ? 600 : 400 }}>
                    {p.outstanding > 0 ? fmtAED(p.outstanding, p.currency) : "—"}
                  </td>
                  <td style={{ fontSize: 13, color: "var(--fg-2)" }}>{METHOD_LABEL[p.method] || p.method}</td>
                  <td className="cell-mono cell-muted" style={{ fontSize: 12 }}>{p.dueDate}</td>
                  <td className="cell-mono cell-muted" style={{ fontSize: 12 }}>{p.date || "—"}</td>
                  <td><Chip kind={sm.kind}>{sm.label}</Chip></td>
                  <td style={{ textAlign: "right", whiteSpace: "nowrap" }}>
                    {canPay ? (
                      <button className="btn btn-ghost btn-sm" onClick={() => markPaid(p)} disabled={busy}>
                        <Icon name={busy ? "loader" : "check-circle"} size={13} />
                        {busy ? "Saving…" : "Mark paid"}
                      </button>
                    ) : (
                      <span style={{ fontSize: 12, color: "var(--fg-4)" }}>—</span>
                    )}
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>

        <Pagination page={page} pages={pages} total={total} limit={LIMIT} onPage={setPage} />
      </div>
    </div>
  );
}

Object.assign(window, { PaymentsPage });
