// people.jsx — Manifest CRM workspace

const { useState: useStateM, useEffect: useEffectM, useMemo: useMemoM } = React;

const CRM_TOUCH_KINDS = ["note", "email", "call", "meeting", "message", "intro", "follow-up"];
const CRM_ORG_KINDS = ["client", "partner", "vendor", "funder", "agency", "company", "nonprofit", "other"];
const CRM_STATUSES = ["active", "paused", "archived"];

function crmGmailCompose(email) {
  return `https://mail.google.com/mail/?view=cm&fs=1&to=${encodeURIComponent(email || "")}`;
}

function crmGmailSearch(email) {
  const q = `from:${email || ""} OR to:${email || ""}`;
  return `https://mail.google.com/mail/u/0/#search/${encodeURIComponent(q)}`;
}

function crmMapSearch(location) {
  return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(location || "")}`;
}

function crmTodayPlus(days) {
  const d = new Date();
  d.setDate(d.getDate() + days);
  return d.toISOString().slice(0, 10);
}

function crmFmtDate(value) {
  if (!value) return "";
  const d = new Date(value);
  if (Number.isNaN(d.getTime())) return String(value).slice(0, 10);
  return d.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" });
}

function crmOpen(url) {
  if (url) window.open(url, "_blank", "noopener,noreferrer");
}

function ContactActions({ person, compact }) {
  const email = person?.email || "";
  const phone = person?.phone || "";
  const location = person?.location || "";
  return (
    <div className={"crm-actions" + (compact ? " compact" : "")}>
      <button className="btn tiny" disabled={!email} onClick={() => crmOpen(crmGmailCompose(email))}>Email</button>
      <button className="btn tiny ghost" disabled={!email} onClick={() => crmOpen(crmGmailSearch(email))}>Gmail</button>
      <a className={"btn tiny ghost" + (!phone ? " disabled" : "")} href={phone ? `tel:${phone}` : undefined}>Call</a>
      <button className="btn tiny ghost" disabled={!location} onClick={() => crmOpen(crmMapSearch(location))}>Map</button>
    </div>
  );
}

function PeopleView({ projects }) {
  const [people, setPeople] = useStateM([]);
  const [orgs, setOrgs] = useStateM([]);
  const [q, setQ] = useStateM("");
  const [view, setView] = useStateM("all");
  const [projectFilter, setProjectFilter] = useStateM("");
  const [orgFilter, setOrgFilter] = useStateM("");
  const [selectedKind, setSelectedKind] = useStateM("person");
  const [selectedId, setSelectedId] = useStateM(null);
  const [detail, setDetail] = useStateM(null);
  const [orgDetail, setOrgDetail] = useStateM(null);
  const [showCreatePerson, setShowCreatePerson] = useStateM(false);
  const [showCreateOrg, setShowCreateOrg] = useStateM(false);

  const status = view === "archived" ? "archived" : view === "paused" ? "paused" : "active";

  const loadPeople = () => {
    const params = new URLSearchParams();
    if (q) params.set("q", q);
    if (view === "due") params.set("due", "1");
    if (projectFilter) params.set("project_id", projectFilter);
    if (orgFilter) params.set("org_id", orgFilter);
    if (status) params.set("status", status);
    fetch(`/api/v1/people?${params}`)
      .then(r => r.ok ? r.json() : [])
      .then(setPeople)
      .catch(() => setPeople([]));
  };

  const loadOrgs = () => {
    fetch("/api/v1/organizations")
      .then(r => r.ok ? r.json() : [])
      .then(setOrgs)
      .catch(() => setOrgs([]));
  };

  useEffectM(loadPeople, [q, view, projectFilter, orgFilter]);
  useEffectM(loadOrgs, []);

  useEffectM(() => {
    if (!selectedId) { setDetail(null); setOrgDetail(null); return; }
    if (selectedKind === "organization") {
      fetch(`/api/v1/organizations/${selectedId}`)
        .then(r => r.ok ? r.json() : null)
        .then(setOrgDetail)
        .catch(() => setOrgDetail(null));
      return;
    }
    fetch(`/api/v1/people/${selectedId}`)
      .then(r => r.ok ? r.json() : null)
      .then(setDetail)
      .catch(() => setDetail(null));
  }, [selectedId, selectedKind]);

  const dueCount = people.filter(p => p.next_touch).length;
  const selectedProject = projects.find(p => p.id === projectFilter);

  const refreshSelected = () => {
    loadPeople();
    loadOrgs();
    if (!selectedId) return;
    if (selectedKind === "organization") {
      fetch(`/api/v1/organizations/${selectedId}`).then(r => r.ok ? r.json() : null).then(setOrgDetail);
    } else {
      fetch(`/api/v1/people/${selectedId}`).then(r => r.ok ? r.json() : null).then(setDetail);
    }
  };

  return (
    <div className="crm-shell">
      <aside className="crm-rail">
        <div className="eyebrow">Manifest</div>
        <h2>Relationships</h2>
        <button className={"crm-view-btn" + (view === "all" ? " active" : "")} onClick={() => setView("all")}>
          <span>All active</span><b>{people.length}</b>
        </button>
        <button className={"crm-view-btn" + (view === "due" ? " active" : "")} onClick={() => setView("due")}>
          <span>Follow-ups due</span><b>{dueCount}</b>
        </button>
        <button className={"crm-view-btn" + (view === "paused" ? " active" : "")} onClick={() => setView("paused")}>
          <span>Paused</span>
        </button>
        <button className={"crm-view-btn" + (view === "archived" ? " active" : "")} onClick={() => setView("archived")}>
          <span>Archived</span>
        </button>

        <label className="crm-label">Project</label>
        <select className="crm-input" value={projectFilter} onChange={e => setProjectFilter(e.target.value)}>
          <option value="">All projects</option>
          {projects.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
        </select>

        <label className="crm-label">Organization</label>
        <select className="crm-input" value={orgFilter} onChange={e => setOrgFilter(e.target.value)}>
          <option value="">All organizations</option>
          {orgs.map(o => <option key={o.id} value={o.id}>{o.name}</option>)}
        </select>

        <div className="crm-rail-actions">
          <button className="btn tiny primary" onClick={() => setShowCreatePerson(v => !v)}>New person</button>
          <button className="btn tiny" onClick={() => setShowCreateOrg(v => !v)}>New org</button>
        </div>
      </aside>

      <main className="crm-list-pane">
        <div className="crm-toolbar">
          <div>
            <div className="eyebrow">{selectedProject ? selectedProject.name : "All camps"}</div>
            <h2>People</h2>
          </div>
          <input
            className="crm-search"
            type="search"
            placeholder="Search name, email, title, organization, notes..."
            value={q}
            onChange={e => setQ(e.target.value)}
          />
        </div>

        {showCreatePerson && (
          <PersonForm
            orgs={orgs}
            onCancel={() => setShowCreatePerson(false)}
            onSaved={(p) => { setShowCreatePerson(false); setSelectedKind("person"); setSelectedId(p.id); refreshSelected(); }}
          />
        )}
        {showCreateOrg && (
          <OrganizationForm
            onCancel={() => setShowCreateOrg(false)}
            onSaved={(o) => { setShowCreateOrg(false); setSelectedKind("organization"); setSelectedId(o.id); refreshSelected(); }}
          />
        )}

        <div className="crm-table">
          <div className="crm-table-head">
            <span>Name</span><span>Organization</span><span>Last touch</span><span>Next</span>
          </div>
          {people.map(p => (
            <button
              key={p.id}
              className={"crm-person-row" + (selectedKind === "person" && selectedId === p.id ? " active" : "")}
              onClick={() => { setSelectedKind("person"); setSelectedId(p.id); }}
            >
              <span className="crm-person-main">
                <span className="avatar">{p.initials || p.name.slice(0, 2).toUpperCase()}</span>
                <span><b>{p.name}</b><small>{p.title || p.email || "No role set"}</small></span>
              </span>
              <span>{p.org_name || "Independent"}</span>
              <span>{p.last_interaction ? `${p.last_interaction.kind}: ${crmFmtDate(p.last_interaction.occurred_at)}` : "None"}</span>
              <span>{p.next_touch ? crmFmtDate(p.next_touch) : "Not set"}</span>
            </button>
          ))}
          {people.length === 0 && <div className="crm-empty">No matching people.</div>}
        </div>

        <div className="crm-org-strip">
          <div className="crm-strip-title">Organizations</div>
          {orgs.map(o => (
            <button
              key={o.id}
              className={"crm-org-chip" + (selectedKind === "organization" && selectedId === o.id ? " active" : "")}
              onClick={() => { setSelectedKind("organization"); setSelectedId(o.id); }}
            >
              <span>{o.name}</span><b>{o.people_count || 0}</b>
            </button>
          ))}
        </div>
      </main>

      <section className="crm-detail-pane">
        {selectedKind === "person" && detail && (
          <PersonDossier
            detail={detail}
            orgs={orgs}
            projects={projects}
            onChanged={refreshSelected}
            onDeleted={() => { setSelectedId(null); setDetail(null); refreshSelected(); }}
          />
        )}
        {selectedKind === "organization" && orgDetail && (
          <OrganizationDossier
            org={orgDetail}
            onChanged={refreshSelected}
            onDeleted={() => { setSelectedId(null); setOrgDetail(null); refreshSelected(); }}
          />
        )}
        {!selectedId && (
          <div className="crm-empty lg">
            <div className="ttl">Select a person or organization.</div>
            <div className="sub">Open a dossier to edit contact details, log touchpoints, and manage follow-ups.</div>
          </div>
        )}
      </section>
    </div>
  );
}

function PersonForm({ person, orgs, onSaved, onCancel }) {
  const isEdit = !!person;
  const [draft, setDraft] = useStateM({
    name: person?.name || "",
    title: person?.title || "",
    org_id: person?.org_id || "",
    email: person?.email || "",
    phone: person?.phone || "",
    location: person?.location || "",
    preferred_contact: person?.preferred_contact || "",
    next_touch: person?.next_touch || "",
    status: person?.status || "active",
    context: person?.context || "",
    notes: person?.notes || "",
    tags: (person?.tags || []).join(", "),
    linkedin: person?.links?.linkedin || "",
    website: person?.links?.website || "",
  });
  const [error, setError] = useStateM("");

  const set = (field, value) => setDraft(prev => ({ ...prev, [field]: value }));

  async function submit(e) {
    e.preventDefault();
    setError("");
    const body = {
      name: draft.name.trim(),
      title: draft.title.trim(),
      org_id: draft.org_id || null,
      email: draft.email.trim(),
      phone: draft.phone.trim(),
      location: draft.location.trim(),
      preferred_contact: draft.preferred_contact,
      next_touch: draft.next_touch,
      status: draft.status,
      context: draft.context.trim(),
      notes: draft.notes.trim(),
      tags: draft.tags.split(",").map(t => t.trim()).filter(Boolean),
      links: {
        linkedin: draft.linkedin.trim(),
        website: draft.website.trim(),
      },
    };
    try {
      const r = await fetch(isEdit ? `/api/v1/people/${person.id}` : "/api/v1/people", {
        method: isEdit ? "PATCH" : "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok) throw new Error(data.detail || "Could not save person");
      onSaved(data);
    } catch (err) {
      setError(err.message);
    }
  }

  return (
    <form className="crm-form" onSubmit={submit}>
      <div className="crm-form-grid">
        <label>Name<input className="crm-input" value={draft.name} onChange={e => set("name", e.target.value)} required /></label>
        <label>Title<input className="crm-input" value={draft.title} onChange={e => set("title", e.target.value)} /></label>
        <label>Organization<select className="crm-input" value={draft.org_id || ""} onChange={e => set("org_id", e.target.value)}>
          <option value="">Independent</option>
          {orgs.map(o => <option key={o.id} value={o.id}>{o.name}</option>)}
        </select></label>
        <label>Email<input className="crm-input" type="email" value={draft.email} onChange={e => set("email", e.target.value)} /></label>
        <label>Phone<input className="crm-input" type="tel" value={draft.phone} onChange={e => set("phone", e.target.value)} /></label>
        <label>Location<input className="crm-input" value={draft.location} onChange={e => set("location", e.target.value)} /></label>
        <label>Preferred contact<select className="crm-input" value={draft.preferred_contact} onChange={e => set("preferred_contact", e.target.value)}>
          <option value="">No preference</option><option value="email">Email</option><option value="phone">Phone</option><option value="meeting">Meeting</option>
        </select></label>
        <label>Next touch<input className="crm-input" type="date" value={draft.next_touch} onChange={e => set("next_touch", e.target.value)} /></label>
        <label>Status<select className="crm-input" value={draft.status} onChange={e => set("status", e.target.value)}>
          {CRM_STATUSES.map(s => <option key={s} value={s}>{s}</option>)}
        </select></label>
        <label>Tags<input className="crm-input" value={draft.tags} onChange={e => set("tags", e.target.value)} placeholder="client, reviewer" /></label>
        <label>LinkedIn<input className="crm-input" type="url" value={draft.linkedin} onChange={e => set("linkedin", e.target.value)} /></label>
        <label>Website<input className="crm-input" type="url" value={draft.website} onChange={e => set("website", e.target.value)} /></label>
      </div>
      <label>Relationship context<textarea className="crm-input" rows={3} value={draft.context} onChange={e => set("context", e.target.value)} /></label>
      <label>Private notes<textarea className="crm-input" rows={3} value={draft.notes} onChange={e => set("notes", e.target.value)} /></label>
      {error && <div className="login-error">{error}</div>}
      <div className="crm-form-actions">
        <button className="btn primary tiny" type="submit">{isEdit ? "Save person" : "Create person"}</button>
        <button className="btn tiny" type="button" onClick={onCancel}>Cancel</button>
      </div>
    </form>
  );
}

function OrganizationForm({ org, onSaved, onCancel }) {
  const isEdit = !!org;
  const [draft, setDraft] = useStateM({
    name: org?.name || "",
    kind: org?.kind || "company",
    website: org?.website || "",
    email: org?.email || "",
    phone: org?.phone || "",
    location: org?.location || "",
    tags: (org?.tags || []).join(", "),
    status: org?.status || "active",
    notes: org?.notes || "",
  });
  const [error, setError] = useStateM("");
  const set = (field, value) => setDraft(prev => ({ ...prev, [field]: value }));

  async function submit(e) {
    e.preventDefault();
    setError("");
    const body = {
      ...draft,
      tags: draft.tags.split(",").map(t => t.trim()).filter(Boolean),
    };
    try {
      const r = await fetch(isEdit ? `/api/v1/organizations/${org.id}` : "/api/v1/organizations", {
        method: isEdit ? "PATCH" : "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });
      const data = await r.json().catch(() => ({}));
      if (!r.ok) throw new Error(data.detail || "Could not save organization");
      onSaved(data);
    } catch (err) {
      setError(err.message);
    }
  }

  return (
    <form className="crm-form" onSubmit={submit}>
      <div className="crm-form-grid">
        <label>Name<input className="crm-input" value={draft.name} onChange={e => set("name", e.target.value)} required /></label>
        <label>Type<select className="crm-input" value={draft.kind} onChange={e => set("kind", e.target.value)}>
          {CRM_ORG_KINDS.map(k => <option key={k} value={k}>{k}</option>)}
        </select></label>
        <label>Email<input className="crm-input" type="email" value={draft.email} onChange={e => set("email", e.target.value)} /></label>
        <label>Phone<input className="crm-input" type="tel" value={draft.phone} onChange={e => set("phone", e.target.value)} /></label>
        <label>Website<input className="crm-input" type="url" value={draft.website} onChange={e => set("website", e.target.value)} /></label>
        <label>Location<input className="crm-input" value={draft.location} onChange={e => set("location", e.target.value)} /></label>
        <label>Status<select className="crm-input" value={draft.status} onChange={e => set("status", e.target.value)}>
          {CRM_STATUSES.map(s => <option key={s} value={s}>{s}</option>)}
        </select></label>
        <label>Tags<input className="crm-input" value={draft.tags} onChange={e => set("tags", e.target.value)} /></label>
      </div>
      <label>Notes<textarea className="crm-input" rows={3} value={draft.notes} onChange={e => set("notes", e.target.value)} /></label>
      {error && <div className="login-error">{error}</div>}
      <div className="crm-form-actions">
        <button className="btn primary tiny" type="submit">{isEdit ? "Save organization" : "Create organization"}</button>
        <button className="btn tiny" type="button" onClick={onCancel}>Cancel</button>
      </div>
    </form>
  );
}

function PersonDossier({ detail, orgs, projects, onChanged, onDeleted }) {
  const [editing, setEditing] = useStateM(false);
  const [interactions, setInteractions] = useStateM([]);
  const [kind, setKind] = useStateM("note");
  const [direction, setDirection] = useStateM("");
  const [summary, setSummary] = useStateM("");
  const [body, setBody] = useStateM("");
  const [touchProject, setTouchProject] = useStateM("");
  const [nextTouch, setNextTouch] = useStateM("");

  const loadInteractions = () => {
    fetch(`/api/v1/people/${detail.id}/interactions`)
      .then(r => r.ok ? r.json() : [])
      .then(setInteractions)
      .catch(() => setInteractions([]));
  };
  useEffectM(loadInteractions, [detail.id]);

  async function patchPerson(updates) {
    const r = await fetch(`/api/v1/people/${detail.id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(updates),
    });
    if (r.ok) onChanged();
  }

  async function logTouch(e) {
    e.preventDefault();
    if (!summary.trim()) return;
    const r = await fetch(`/api/v1/people/${detail.id}/interactions`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        kind,
        direction,
        summary: summary.trim(),
        body: body.trim(),
        project_id: touchProject || null,
        org_id: detail.org_id || null,
        next_touch: nextTouch || undefined,
      }),
    });
    if (r.ok) {
      setKind("note"); setDirection(""); setSummary(""); setBody(""); setTouchProject(""); setNextTouch("");
      loadInteractions();
      onChanged();
    }
  }

  async function removePerson() {
    if (!window.confirm(`Remove ${detail.name} from Manifest?`)) return;
    await fetch(`/api/v1/people/${detail.id}`, { method: "DELETE" });
    onDeleted();
  }

  if (editing) {
    return <PersonForm person={detail} orgs={orgs} onCancel={() => setEditing(false)} onSaved={() => { setEditing(false); onChanged(); }} />;
  }

  return (
    <div className="crm-dossier">
      <div className="crm-dossier-head">
        <span className="avatar lg">{detail.initials || detail.name.slice(0, 2).toUpperCase()}</span>
        <div>
          <div className="eyebrow">{detail.org_name || "Independent"}</div>
          <h2>{detail.name}</h2>
          <p>{detail.title || "No title set"}</p>
        </div>
        <span style={{ flex: 1 }} />
        <button className="btn tiny" onClick={() => setEditing(true)}>Edit</button>
        <button className="btn tiny ghost" onClick={removePerson}>Archive/delete</button>
      </div>

      <ContactActions person={detail} />

      <div className="crm-field-grid">
        <Info label="Email" value={detail.email} />
        <Info label="Phone" value={detail.phone} />
        <Info label="Location" value={detail.location} />
        <Info label="Preferred" value={detail.preferred_contact || "Not set"} />
        <Info label="Next touch" value={detail.next_touch ? crmFmtDate(detail.next_touch) : "Not set"} />
        <Info label="Status" value={detail.status} />
      </div>

      {(detail.links?.linkedin || detail.links?.website) && (
        <div className="crm-actions">
          <button className="btn tiny ghost" disabled={!detail.links?.linkedin} onClick={() => crmOpen(detail.links.linkedin)}>LinkedIn</button>
          <button className="btn tiny ghost" disabled={!detail.links?.website} onClick={() => crmOpen(detail.links.website)}>Website</button>
        </div>
      )}

      {detail.context && <section className="crm-section"><h3>Context</h3><p>{detail.context}</p></section>}
      {detail.notes && <section className="crm-section"><h3>Notes</h3><p>{detail.notes}</p></section>}

      <section className="crm-section">
        <h3>Follow-up shortcuts</h3>
        <div className="crm-actions">
          <button className="btn tiny" onClick={() => patchPerson({ next_touch: crmTodayPlus(1) })}>Tomorrow</button>
          <button className="btn tiny" onClick={() => patchPerson({ next_touch: crmTodayPlus(7) })}>Next week</button>
          <button className="btn tiny" onClick={() => patchPerson({ next_touch: crmTodayPlus(30) })}>30 days</button>
          <button className="btn tiny ghost" onClick={() => patchPerson({ next_touch: "" })}>Clear</button>
        </div>
      </section>

      {detail.projects?.length > 0 && (
        <section className="crm-section">
          <h3>Project affiliations</h3>
          <div className="crm-affiliations">
            {detail.projects.map(a => (
              <div className="crm-affiliation" key={a.project_id}>
                <b>{a.project_name || a.project_id}</b>
                <span>{a.role || a.kind}</span>
              </div>
            ))}
          </div>
        </section>
      )}

      <section className="crm-section">
        <h3>Log touchpoint</h3>
        <form className="crm-touch-form" onSubmit={logTouch}>
          <select className="crm-input" value={kind} onChange={e => setKind(e.target.value)}>
            {CRM_TOUCH_KINDS.map(k => <option key={k} value={k}>{k}</option>)}
          </select>
          <select className="crm-input" value={direction} onChange={e => setDirection(e.target.value)}>
            <option value="">Direction</option><option value="inbound">Inbound</option><option value="outbound">Outbound</option><option value="internal">Internal</option>
          </select>
          <select className="crm-input" value={touchProject} onChange={e => setTouchProject(e.target.value)}>
            <option value="">No project</option>
            {projects.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
          </select>
          <input className="crm-input wide" value={summary} onChange={e => setSummary(e.target.value)} placeholder="Summary" required />
          <input className="crm-input" type="date" value={nextTouch} onChange={e => setNextTouch(e.target.value)} title="Next touch" />
          <textarea className="crm-input full" rows={3} value={body} onChange={e => setBody(e.target.value)} placeholder="Details" />
          <button className="btn primary tiny" type="submit">Log touchpoint</button>
        </form>
      </section>

      <section className="crm-section">
        <h3>History</h3>
        <InteractionList interactions={interactions} onChanged={loadInteractions} />
      </section>
    </div>
  );
}

function OrganizationDossier({ org, onChanged, onDeleted }) {
  const [editing, setEditing] = useStateM(false);
  async function removeOrg() {
    if (!window.confirm(`Delete ${org.name}? People will remain in Manifest without an organization.`)) return;
    await fetch(`/api/v1/organizations/${org.id}`, { method: "DELETE" });
    onDeleted();
  }
  if (editing) {
    return <OrganizationForm org={org} onCancel={() => setEditing(false)} onSaved={() => { setEditing(false); onChanged(); }} />;
  }
  return (
    <div className="crm-dossier">
      <div className="crm-dossier-head">
        <div>
          <div className="eyebrow">{org.kind || "organization"}</div>
          <h2>{org.name}</h2>
          <p>{org.location || `${org.people_count || 0} people`}</p>
        </div>
        <span style={{ flex: 1 }} />
        <button className="btn tiny" onClick={() => setEditing(true)}>Edit</button>
        <button className="btn tiny ghost" onClick={removeOrg}>Delete</button>
      </div>
      <div className="crm-actions">
        <button className="btn tiny" disabled={!org.email} onClick={() => crmOpen(crmGmailCompose(org.email))}>Email org</button>
        <a className={"btn tiny ghost" + (!org.phone ? " disabled" : "")} href={org.phone ? `tel:${org.phone}` : undefined}>Call</a>
        <button className="btn tiny ghost" disabled={!org.website} onClick={() => crmOpen(org.website)}>Website</button>
        <button className="btn tiny ghost" disabled={!org.location} onClick={() => crmOpen(crmMapSearch(org.location))}>Map</button>
      </div>
      <div className="crm-field-grid">
        <Info label="Email" value={org.email} />
        <Info label="Phone" value={org.phone} />
        <Info label="Status" value={org.status} />
        <Info label="Tags" value={(org.tags || []).join(", ")} />
      </div>
      {org.notes && <section className="crm-section"><h3>Notes</h3><p>{org.notes}</p></section>}
      <section className="crm-section">
        <h3>People</h3>
        <div className="crm-mini-list">
          {(org.people || []).map(p => (
            <div className="crm-mini-row" key={p.id}>
              <span className="avatar">{p.initials || p.name.slice(0, 2).toUpperCase()}</span>
              <b>{p.name}</b><span>{p.title}</span><span>{p.next_touch ? crmFmtDate(p.next_touch) : ""}</span>
            </div>
          ))}
          {(org.people || []).length === 0 && <div className="crm-empty">No people in this organization yet.</div>}
        </div>
      </section>
      <section className="crm-section">
        <h3>Recent interactions</h3>
        <InteractionList interactions={org.recent_interactions || []} />
      </section>
    </div>
  );
}

function InteractionList({ interactions, onChanged }) {
  async function remove(interactionId) {
    if (!window.confirm("Delete this interaction?")) return;
    await fetch(`/api/v1/interactions/${interactionId}`, { method: "DELETE" });
    if (onChanged) onChanged();
  }
  return (
    <div className="crm-history">
      {interactions.map(i => (
        <div className="crm-history-row" key={i.id}>
          <span className="crm-kind">{i.kind}</span>
          <div>
            <b>{i.summary}</b>
            {i.body && <p>{i.body}</p>}
            <small>{crmFmtDate(i.occurred_at)}{i.direction ? ` · ${i.direction}` : ""}</small>
          </div>
          {i.external_url && <button className="btn tiny ghost" onClick={() => crmOpen(i.external_url)}>Open</button>}
          {onChanged && <button className="remove-btn" onClick={() => remove(i.id)} title="Delete">×</button>}
        </div>
      ))}
      {interactions.length === 0 && <div className="crm-empty">No interactions logged.</div>}
    </div>
  );
}

function crmInfoAction(label, value) {
  if (!value) return null;
  if (label === "Email") return { href: crmGmailCompose(value), text: value };
  if (label === "Phone") return { href: `tel:${value}`, text: value };
  if (label === "Location") return { href: crmMapSearch(value), text: value };
  return null;
}

function Info({ label, value }) {
  const action = crmInfoAction(label, value);
  return (
    <div className="crm-info">
      <span>{label}</span>
      {action ? (
        <a href={action.href} target={action.href.startsWith("http") ? "_blank" : undefined} rel="noreferrer">{action.text}</a>
      ) : (
        <b>{value || "Not set"}</b>
      )}
    </div>
  );
}

Object.assign(window, { PeopleView, ContactActions, crmGmailCompose, crmGmailSearch, crmFmtDate });
