/* global React, PD */
const { useState, useEffect, useMemo } = React;

function ViewerView({ initialEntity, onJsonOpen }) {
  const [entity, setEntity] = useState(initialEntity || 'deals');
  const [until, setUntil] = useState('');
  const [search, setSearch] = useState('');
  const [page, setPage] = useState(1);
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  const ENTITIES = PD_ENTITIES_DEFAULT || [];

  const loadData = async () => {
    setLoading(true); setError('');
    try {
      const res = await PD.getData(entity, { page, limit: 100, until, search });
      setData(res.data || res || []);
    } catch (e) { setError(e.message); setData([]); }
    setLoading(false);
  };

  useEffect(() => { loadData(); }, [entity, page, until, search]);
  useEffect(() => { if (initialEntity) setEntity(initialEntity); }, [initialEntity]);

  const ent = ENTITIES.find(e => e.id === entity) || ENTITIES[0];

  const PER = 50;
  const pages = Math.max(1, Math.ceil(data.length / PER));
  const slice = data.slice((page - 1) * PER, page * PER);

  function extractPrimary(row) {
    const d = row.data || {};
    return d.title || d.name || d.subject || d.key || String(row.pipedrive_id);
  }
  function extractSecondary(row) {
    const d = row.data || {};
    const parts = [];
    if (d.value)    parts.push(`${d.value} ${d.currency || ''}`);
    if (d.email)    parts.push(d.email);
    if (d.org_id?.name) parts.push(d.org_id.name);
    if (d.person_id?.name) parts.push(d.person_id.name);
    if (d.status)   parts.push(d.status);
    return parts.join(' · ') || '—';
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      <div className="card" style={{ padding: 12, display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
        <div style={{ minWidth: 220 }}>
          <Select value={entity} onChange={e => { setEntity(e.target.value); setPage(1); }}
            options={ENTITIES.map(e => ({ value: e.id, label: e.label }))}/>
        </div>
        <div style={{ flex: 1, minWidth: 200 }}>
          <Input icon={<Icon d={I.search} size={13}/>} placeholder="Search records…" value={search}
            onChange={e => { setSearch(e.target.value); setPage(1); }}/>
        </div>
        <div style={{ minWidth: 200 }}>
          <Input icon={<Icon d={I.calendar} size={13}/>} type="datetime-local" value={until}
            onChange={e => setUntil(e.target.value)} title="Point-in-time cutoff"/>
        </div>
        <Button variant="secondary" icon={<Icon d={I.refresh} size={13}/>} onClick={() => loadData()}>Refresh</Button>
      </div>

      <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
        <Badge tone="brand" dot>{ent?.label || entity}</Badge>
        <span style={{ fontSize: 12.5, color: 'var(--s-fg-3)' }}>{data.length} rows loaded</span>
        {loading && <span className="spin-inline" style={{ color: 'var(--s-fg-3)' }}/>}
        {error && <span style={{ fontSize: 12, color: 'var(--s-danger)' }}>Error: {error}</span>}
      </div>

      <div className="card" style={{ overflow: 'hidden' }}>
        <div style={{ overflowX: 'auto', maxHeight: 520 }}>
          <table className="data">
            <thead>
              <tr>
                <th style={{ width: 70 }}>PD ID</th>
                <th style={{ width: 86 }}>Op</th>
                <th>Primary</th>
                <th>Secondary</th>
                <th style={{ width: 160 }}>Synced</th>
                <th style={{ width: 80 }}></th>
              </tr>
            </thead>
            <tbody>
              {slice.map((r, i) => (
                <tr key={i}>
                  <td className="mono" style={{ color: 'var(--s-fg-3)' }}>{r.pipedrive_id}</td>
                  <td><OpBadge op={r.operation}/></td>
                  <td><strong style={{ fontWeight: 500 }}>{extractPrimary(r)}</strong></td>
                  <td style={{ color: 'var(--s-fg-2)' }}>{extractSecondary(r)}</td>
                  <td className="mono" style={{ color: 'var(--s-fg-3)', fontSize: 12 }}>{new Date(r.sync_timestamp).toLocaleTimeString()}</td>
                  <td>
                    <button onClick={() => onJsonOpen({ id: r.pipedrive_id, primary: extractPrimary(r), op: r.operation, rawData: r })}
                      style={{ background: 'transparent', border: 0, color: 'var(--s-link)', cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 12 }}>
                      <Icon d={I.eye} size={12}/> JSON
                    </button>
                  </td>
                </tr>
              ))}
              {!loading && slice.length === 0 && (
                <tr><td colSpan={6} style={{ textAlign: 'center', color: 'var(--s-fg-3)', padding: 32 }}>No records found</td></tr>
              )}
            </tbody>
          </table>
        </div>

        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '10px 14px', borderTop: '1px solid var(--s-border)', background: 'var(--s-bg-2)' }}>
          <span style={{ fontSize: 12, color: 'var(--s-fg-3)' }}>Showing {slice.length} of {data.length} · page {page} of {pages}</span>
          <div style={{ display: 'flex', gap: 6 }}>
            <Button size="sm" variant="ghost" disabled={page <= 1} icon={<Icon d={I.chevLeft} size={12}/>} onClick={() => setPage(p => Math.max(1, p - 1))}>Prev</Button>
            <Button size="sm" variant="ghost" disabled={page >= pages} iconRight={<Icon d={I.chevRight} size={12}/>} onClick={() => setPage(p => Math.min(pages, p + 1))}>Next</Button>
          </div>
        </div>
      </div>
    </div>
  );
}

function OpBadge({ op }) {
  const map = { INITIAL: 'info', INSERT: 'success', UPDATE: 'accent', DELETE: 'danger' };
  return <Badge tone={map[op] || 'neutral'}>{op}</Badge>;
}

function JsonView({ obj }) {
  const json = JSON.stringify(obj, null, 2);
  const colored = useMemo(() => json
    .replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
    .replace(/"([^"]+)":/g, '<span style="color:var(--s-link)">"$1"</span>:')
    .replace(/: (".*?")/g, ': <span style="color:var(--s-success)">$1</span>')
    .replace(/: (-?\d+\.?\d*)/g, ': <span style="color:var(--s-accent)">$1</span>')
    .replace(/: (true|false|null)/g, ': <span style="color:var(--s-warning)">$1</span>')
  , [json]);
  return (
    <div style={{ padding: 18, background: 'var(--s-bg-1)' }}>
      <pre style={{ fontFamily: 'var(--s-font-mono)', fontSize: 12, lineHeight: 1.7, color: 'var(--s-fg-1)', whiteSpace: 'pre-wrap', wordBreak: 'break-all', margin: 0 }}
        dangerouslySetInnerHTML={{ __html: colored }}/>
    </div>
  );
}

window.ViewerView = ViewerView;
window.JsonView = JsonView;
