// Bylt Capital CRM — leads. (Clients live in clients.jsx.)

function PageSearch({ value, onChange, placeholder }) {
  return (
    <div className="search">
      <Icon name="search" size={15} />
      <input type="search" value={value} onChange={e => onChange(e.target.value)} placeholder={placeholder} aria-label={placeholder} />
    </div>
  );
}
const matches = (needle, ...fields) => !needle || fields.some(x => String(x || "").toLowerCase().includes(needle));

// ── Website application details (leads and deals) ──────────────────────────
// The SSN shows masked; "Show" asks the server for it (not for Viewers, and
// logged on a deal). It is hidden again when this closes.
const APP_PRODUCTS = { mca: "Merchant Cash Advance", loc: "Line of Credit", eq: "Equipment Financing", rbf: "Revenue-Based Financing", tl: "Term Loan", sba: "SBA Loan", inv: "Invoice Factoring", unsure: "Not sure" };
const APP_STEPS = ["Contact", "Funding", "Business", "Owner details"];
function ApplicationDetails({ app, reveal, canReveal, hidePrivate }) {
  const [ssn, setSsn] = useState(null);
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");
  if (!app) return null;
  const show = async () => {
    setBusy(true); setErr("");
    try { setSsn(await reveal()); } catch (e) { setErr(e.message); }
    setBusy(false);
  };
  const ein = app.ein && app.ein.length === 9 ? `${app.ein.slice(0, 2)}-${app.ein.slice(2)}` : "";
  const row = (k, v) => v ? <div className="kv" key={k}><dt>{k}</dt><dd>{v}</dd></div> : null;
  return (
    <dl>
      {app.source === "typed" ? null : <div className="kv"><dt>Status</dt><dd>{app.complete ? <Pill status="active" label="Complete" /> : <Pill status="pending" label={`Incomplete · stopped after step ${app.lastStep || 1} of 4 (${APP_STEPS[(app.lastStep || 1) - 1]})`} />}</dd></div>}
      {row("Owner", [app.firstName, app.lastName].filter(Boolean).join(" "))}
      {row("Email", app.email ? <a href={`mailto:${app.email}`}>{app.email}</a> : "")}
      {row("Phone", app.phone ? <a href={`tel:${app.phone}`}>{app.phone}</a> : "")}
      {hidePrivate ? null : row("Date of birth", app.dob)}
      {!hidePrivate && app.ssnLast4 ? (
        <div className="kv"><dt>SSN</dt><dd className="tnum">
          {ssn || `•••-••-${app.ssnLast4}`}{" "}
          {canReveal ? (ssn ? <button type="button" className="link-btn" onClick={() => setSsn(null)}>Hide</button>
            : <button type="button" className="link-btn" disabled={busy} onClick={show}>{busy ? "Loading…" : "Show"}</button>) : null}
          {err ? <span className="err" role="alert"> {err}</span> : null}
        </dd></div>
      ) : null}
      {row("Credit (self-reported)", app.credit)}
      {(() => { const list = (app.products && app.products.length ? app.products : app.product ? [app.product] : []).map(k => APP_PRODUCTS[k]).filter(Boolean); return row(list.length > 1 ? "Products" : "Product", list.join(", ")); })()}
      {row("Amount requested", app.amount ? fmt.money(app.amount) : "")}
      {row("Monthly revenue", app.monthlyRevenue ? fmt.money(app.monthlyRevenue) : "")}
      {row("Use of funds", app.useOfFunds)}
      {row("Business", app.business ? app.business + (app.dba ? ` (DBA ${app.dba})` : "") : "")}
      {row("Industry", app.industry)}
      {hidePrivate ? null : row("EIN", ein)}
      {row("Business start", app.startDate ? `${app.startDate}${app.timeInBusiness ? ` (${app.timeInBusiness})` : ""}` : "")}
      {row("State", app.state)}
      {row("Referral code", app.ref)}
      {app.more && typeof app.more === "object" ? Object.entries(app.more).map(([k, v]) => <div className="kv" key={"more-" + k}><dt>{k}</dt><dd>{String(v)}</dd></div>) : null}
      {app.source === "typed" ? null : row(app.complete ? "Submitted" : "Last saved", fmt.date(app.completedAt || app.updatedAt))}
    </dl>
  );
}
function ApplicationSheet({ lead, user, onClose }) {
  return (
    <Sheet eyebrow="Website application" title={lead.biz || lead.name || "Application"} onClose={onClose}>
      <div className="form-section"><ApplicationDetails app={lead.application} canReveal={!!canOf(user).pii} reveal={() => API.leadSsn(lead.id)} /></div>
    </Sheet>
  );
}

// Typing in an SSN, EIN or date of birth a rep got from the merchant. Stored encrypted the moment it
// is saved; the boxes start empty and only the ones filled in change what is on file.
function EnterPiiSheet({ kind, id, biz, has, onClose, onSaved }) {
  const [v, set] = useForm({ ssn: "", ein: "", dob: "" });
  const save = useSave(onSaved);
  const submit = () => {
    if (!v.ssn.trim() && !v.ein.trim() && !v.dob.trim()) return save.setError("Enter at least one of them.");
    save.run(() => API.putPii(kind, id, { ssn: v.ssn, ein: v.ein, dob: v.dob }));
  };
  const hint = (k, label) => (has && has[k] ? `${label} is on file; leave blank to keep it` : undefined);
  return (
    <Sheet eyebrow={biz || "Private details"} title="Enter private details" onClose={onClose} onSubmit={submit} submitLabel="Save encrypted" busy={save.busy} error={save.error}>
      <div className="form-section">
        <p className="dim" style={{ marginBottom: 12 }}>Saved encrypted on the server. Afterwards the CRM shows the last 4, and "Show" reveals the whole number and records who looked.</p>
        <div className="form-grid">
          <Field label="Social Security number" hint={hint("ssn", "An SSN")}><TextInput value={v.ssn} onChange={x => set("ssn", x)} placeholder="123-45-6789" autoComplete="off" inputMode="numeric" /></Field>
          <Field label="EIN" hint={hint("ein", "An EIN")}><TextInput value={v.ein} onChange={x => set("ein", x)} placeholder="12-3456789" autoComplete="off" inputMode="numeric" /></Field>
          <Field label="Date of birth" hint={hint("dob", "A date of birth")}><TextInput value={v.dob} onChange={x => set("dob", x)} placeholder="MM/DD/YYYY" autoComplete="off" /></Field>
        </div>
      </div>
    </Sheet>
  );
}

// The Private details card (DEC-082). One card, the same on a lead, a deal and a client:
// SSN, EIN and date of birth, last 4 until "Show", "Enter" / "Change" to type them in.
// `summary` = { ssnLast4, einLast4, dob (true when on file), from (where a borrowed value came from) }.
const last4Of = (v) => { const d = String(v || "").replace(/\D/g, ""); return d.length >= 4 ? d.slice(-4) : null; };
const piiSummary = {
  lead: (l) => { const p = l.pii || {}, a = l.application || {}; return { ssnLast4: p.ssnLast4 || a.ssnLast4 || null, einLast4: p.einLast4 || last4Of(a.ein), dob: !!(p.dob || a.dob) }; },
  deal: (d, client) => {
    const a = d.application || {}, c = client || {}, cp = c.pii || {};
    const ssnLast4 = a.ssnLast4 || cp.ssnLast4 || null, einLast4 = last4Of(a.ein) || last4Of(c.ein), dob = !!(a.dob || c.dob);
    const borrowed = (!a.ssnLast4 && cp.ssnLast4) || (!last4Of(a.ein) && last4Of(c.ein)) || (!a.dob && c.dob);
    return { ssnLast4, einLast4, dob, from: borrowed ? "Some of these come from the client file." : "" };
  },
  client: (s) => ({ ...(s || {}), from: s && s.ssnFrom ? `SSN from deal ${s.ssnFrom}.` : "" }),
};
function PrivateDetailsCard({ kind, id, summary, canReveal, onEnter }) {
  const [shown, setShown] = useState(null);
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");
  const s = summary || {};
  const any = !!(s.ssnLast4 || s.einLast4 || s.dob);
  useEffect(() => { setShown(null); setErr(""); }, [id, s.ssnLast4, s.einLast4, s.dob]);    // after a change, what was revealed is hidden again
  const reveal = async () => { setBusy(true); setErr(""); try { setShown(await API.pii(kind, id)); } catch (e) { setErr(e.message); } setBusy(false); };
  const none = <span className="dim">Not on file</span>;
  const val = (has, full, masked) => (!has ? none : shown && full ? full : masked);
  return (
    <div className="card card-flush pii-card">
      <div className="card-head"><span className="label">Private details</span>
        <span style={{ display: "flex", gap: 12 }}>
          {canReveal && any ? (shown ? <button type="button" className="link-btn" onClick={() => setShown(null)}>Hide</button> : <button type="button" className="link-btn" disabled={busy} onClick={reveal}>{busy ? "Loading…" : "Show"}</button>) : null}
          {canReveal && onEnter ? <button type="button" className="link-btn" onClick={onEnter}>{any ? "Change" : "Enter"}</button> : null}
        </span>
      </div>
      <dl>
        <div className="kv"><dt>SSN</dt><dd className="tnum">{val(s.ssnLast4, shown && shown.ssn, `•••-••-${s.ssnLast4}`)}</dd></div>
        <div className="kv"><dt>EIN</dt><dd className="tnum">{val(s.einLast4, shown && shown.ein, `••-•••${s.einLast4}`)}</dd></div>
        <div className="kv"><dt>Date of birth</dt><dd className="tnum">{val(s.dob, shown && shown.dob, "On file")}</dd></div>
      </dl>
      {!any ? <div className="card-body dim" style={{ fontSize: 13 }}>Enter them to have them ready for lender submissions; they are stored encrypted.</div> : null}
      {s.from ? <div className="card-body muted" style={{ fontSize: 12 }}>{s.from}</div> : null}
      {err ? <div className="card-body err" role="alert">{err}</div> : null}
      {shown ? <div className="card-body muted" style={{ fontSize: 12 }}>Looking at these is recorded on the {kind === "client" ? "client's newest deal" : kind}'s log.</div> : null}
    </div>
  );
}

// Leads themselves are in leads.jsx (Round 9).

Object.assign(window, { PageSearch, matches, ApplicationDetails, ApplicationSheet, EnterPiiSheet, PrivateDetailsCard, piiSummary });
