// components.jsx — shared UI for the agency dashboard.
const { useState, useMemo } = React;

// ---- formatting ------------------------------------------------------------
const fmt = (n) => n.toLocaleString('en-US');

// ---- segmented date filter -------------------------------------------------
function SegmentedFilter({ value, onChange }) {
  return (
    <div className="seg" role="tablist" aria-label="Date range">
      {window.PERIOD_KEYS.map((k) => (
        <button
          key={k}
          role="tab"
          aria-selected={value === k}
          className={'seg-btn' + (value === k ? ' is-active' : '')}
          onClick={() => onChange(k)}
        >
          {window.PERIODS[k].label}
        </button>
      ))}
    </div>
  );
}

// ---- trend badge -----------------------------------------------------------
// `invert` = true means "up is bad" (e.g. contracts lost): an increase is red.
function TrendBadge({ cur, prev, invert = false }) {
  const t = window.trend(cur, prev);
  if (t.dir === 0) {
    return <span className="trend trend-flat">— 0%</span>;
  }
  const favorable = invert ? t.dir < 0 : t.dir > 0;
  const arrow = t.dir > 0 ? '▲' : '▼';
  return (
    <span className={'trend ' + (favorable ? 'trend-pos' : 'trend-neg')}>
      {arrow} {t.pct.toFixed(1)}%
    </span>
  );
}

// ---- metric card -----------------------------------------------------------
// tone ∈ 'accent' | 'pos' | 'pend' | 'neg' — drives the accent rail/number hue
// when semantic color is enabled.
function MetricCard({ label, value, prev, tone = 'accent', invert = false, semantic }) {
  const toneClass = semantic ? ` tone-${tone}` : '';
  return (
    <div className={'metric-card' + toneClass}>
      <div className="metric-rail" />
      <div className="metric-label">{label}</div>
      <div className="metric-value">{fmt(value)}</div>
      <div className="metric-foot">
        <TrendBadge cur={value} prev={prev} invert={invert} />
        <span className="metric-vs">vs prior period</span>
      </div>
    </div>
  );
}

function MetricRow({ m, semantic }) {
  return (
    <div className="metric-grid">
      <MetricCard label="Total Leads"        value={m.leads_generated}   prev={m.prev.leads_generated}   tone="accent" semantic={semantic} />
      <MetricCard label="Total Cases Signed" value={m.cases_signed}      prev={m.prev.cases_signed}      tone="pos"    semantic={semantic} />
      <MetricCard label="Contracts Pending"  value={m.contracts_pending} prev={m.prev.contracts_pending} tone="pend"   semantic={semantic} />
      <MetricCard label="Contracts Lost"     value={m.contracts_lost}    prev={m.prev.contracts_lost}    tone="neg" invert semantic={semantic} />
    </div>
  );
}

// ---- CRM badge -------------------------------------------------------------
function CrmBadge({ type }) {
  if (!type) return null;
  return <span className="crm-badge">{type}</span>;
}

// ---- sortable + searchable client table ------------------------------------
const COLS = [
  { key: 'name',              label: 'Client Name',       align: 'left',  num: false },
  { key: 'calls',             label: 'Calls',             align: 'center', num: true },
  { key: 'form_fills',        label: 'Form Fills',        align: 'center', num: true },
  { key: 'chats',             label: 'Chats',             align: 'center', num: true },
  { key: 'leads_generated',   label: 'Total Leads',       align: 'center', num: true, strong: true },
  { key: 'cases_signed',      label: 'Cases Signed',      align: 'center', num: true },
  { key: 'contracts_pending', label: 'Contracts Pending', align: 'center', num: true },
  { key: 'contracts_lost',    label: 'Contracts Lost',    align: 'center', num: true },
];

function ClientTable({ rows, onOpen }) {
  const [sort, setSort] = useState({ key: 'leads_generated', dir: 'desc' });
  const [query, setQuery] = useState('');

  const clickSort = (key) => {
    setSort((s) =>
      s.key === key
        ? { key, dir: s.dir === 'asc' ? 'desc' : 'asc' }
        : { key, dir: key === 'name' ? 'asc' : 'desc' }
    );
  };

  const view = useMemo(() => {
    const q = query.trim().toLowerCase();
    let r = rows.filter((row) =>
      !q ||
      row.client.name.toLowerCase().includes(q) ||
      row.client.crm_type.toLowerCase().includes(q) ||
      row.client.region.toLowerCase().includes(q)
    );
    const get = (row) => (sort.key === 'name' ? row.client.name.toLowerCase() : row[sort.key]);
    r = [...r].sort((a, b) => {
      const av = get(a), bv = get(b);
      if (av < bv) return sort.dir === 'asc' ? -1 : 1;
      if (av > bv) return sort.dir === 'asc' ? 1 : -1;
      return 0;
    });
    return r;
  }, [rows, sort, query]);

  return (
    <div className="panel">
      <div className="panel-head">
        <div className="panel-titles">
          <h2 className="panel-title">All Clients</h2>
          <span className="panel-count">{view.length} of {rows.length}</span>
        </div>
        <label className="search">
          <svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true">
            <circle cx="7" cy="7" r="4.5" fill="none" stroke="currentColor" strokeWidth="1.4" />
            <line x1="10.5" y1="10.5" x2="14" y2="14" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" />
          </svg>
          <input
            type="text"
            placeholder="Search clients…"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
          />
          {query && (
            <button className="search-clear" onClick={() => setQuery('')} aria-label="Clear search">×</button>
          )}
        </label>
      </div>

      <div className="table-scroll">
        <table className="ctable">
          <thead>
            <tr>
              {COLS.map((col) => (
                <th
                  key={col.key}
                  className={'th-' + col.align + (col.strong ? ' th-strong' : '') + (sort.key === col.key ? ' th-sorted' : '')}
                  onClick={() => clickSort(col.key)}
                >
                  <span className="th-inner">
                    {col.label}
                    <span className="th-caret">{sort.key === col.key ? (sort.dir === 'asc' ? '↑' : '↓') : ''}</span>
                  </span>
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {view.map((row) => (
              <tr key={row.client.id} className="crow" onClick={() => onOpen(row.client.id)} tabIndex={0}
                  onKeyDown={(e) => { if (e.key === 'Enter') onOpen(row.client.id); }}>
                <td className="td-name">
                  <span className="cname">{row.client.name}</span>
                </td>
                <td className="num"><span className="nv">{fmt(row.calls)}</span></td>
                <td className="num"><span className="nv">{fmt(row.form_fills)}</span></td>
                <td className="num"><span className="nv">{fmt(row.chats)}</span></td>
                <td className="num num-strong"><span className="nv">{fmt(row.leads_generated)}</span></td>
                <td className="num"><span className="nv">{fmt(row.cases_signed)}</span></td>
                <td className="num"><span className="nv">{fmt(row.contracts_pending)}</span></td>
                <td className="num"><span className="nv">{fmt(row.contracts_lost)}</span></td>
              </tr>
            ))}
            {view.length === 0 && (
              <tr><td colSpan={COLS.length} className="empty">No clients match “{query}”.</td></tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// ---- source breakdown card (client view) -----------------------------------
function SourceCard({ label, value, total, prev, hint }) {
  const pct = total > 0 ? Math.round((value / total) * 100) : 0;
  return (
    <div className="source-card">
      <div className="source-top">
        <span className="source-label">{label}</span>
        <TrendBadge cur={value} prev={prev} />
      </div>
      <div className="source-value">{fmt(value)}</div>
      <div className="source-bar"><span style={{ width: pct + '%' }} /></div>
      <div className="source-foot"><span className="source-pct">{pct}%</span><span className="source-hint">{hint}</span></div>
    </div>
  );
}

Object.assign(window, {
  fmt, SegmentedFilter, TrendBadge, MetricCard, MetricRow,
  CrmBadge, ClientTable, SourceCard,
});
