/* portfolio-crm.jsx — CRM v2: workable leads pipeline.
 *
 * v1 was a read-only list. v2 makes each lead a card you can WORK:
 *   • status pipeline  (new → contacted → in-process → offer → closed-won/lost)
 *   • private notes + follow-up date            → PATCH /api/leads (admin)
 *   • recruiter detail (JD · salary · work mode) from the two-step form
 *   • customer purchase panel (product/amount/license) — structure ready now,
 *     filled with real orders when the payments slice ships.
 * Reads/writes ride the same admin token used by Publish.
 */

const { useState: useStateCrm, useEffect: useEffectCrm, useMemo: useMemoCrm } = React;

const CRM_STATUSES = ["new", "contacted", "in-process", "offer", "closed-won", "closed-lost"];

const CrmLeadsEditor = () => {
  const { show } = React.useContext(ToastContext);
  const [items, setItems] = useStateCrm([]);
  const [loading, setLoading] = useStateCrm(false);
  const [err, setErr] = useStateCrm("");
  const [kind, setKind] = useStateCrm("all");
  const [statusFilter, setStatusFilter] = useStateCrm("all");
  const [query, setQuery] = useStateCrm("");
  const [openId, setOpenId] = useStateCrm(null);     // expanded card
  const [draft, setDraft] = useStateCrm({});          // unsaved notes/followUp per open card
  const [saving, setSaving] = useStateCrm(false);

  const token = () => {
    let t = (typeof getAdminToken === "function") ? getAdminToken() : "";
    if (!t) {
      const pw = window.prompt("Enter your admin password to view leads:");
      if (!pw) return "";
      t = pw; setAdminToken(pw);
    }
    return t;
  };

  const fetchLeads = async () => {
    setLoading(true); setErr("");
    try {
      const t = token(); if (!t) { setLoading(false); return; }
      const r = await fetch("/api/leads", { headers: { "x-admin-token": t } });
      if (r.status === 401) { setAdminToken(""); setErr("Wrong password. Click Refresh to try again."); setLoading(false); return; }
      const j = await r.json();
      if (!j.ok) throw new Error(j.error || "fetch-failed");
      setItems(j.items || []);
    } catch (e) { setErr("Could not load leads. Is the live API up?"); }
    finally { setLoading(false); }
  };

  useEffectCrm(() => { fetchLeads(); /* eslint-disable-next-line */ }, []);

  // PATCH one lead's workflow fields and update the local list in place.
  const patchLead = async (id, patch) => {
    setSaving(true);
    try {
      const t = token(); if (!t) return false;
      const r = await fetch("/api/leads", {
        method: "PATCH",
        headers: { "Content-Type": "application/json", "x-admin-token": t },
        body: JSON.stringify({ id, ...patch }),
      });
      if (r.status === 401) { setAdminToken(""); show("Wrong password — refresh and retry"); return false; }
      const j = await r.json();
      if (!j.ok) throw new Error(j.error || "patch-failed");
      setItems(prev => prev.map(it => it.id === id ? { ...it, ...patch, updatedAt: new Date().toISOString() } : it));
      return true;
    } catch (e) { show("Could not save — try again"); return false; }
    finally { setSaving(false); }
  };

  const setStatus = async (id, status) => { if (await patchLead(id, { status })) show("Status → " + status); };
  const saveWork = async (id) => {
    const d = draft[id] || {};
    if (await patchLead(id, { notes: d.notes ?? "", followUp: d.followUp ?? "" })) show("Saved notes & follow-up");
  };

  const filtered = useMemoCrm(() => {
    const q = query.trim().toLowerCase();
    return items.filter(it => {
      if (kind !== "all" && it.kind !== kind) return false;
      if (statusFilter !== "all" && (it.status || "new") !== statusFilter) return false;
      if (!q) return true;
      return [it.name, it.email, it.company, it.role, it.message, it.jd, it.salary, it.workMode, it.notes]
        .filter(Boolean).join(" ").toLowerCase().includes(q);
    });
  }, [items, kind, statusFilter, query]);

  const exportCsv = () => {
    const header = ["at", "kind", "status", "name", "email", "company", "role", "salary", "workMode", "jd", "message", "notes", "followUp", "source"];
    const rows = [header.join(",")].concat(filtered.map(it =>
      header.map(h => JSON.stringify(it[h] || "")).join(",")));
    const blob = new Blob([rows.join("\n")], { type: "text/csv" });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.download = `lb-leads-${new Date().toISOString().slice(0, 10)}.csv`;
    a.click(); setTimeout(() => URL.revokeObjectURL(a.href), 1000);
    show("CSV exported");
  };

  const counts = {
    all: items.length,
    recruiter: items.filter(i => i.kind === "recruiter").length,
    customer: items.filter(i => i.kind === "customer").length,
    general: items.filter(i => i.kind === "general").length,
  };
  // Follow-ups due today or earlier get a visual nudge.
  const today = new Date().toISOString().slice(0, 10);
  const dueCount = items.filter(i => i.followUp && i.followUp <= today && !String(i.status || "").startsWith("closed")).length;

  const toggleOpen = (it) => {
    const next = openId === it.id ? null : it.id;
    setOpenId(next);
    if (next && !(it.id in draft)) setDraft(d => ({ ...d, [it.id]: { notes: it.notes || "", followUp: it.followUp || "" } }));
  };

  return (
    <div className="crm-root">
      <div className="crm-head">
        <div>
          <strong style={{ fontSize: 14 }}>Leads pipeline</strong>
          <span style={{ color: "var(--text-3)", fontSize: 12, marginLeft: 8 }}>
            {counts.all} total · {counts.recruiter} recruiter · {counts.customer} customer
            {dueCount > 0 && <span className="crm-due"> · {dueCount} follow-up{dueCount === 1 ? "" : "s"} due</span>}
          </span>
        </div>
        <div style={{ display: "flex", gap: 6 }}>
          <button className="btn btn-sm" onClick={fetchLeads} disabled={loading}>
            <Icon name="spark" size={11}/> {loading ? "Loading…" : "Refresh"}
          </button>
          <button className="btn btn-sm" onClick={exportCsv} disabled={!filtered.length}>
            <Icon name="download" size={11}/> Export CSV
          </button>
        </div>
      </div>

      <div className="crm-filters">
        {["all", "recruiter", "customer", "general"].map(k => (
          <button key={k} className={"crm-pill" + (kind === k ? " active" : "")} onClick={() => setKind(k)}>
            {k} <span className="ct">{counts[k]}</span>
          </button>
        ))}
        <input className="crm-search" placeholder="Search name · email · company · JD…"
          value={query} onChange={(e) => setQuery(e.target.value)} />
      </div>

      <div className="crm-filters" style={{ marginTop: 2 }}>
        <span className="crm-lbl" style={{ alignSelf: "center" }}>Status:</span>
        {["all"].concat(CRM_STATUSES).map(s => (
          <button key={s} className={"crm-pill crm-pill-status" + (statusFilter === s ? " active" : "")} onClick={() => setStatusFilter(s)}>
            {s}
          </button>
        ))}
      </div>

      {err && <div className="crm-err">{err}</div>}

      {!loading && !err && filtered.length === 0 && (
        <div className="crm-empty">
          <strong>No leads match.</strong>
          <p>Recruiters who fill the form at <code>lakshmanbazarla.com</code> land here automatically. Customer purchases will appear when the store ships.</p>
        </div>
      )}

      <div className="crm-list">
        {filtered.map((it, i) => {
          const st = it.status || "new";
          const isOpen = openId === it.id;
          const d = draft[it.id] || { notes: it.notes || "", followUp: it.followUp || "" };
          const due = it.followUp && it.followUp <= today && !st.startsWith("closed");
          return (
            <div className={"crm-row" + (isOpen ? " open" : "")} key={it.id || i}>
              <div className="crm-row-head" onClick={() => toggleOpen(it)} style={{ cursor: "pointer" }}>
                <span className={"crm-tag crm-tag-" + (it.kind || "general")}>{it.kind || "general"}</span>
                <span className={"crm-status crm-status-" + st}>{st}</span>
                <strong>{it.name || "(no name)"}</strong>
                {it.company && <span className="crm-co">· {it.company}</span>}
                {due && <span className="crm-due">⏰ due</span>}
                <span className="crm-row-meta">{it.at ? new Date(it.at).toLocaleString() : "—"}</span>
              </div>

              <div className="crm-row-body">
                <div><span className="crm-lbl">Email:</span> <a href={`mailto:${it.email}`}>{it.email}</a></div>
                {it.role && <div><span className="crm-lbl">Role:</span> {it.role}</div>}
                {/* Step-2 recruiter detail */}
                {it.salary && <div><span className="crm-lbl">Salary:</span> {it.salary}</div>}
                {it.workMode && <div><span className="crm-lbl">Mode:</span> {it.workMode}</div>}
                {it.jd && (
                  <div className="crm-jd">
                    <span className="crm-lbl">JD:</span>{" "}
                    {/^https?:\/\//.test(it.jd)
                      ? <a href={it.jd} target="_blank" rel="noreferrer">{it.jd.slice(0, 80)}{it.jd.length > 80 ? "…" : ""}</a>
                      : <span>{it.jd.slice(0, 220)}{it.jd.length > 220 ? "…" : ""}</span>}
                  </div>
                )}
                {it.message && <div className="crm-msg">"{it.message}"</div>}

                {/* Customer purchase panel — structure ready, filled by the
                    payments slice. Shows for customer-kind leads only. */}
                {it.kind === "customer" && (
                  <div className="crm-purchase">
                    <div className="crm-purchase-title">Purchase</div>
                    <div><span className="crm-lbl">Application:</span> {it.product || "—"}</div>
                    <div><span className="crm-lbl">Amount:</span> {it.amount || "—"}</div>
                    <div><span className="crm-lbl">License:</span> {it.license || "—"}</div>
                    <div className="crm-source">Orders connect here when the store ships.</div>
                  </div>
                )}

                {it.source && <div className="crm-source"><span className="crm-lbl">Source:</span> {it.source}</div>}
              </div>

              {/* Workflow strip — always visible so status is one click. */}
              <div className="crm-work">
                <div className="crm-work-status">
                  {CRM_STATUSES.map(s => (
                    <button key={s} disabled={saving}
                      className={"crm-chip" + (st === s ? " active" : "")}
                      onClick={() => setStatus(it.id, s)}>{s}</button>
                  ))}
                </div>
                {isOpen && (
                  <div className="crm-work-detail">
                    <label className="crm-lbl">Private notes (only you see this)</label>
                    <textarea rows={3} value={d.notes}
                      placeholder="Call summary, salary discussed, next step…"
                      onChange={(e) => setDraft(prev => ({ ...prev, [it.id]: { ...d, notes: e.target.value } }))} />
                    <div className="crm-work-row">
                      <div>
                        <label className="crm-lbl">Follow-up date</label>
                        <input type="date" value={d.followUp}
                          onChange={(e) => setDraft(prev => ({ ...prev, [it.id]: { ...d, followUp: e.target.value } }))} />
                      </div>
                      <button className="btn btn-sm btn-accent" disabled={saving} onClick={() => saveWork(it.id)}>
                        <Icon name="check" size={11}/> {saving ? "Saving…" : "Save notes & follow-up"}
                      </button>
                    </div>
                  </div>
                )}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

Object.assign(window, { CrmLeadsEditor });
