/* Indexes — list, create modal, detail with search */

function IndexesList({ onOpenIndex, onCreate, indexes }) {
  const [filter, setFilter] = React.useState('all');
  const [query, setQuery] = React.useState('');

  const filtered = indexes.filter(idx => {
    if (filter !== 'all' && idx.status !== filter) return false;
    if (query && !idx.name.toLowerCase().includes(query.toLowerCase())) return false;
    return true;
  });

  return (
    <div className="page-content">
      <div className="page-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', flexWrap: 'wrap', gap: 16 }}>
        <div>
          <h1 className="page-title">Indexes</h1>
          <p className="page-subtitle">Searchable collections built from your video data.</p>
        </div>
        <button className="btn btn-primary" onClick={onCreate}>
          <Icon.Plus size={14} /> New index
        </button>
      </div>

      {/* Filter row */}
      <div style={{ display: 'flex', gap: 12, alignItems: 'center', marginBottom: 16 }}>
        <div style={{ position: 'relative', flex: '0 1 320px' }}>
          <Icon.Search size={14} color="var(--text-tertiary)"
            style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)' }} />
          <input className="input" placeholder="Search indexes…"
            style={{ paddingLeft: 34 }}
            value={query} onChange={(e) => setQuery(e.target.value)} />
        </div>
        <div style={{ display: 'flex', gap: 4 }}>
          {[
            { id: 'all', label: 'All' },
            { id: 'ready', label: 'Ready' },
            { id: 'indexing', label: 'Indexing' },
            { id: 'failed', label: 'Failed' },
          ].map(t => (
            <button key={t.id} onClick={() => setFilter(t.id)}
              className={filter === t.id ? 'btn btn-secondary btn-sm' : 'btn btn-ghost btn-sm'}
              style={filter === t.id ? { borderColor: 'var(--accent)', color: 'var(--accent-text)', background: 'var(--accent-subtle)' } : {}}>
              {t.label}
            </button>
          ))}
        </div>
        <div style={{ flex: 1 }} />
        <span className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>
          {filtered.length} of {indexes.length}
        </span>
      </div>

      {/* Indexes table */}
      <div className="card">
        <div style={{
          display: 'grid',
          gridTemplateColumns: '1fr 110px 100px 120px 130px 110px 30px',
          gap: 12, padding: '12px 20px',
          borderBottom: '1px solid var(--border-default)',
          background: 'var(--bg-inset)',
        }}>
          {['Name', 'Videos', 'Hours', 'Size', 'Status', 'Updated', ''].map((h, i) => (
            <span key={i} className="eyebrow" style={{ fontSize: 10 }}>{h}</span>
          ))}
        </div>
        {filtered.map((idx, i) => (
          <div key={idx.id} onClick={() => onOpenIndex(idx)}
            style={{
              display: 'grid',
              gridTemplateColumns: '1fr 110px 100px 120px 130px 110px 30px',
              gap: 12, padding: '14px 20px', alignItems: 'center',
              borderBottom: i < filtered.length - 1 ? '1px solid var(--border-subtle)' : 'none',
              cursor: 'pointer',
              transition: 'background var(--duration-fast)',
            }}
            onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-surface-hover)'}
            onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
            <div style={{ minWidth: 0 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <div style={{
                  width: 32, height: 32, borderRadius: 6, flexShrink: 0,
                  background: 'linear-gradient(135deg, var(--accent), var(--accent-light))',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                }}>
                  <Icon.Database size={14} color="white" />
                </div>
                <div style={{ minWidth: 0 }}>
                  <div style={{ fontSize: 13, fontWeight: 500, color: 'var(--text-primary)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                    {idx.name}
                  </div>
                  <div style={{ fontSize: 11, color: 'var(--text-tertiary)', marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                    {idx.accent}
                  </div>
                </div>
              </div>
            </div>
            <span className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)' }}>{idx.videos.toLocaleString()}</span>
            <span className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)' }}>{idx.hours.toFixed(1)}</span>
            <span className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)' }}>{idx.size}</span>
            <StatusPill status={idx.status} progress={idx.progress} />
            <span style={{ fontSize: 12, color: 'var(--text-tertiary)' }}>{idx.updated}</span>
            <Icon.ChevronRight size={14} color="var(--text-tertiary)" />
          </div>
        ))}
        {filtered.length === 0 && (
          <EmptyState icon="Database" title="No indexes match" body="Try a different filter or search term." />
        )}
      </div>
    </div>
  );
}

/* ─── Create Index Modal ─── */

function CreateIndexModal({ open, onClose, onCreated }) {
  const [name, setName] = React.useState('');
  const [mode, setMode] = React.useState('standard');
  const [step, setStep] = React.useState(0);
  const [files, setFiles] = React.useState([]);
  const [creating, setCreating] = React.useState(false);

  React.useEffect(() => {
    if (open) {
      setName(''); setMode('standard'); setStep(0);
      setFiles([]); setCreating(false);
    }
  }, [open]);

  if (!open) return null;

  const fakeUpload = () => {
    setFiles([
      { name: 'cam-04-east-perimeter-2026-01-15.mp4', size: '14.0 GB', progress: 1 },
      { name: 'cam-12-north-gate-2026-01-15.mp4', size: '12.6 GB', progress: 0.92 },
      { name: 'cam-07-parking-lot-2026-01-15.mp4', size: '11.2 GB', progress: 0.34 },
    ]);
  };

  const create = () => {
    setCreating(true);
    setTimeout(() => {
      onCreated({
        id: 'idx_' + Math.random().toString(36).slice(2, 6),
        name: name || 'untitled-index',
        videos: files.length, hours: 24.0,
        size: mode === 'dwarf' ? '0.95 GB' : mode === 'mellon' ? '32.3 GB' : '38 GB',
        status: 'indexing', progress: 0.05,
        accent: 'just created',
        updated: 'just now',
        model: mode === 'standard' ? 'standard' : mode,
      });
    }, 800);
  };

  return (
    <Modal onClose={onClose} title="Create new index" width={640}>
      {/* Steps */}
      <div style={{ display: 'flex', gap: 6, marginBottom: 24 }}>
        {['Configure', 'Add videos', 'Review'].map((s, i) => (
          <div key={i} style={{ flex: 1 }}>
            <div style={{
              height: 3, background: i <= step ? 'var(--accent)' : 'var(--border-subtle)',
              borderRadius: 2, transition: 'background 0.3s',
            }} />
            <div style={{ marginTop: 8, fontSize: 11, color: i <= step ? 'var(--text-primary)' : 'var(--text-tertiary)', fontWeight: i === step ? 500 : 400 }}>
              {String(i + 1).padStart(2, '0')} · {s}
            </div>
          </div>
        ))}
      </div>

      {step === 0 && (
        <div style={{ display: 'grid', gap: 16 }}>
          <div>
            <label className="label">Index name</label>
            <input className="input" placeholder="e.g. surveillance-q2-2026" autoFocus
              value={name} onChange={(e) => setName(e.target.value)} />
          </div>
          <div>
            <label className="label">Ingestion mode</label>
            <select className="input" value={mode} onChange={(e) => setMode(e.target.value)}
              style={{ fontFamily: 'var(--font-mono)', fontSize: 13 }}>
              <option value="standard">Standard — original video, no compression</option>
              <option value="mellon">Mellon — compressed · 15% cost saving</option>
              <option value="dwarf">Dwarf — highly compressed · 45% cost saving</option>
            </select>
            <div style={{
              marginTop: 10, padding: 14, background: 'var(--bg-inset)',
              border: '1px solid var(--border-subtle)', borderRadius: 'var(--radius-md)',
              display: 'flex', gap: 12, alignItems: 'flex-start',
            }}>
              {(() => {
                const meta = {
                  standard: { icon: 'Database', title: 'Standard ingestion', body: 'Indexes your videos as-is. Highest fidelity, full bitrate retained — best when you need pixel-perfect playback alongside search.', save: null, accent: 'var(--text-tertiary)' },
                  mellon:   { icon: 'Layers',   title: 'Mellon · compressed', body: 'Hardware-decoded, zero-copy ingestion on a perceptually-compressed copy. Same accuracy, lower egress and decode cost across training and inference.', save: '15% cost saving', accent: 'var(--accent)' },
                  dwarf:    { icon: 'Compress', title: 'Dwarf · highly compressed', body: 'Uses our DCVC-RT codec to shrink originals 30–40× before indexing. Massive storage and bandwidth savings — recommended for archival and high-volume fleets.', save: '45% cost saving', accent: 'var(--accent)' },
                }[mode];
                const Comp = Icon[meta.icon];
                return (
                  <>
                    <div style={{
                      width: 32, height: 32, borderRadius: 'var(--radius-sm)',
                      background: 'var(--bg-surface)', border: '1px solid var(--border-subtle)',
                      display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                    }}>
                      <Comp size={15} color={meta.accent} />
                    </div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                        <span style={{ fontSize: 13, fontWeight: 500 }}>{meta.title}</span>
                        {meta.save && <span className="badge badge-accent" style={{ fontSize: 9 }}>{meta.save}</span>}
                      </div>
                      <div style={{ fontSize: 12, color: 'var(--text-secondary)', lineHeight: 1.5 }}>{meta.body}</div>
                    </div>
                  </>
                );
              })()}
            </div>
          </div>
        </div>
      )}

      {step === 1 && (
        <div>
          <div onClick={fakeUpload} style={{
            border: '2px dashed var(--border-default)', borderRadius: 'var(--radius-lg)',
            padding: '40px 24px', textAlign: 'center', cursor: 'pointer',
            background: 'var(--bg-inset)',
            transition: 'all var(--duration-fast)',
          }}
            onMouseEnter={(e) => { e.currentTarget.style.borderColor = 'var(--accent)'; e.currentTarget.style.background = 'var(--accent-subtle)'; }}
            onMouseLeave={(e) => { e.currentTarget.style.borderColor = 'var(--border-default)'; e.currentTarget.style.background = 'var(--bg-inset)'; }}>
            <Icon.Upload size={28} color="var(--text-tertiary)" />
            <div style={{ marginTop: 12, fontSize: 14, fontWeight: 500 }}>Drop files or click to browse</div>
            <div style={{ marginTop: 4, fontSize: 12, color: 'var(--text-tertiary)' }}>
              MP4, MKV, MOV, Y4M up to 50 GB · or paste S3 / GCS URLs
            </div>
          </div>

          <div style={{ marginTop: 16, display: 'flex', gap: 8 }}>
            <button className="btn btn-secondary btn-sm"><Icon.Globe size={12} /> From URL</button>
            <button className="btn btn-secondary btn-sm">From S3 bucket</button>
            <button className="btn btn-secondary btn-sm">From Backblaze B2</button>
          </div>

          {files.length > 0 && (
            <div style={{ marginTop: 20 }}>
              <div className="eyebrow" style={{ marginBottom: 8 }}>Uploading · {files.length}</div>
              {files.map((f, i) => (
                <div key={i} style={{ padding: '10px 0', borderTop: i > 0 ? '1px solid var(--border-subtle)' : 'none' }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, marginBottom: 4 }}>
                    <span style={{ fontFamily: 'var(--font-mono)' }}>{f.name}</span>
                    <span className="mono" style={{ color: 'var(--text-tertiary)' }}>{f.size}</span>
                  </div>
                  <div style={{ height: 3, background: 'var(--border-subtle)', borderRadius: 2 }}>
                    <div style={{
                      width: `${f.progress * 100}%`, height: '100%',
                      background: f.progress === 1 ? 'var(--positive)' : 'var(--accent)',
                      borderRadius: 2, transition: 'width 0.3s',
                    }} />
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {step === 2 && (
        <div>
          <div className="card" style={{ background: 'var(--bg-inset)', border: 'none' }}>
            <div style={{ padding: 16 }}>
              {[
                ['Name', name || 'untitled-index'],
                ['Ingestion', mode === 'standard' ? 'Standard' : mode === 'mellon' ? 'Mellon · 15% saving' : 'Dwarf · 45% saving'],
                ['Videos', files.length || 0],
                ['Total size', mode === 'dwarf' ? '0.95 GB (38.0 GB → Dwarf)' : mode === 'mellon' ? '32.3 GB (38.0 GB → Mellon)' : '38.0 GB'],
                ['Estimated indexing time', mode === 'dwarf' ? '~1h 12m' : mode === 'mellon' ? '~1h 52m' : '~2h 12m'],
                ['Estimated cost', mode === 'dwarf' ? '70 credits (was 128)' : mode === 'mellon' ? '109 credits (was 128)' : '128 credits'],
              ].map(([k, v], i) => (
                <div key={i} style={{ display: 'flex', justifyContent: 'space-between', padding: '8px 0', fontSize: 13, borderTop: i > 0 ? '1px solid var(--border-subtle)' : 'none' }}>
                  <span style={{ color: 'var(--text-secondary)' }}>{k}</span>
                  <span className="mono" style={{ color: 'var(--text-primary)', fontWeight: 500 }}>{v}</span>
                </div>
              ))}
            </div>
          </div>
          <div style={{ marginTop: 16, padding: 12, background: 'var(--accent-muted)', borderRadius: 'var(--radius-md)', fontSize: 12, color: 'var(--accent-text)', display: 'flex', gap: 10 }}>
            <Icon.Info size={14} />
            <span>Indexing runs in the background. We'll email you when it's ready.</span>
          </div>
        </div>
      )}

      {/* Footer */}
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 28, paddingTop: 20, borderTop: '1px solid var(--border-subtle)' }}>
        <button className="btn btn-ghost" onClick={() => step > 0 ? setStep(step - 1) : onClose()}>
          {step > 0 ? <><Icon.ChevronLeft size={14} /> Back</> : 'Cancel'}
        </button>
        <button className="btn btn-primary" onClick={() => step < 2 ? setStep(step + 1) : create()} disabled={creating}>
          {creating ? <span className="spinner" style={{ borderTopColor: 'white' }} /> :
            step < 2 ? <>Continue <Icon.ArrowRight size={14} /></> : <>Create index <Icon.Check size={14} /></>}
        </button>
      </div>
    </Modal>
  );
}

function Checkbox({ label, sub, defaultChecked = false }) {
  const [on, setOn] = React.useState(defaultChecked);
  return (
    <label style={{ display: 'flex', alignItems: 'flex-start', gap: 10, padding: '10px 12px', border: '1px solid var(--border-subtle)', borderRadius: 'var(--radius-md)', cursor: 'pointer' }}>
      <input type="checkbox" checked={on} onChange={(e) => setOn(e.target.checked)} style={{ marginTop: 2, accentColor: 'var(--accent)' }} />
      <div>
        <div style={{ fontSize: 13, fontWeight: 500 }}>{label}</div>
        {sub && <div style={{ fontSize: 11, color: 'var(--text-tertiary)', marginTop: 2 }}>{sub}</div>}
      </div>
    </label>
  );
}

function Modal({ children, onClose, title, width = 560 }) {
  React.useEffect(() => {
    const k = (e) => e.key === 'Escape' && onClose();
    document.addEventListener('keydown', k);
    return () => document.removeEventListener('keydown', k);
  }, [onClose]);

  return (
    <div onClick={onClose} className="fade-in" style={{
      position: 'fixed', inset: 0, background: 'rgba(20, 18, 14, 0.4)',
      backdropFilter: 'blur(4px)', display: 'flex',
      alignItems: 'center', justifyContent: 'center', padding: 24, zIndex: 200,
    }}>
      <div onClick={(e) => e.stopPropagation()} className="fade-in-up" style={{
        background: 'var(--bg-surface)',
        border: '1px solid var(--border-default)',
        borderRadius: 'var(--radius-lg)',
        boxShadow: 'var(--shadow-lg)',
        width: '100%', maxWidth: width, maxHeight: '90vh', overflowY: 'auto',
      }}>
        {title && (
          <div style={{ padding: '20px 24px', borderBottom: '1px solid var(--border-subtle)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <h3 style={{ fontSize: 16, fontWeight: 600, margin: 0 }}>{title}</h3>
            <button onClick={onClose} className="btn btn-ghost btn-sm" style={{ width: 28, padding: 0 }}>
              <Icon.X size={14} />
            </button>
          </div>
        )}
        <div style={{ padding: 24 }}>{children}</div>
      </div>
    </div>
  );
}

/* ─── Index Detail with Search ─── */

const SAMPLE_RESULTS = [
  { id: 'r1', ts: '02:14:33', start: 7833, end: 7842, video: 'cam-04 / east-perimeter / 2026-01-15.mp4', score: 0.94, snippet: 'A figure in dark clothing climbs over the perimeter fence near the loading dock.' },
  { id: 'r2', ts: '01:47:08', start: 6428, end: 6437, video: 'cam-12 / north-gate / 2026-01-15.mp4', score: 0.81, snippet: 'Person climbs the chain-link fence at the north service entrance.' },
  { id: 'r3', ts: '03:22:55', start: 12175, end: 12184, video: 'cam-04 / east-perimeter / 2026-01-15.mp4', score: 0.76, snippet: 'Individual scaling fence section near camera 4 — second occurrence.' },
  { id: 'r4', ts: '00:38:12', start: 2292, end: 2301, video: 'cam-07 / parking-lot / 2026-01-14.mp4', score: 0.71, snippet: 'Two people approach the fence; one begins to climb but stops.' },
  { id: 'r5', ts: '04:11:40', start: 15100, end: 15109, video: 'cam-12 / north-gate / 2026-01-14.mp4', score: 0.68, snippet: 'Person observed near fence; possible attempt at climbing.' },
];

function IndexDetail({ index, onBack }) {
  const [tab, setTab] = React.useState('search');
  const [query, setQuery] = React.useState('person climbing fence at night');
  const [searching, setSearching] = React.useState(false);
  const [results, setResults] = React.useState(SAMPLE_RESULTS);
  const [selected, setSelected] = React.useState(SAMPLE_RESULTS[0]);
  const [hasSearched, setHasSearched] = React.useState(true);

  const search = () => {
    if (!query.trim()) return;
    setSearching(true);
    setHasSearched(true);
    setTimeout(() => {
      setResults(SAMPLE_RESULTS);
      setSelected(SAMPLE_RESULTS[0]);
      setSearching(false);
    }, 700);
  };

  return (
    <div className="page-content">
      {/* Header */}
      <div style={{ marginBottom: 24 }}>
        <button onClick={onBack} className="btn btn-ghost btn-sm" style={{ marginBottom: 12, paddingLeft: 6 }}>
          <Icon.ChevronLeft size={13} /> Indexes
        </button>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 16, flexWrap: 'wrap' }}>
          <div style={{ minWidth: 0, flex: 1 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 6, flexWrap: 'wrap' }}>
              <h1 className="page-title" style={{ margin: 0, fontSize: 24, whiteSpace: 'nowrap' }}>{index.name}</h1>
              <StatusPill status={index.status} progress={index.progress} />
            </div>
            <div style={{ display: 'flex', gap: 16, fontSize: 13, color: 'var(--text-tertiary)', flexWrap: 'wrap' }}>
              <span className="mono" style={{ whiteSpace: 'nowrap' }}>{index.id}</span>
              <span style={{ whiteSpace: 'nowrap' }}>{index.videos.toLocaleString()} videos</span>
              <span style={{ whiteSpace: 'nowrap' }}>{index.hours.toFixed(1)} hours</span>
              <span style={{ whiteSpace: 'nowrap' }}>{index.size}</span>
              <span style={{ whiteSpace: 'nowrap' }}>model: {index.model}</span>
            </div>
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            <button className="btn btn-secondary"><Icon.Upload size={14} /> Add videos</button>
            <button className="btn btn-secondary"><Icon.More size={14} /></button>
          </div>
        </div>
      </div>

      {/* Tabs */}
      <div style={{ borderBottom: '1px solid var(--border-default)', marginBottom: 24, display: 'flex', gap: 4 }}>
        {[
          { id: 'search', label: 'Search', icon: 'Search' },
          { id: 'videos', label: `Videos \u00B7 ${index.videos}`, icon: 'Video' },
          { id: 'usage', label: 'Usage', icon: 'Activity' },
          { id: 'settings', label: 'Settings', icon: 'Settings' },
        ].map(t => {
          const Comp = Icon[t.icon];
          return (
            <button key={t.id} onClick={() => setTab(t.id)}
              style={{
                padding: '12px 14px',
                fontSize: 13, color: tab === t.id ? 'var(--text-primary)' : 'var(--text-secondary)',
                fontWeight: tab === t.id ? 500 : 400,
                borderBottom: `2px solid ${tab === t.id ? 'var(--accent)' : 'transparent'}`,
                marginBottom: -1,
                display: 'flex', alignItems: 'center', gap: 6,
                whiteSpace: 'nowrap',
              }}>
              <Comp size={13} /> {t.label}
            </button>
          );
        })}
      </div>

      {tab === 'search' && (
        <SearchView
          query={query} setQuery={setQuery}
          searching={searching} onSearch={search}
          results={results} selected={selected} setSelected={setSelected}
          hasSearched={hasSearched}
        />
      )}
      {tab === 'videos' && <VideosTab />}
      {tab === 'usage' && <UsageTab />}
      {tab === 'settings' && <SettingsTab indexName={index.name} />}
    </div>
  );
}

function SearchView({ query, setQuery, searching, onSearch, results, selected, setSelected, hasSearched }) {
  const examples = [
    'person climbing fence at night',
    'red sedan entering the lot',
    'two people in conversation near loading dock',
    'package left unattended',
  ];

  return (
    <div>
      {/* Search input */}
      <div style={{ marginBottom: 24 }}>
        <div style={{
          display: 'flex', gap: 8, alignItems: 'stretch',
          border: '1px solid var(--border-default)', borderRadius: 'var(--radius-lg)',
          background: 'var(--bg-surface)', padding: 4,
          boxShadow: '0 1px 3px rgba(0,0,0,0.03)',
        }}>
          <div style={{ display: 'flex', alignItems: 'center', paddingLeft: 12, paddingRight: 8 }}>
            <Icon.Search size={16} color="var(--text-tertiary)" />
          </div>
          <input
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            onKeyDown={(e) => e.key === 'Enter' && onSearch()}
            placeholder="Describe what you're looking for…"
            style={{
              flex: 1, border: 'none', outline: 'none', background: 'transparent',
              fontSize: 15, color: 'var(--text-primary)', padding: '12px 0',
            }} />
          <button className="btn btn-primary" onClick={onSearch} disabled={searching} style={{ height: 'auto' }}>
            {searching ? <span className="spinner" style={{ borderTopColor: 'white' }} /> : <>Search <Icon.ArrowRight size={14} /></>}
          </button>
        </div>
        {!hasSearched && (
          <div style={{ marginTop: 14, display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            <span className="eyebrow" style={{ alignSelf: 'center', marginRight: 6 }}>Try</span>
            {examples.map(e => (
              <button key={e} onClick={() => { setQuery(e); setTimeout(onSearch, 50); }}
                className="btn btn-secondary btn-sm" style={{ borderRadius: 999 }}>
                {e}
              </button>
            ))}
          </div>
        )}
      </div>

      {hasSearched && !searching && (
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 380px', gap: 20, alignItems: 'start' }}>
          {/* Results list */}
          <div className="card">
            <div style={{ padding: '12px 20px', borderBottom: '1px solid var(--border-subtle)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <span className="eyebrow">{results.length} matches · 138ms</span>
              <button className="btn btn-ghost btn-sm"><Icon.Filter size={12} /> Filter</button>
            </div>
            {results.map((r, i) => (
              <div key={r.id} onClick={() => setSelected(r)}
                style={{
                  padding: '14px 20px', cursor: 'pointer',
                  borderBottom: i < results.length - 1 ? '1px solid var(--border-subtle)' : 'none',
                  borderLeft: `3px solid ${selected?.id === r.id ? 'var(--accent)' : 'transparent'}`,
                  background: selected?.id === r.id ? 'var(--accent-muted)' : 'transparent',
                  transition: 'all var(--duration-fast)',
                }}>
                <div style={{ display: 'flex', gap: 14, alignItems: 'flex-start' }}>
                  {/* Thumbnail */}
                  <div style={{
                    width: 96, height: 56, flexShrink: 0,
                    borderRadius: 4, overflow: 'hidden',
                    background: 'linear-gradient(135deg, #1e1e1c, #3c3a36)',
                    position: 'relative',
                  }}>
                    <div style={{
                      position: 'absolute', inset: 0,
                      background: `radial-gradient(circle at ${30 + i * 12}% ${40 + i * 8}%, rgba(255, 200, 150, 0.18), transparent 50%)`,
                    }} />
                    <div style={{
                      position: 'absolute', bottom: 4, left: 4, right: 4,
                      display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end',
                    }}>
                      <span className="mono" style={{ fontSize: 9, color: 'rgba(255,255,255,0.85)', background: 'rgba(0,0,0,0.6)', padding: '1px 4px', borderRadius: 2 }}>{r.ts}</span>
                      <Icon.Play size={10} color="rgba(255,255,255,0.85)" />
                    </div>
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 8, marginBottom: 4 }}>
                      <span className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{r.video}</span>
                      <span className="mono" style={{
                        fontSize: 11, fontWeight: 600,
                        color: r.score > 0.85 ? 'var(--positive)' : r.score > 0.75 ? 'var(--accent)' : 'var(--text-tertiary)',
                        flexShrink: 0,
                      }}>{r.score.toFixed(2)}</span>
                    </div>
                    <div style={{ fontSize: 13, color: 'var(--text-primary)', lineHeight: 1.5 }}>
                      {r.snippet}
                    </div>
                  </div>
                </div>
              </div>
            ))}
          </div>

          {/* Player + meta */}
          <div style={{ position: 'sticky', top: 80 }}>
            <div className="card">
              {/* Video */}
              <div style={{
                aspectRatio: '16 / 9', position: 'relative',
                background: 'linear-gradient(135deg, #1a1a18, #3c3a36)',
                overflow: 'hidden',
              }}>
                <div style={{
                  position: 'absolute', inset: 0,
                  background: 'radial-gradient(circle at 60% 50%, rgba(255, 200, 150, 0.15), transparent 50%)',
                }} />
                {/* Detection overlay */}
                <div style={{
                  position: 'absolute', left: '52%', top: '32%', width: 70, height: 92,
                  border: '1.5px solid var(--accent-light)', borderRadius: 2,
                }}>
                  <span style={{ position: 'absolute', top: -18, left: 0, fontSize: 9, color: 'white', background: 'var(--accent)', padding: '1px 4px', borderRadius: 2, fontFamily: 'var(--font-mono)' }}>
                    person 0.94
                  </span>
                </div>
                {/* Play */}
                <button style={{
                  position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)',
                  width: 56, height: 56, borderRadius: '50%',
                  background: 'rgba(255, 255, 255, 0.9)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                }}>
                  <Icon.Play size={20} color="var(--accent)" />
                </button>
                <div style={{ position: 'absolute', top: 8, left: 8, fontSize: 10, color: 'rgba(255,255,255,0.85)', background: 'rgba(0,0,0,0.6)', padding: '2px 6px', borderRadius: 2, fontFamily: 'var(--font-mono)' }}>
                  ● REC · {selected?.ts}
                </div>
              </div>

              {/* Timeline */}
              <div style={{ padding: 12 }}>
                <div style={{ height: 4, background: 'var(--border-subtle)', borderRadius: 2, position: 'relative' }}>
                  {/* Marker */}
                  <div style={{ position: 'absolute', left: '36%', width: '2.5%', height: '100%', background: 'var(--accent)', borderRadius: 2 }} />
                  <div style={{ position: 'absolute', left: '36%', top: -3, width: 2, height: 10, background: 'var(--accent)' }} />
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 6, fontSize: 10, color: 'var(--text-tertiary)', fontFamily: 'var(--font-mono)' }}>
                  <span>00:00:00</span>
                  <span style={{ color: 'var(--accent)' }}>{selected?.ts}</span>
                  <span>08:00:00</span>
                </div>
              </div>

              {/* Meta */}
              <div style={{ padding: '12px 16px 16px', borderTop: '1px solid var(--border-subtle)' }}>
                <div className="eyebrow" style={{ marginBottom: 8 }}>Match details</div>
                {[
                  ['Score', selected?.score.toFixed(3)],
                  ['Window', `${selected?.start}s → ${selected?.end}s`],
                  ['Source', selected?.video.split('/')[0].trim()],
                  ['Camera', selected?.video.split('/')[1]?.trim()],
                  ['Detected', 'person, fence, climbing motion'],
                ].map(([k, v], i) => (
                  <div key={i} style={{ display: 'flex', justifyContent: 'space-between', padding: '4px 0', fontSize: 12 }}>
                    <span style={{ color: 'var(--text-tertiary)' }}>{k}</span>
                    <span className="mono" style={{ color: 'var(--text-primary)' }}>{v}</span>
                  </div>
                ))}
              </div>

              <div style={{ display: 'flex', gap: 6, padding: '0 16px 16px' }}>
                <button className="btn btn-secondary btn-sm" style={{ flex: 1 }}><Icon.Download size={12} /> Clip</button>
                <button className="btn btn-secondary btn-sm" style={{ flex: 1 }}><Icon.Tag size={12} /> Label</button>
                <button className="btn btn-secondary btn-sm"><Icon.More size={12} /></button>
              </div>
            </div>
          </div>
        </div>
      )}

      {searching && (
        <div style={{ padding: '60px 20px', textAlign: 'center' }}>
          <div className="spinner" style={{ width: 32, height: 32, margin: '0 auto 16px' }} />
          <div style={{ fontSize: 14, color: 'var(--text-secondary)' }}>Scanning {/* */} embedding space…</div>
          <div className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', marginTop: 6 }}>312 hours · 1,284 videos</div>
        </div>
      )}
    </div>
  );
}

function VideosTab() {
  return (
    <div className="card">
      <div style={{
        display: 'grid', gridTemplateColumns: '60px 1fr 100px 90px 100px 100px 30px',
        gap: 12, padding: '12px 20px',
        borderBottom: '1px solid var(--border-default)', background: 'var(--bg-inset)',
      }}>
        {['', 'File', 'Duration', 'Codec', 'Size', 'Dwarfed', ''].map((h, i) => (
          <span key={i} className="eyebrow" style={{ fontSize: 10 }}>{h}</span>
        ))}
      </div>
      {MOCK_VIDEOS.map((v, i) => (
        <div key={v.id} style={{
          display: 'grid', gridTemplateColumns: '60px 1fr 100px 90px 100px 100px 30px',
          gap: 12, padding: '14px 20px', alignItems: 'center',
          borderBottom: i < MOCK_VIDEOS.length - 1 ? '1px solid var(--border-subtle)' : 'none',
        }}>
          <div style={{
            width: 48, height: 28, borderRadius: 3, background: 'linear-gradient(135deg, #2a2a28, #555)',
          }} />
          <span style={{ fontSize: 12, fontFamily: 'var(--font-mono)', color: 'var(--text-primary)' }}>{v.title}</span>
          <span className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)' }}>{v.duration}</span>
          <span className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)' }}>{v.codec}</span>
          <span className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)' }}>{v.size}</span>
          {v.dwarfed
            ? <span className="badge badge-accent">{v.ratio}×</span>
            : <span className="badge badge-neutral">No</span>
          }
          <Icon.More size={14} color="var(--text-tertiary)" />
        </div>
      ))}
    </div>
  );
}

function UsageTab() {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12 }}>
      {[
        { label: 'Search queries (30d)', val: '14,288', sub: '+22% vs prior' },
        { label: 'Avg latency', val: '128ms', sub: 'p95: 312ms' },
        { label: 'Index size', val: '6.4 GB', sub: 'vectors + metadata' },
      ].map((s, i) => (
        <div key={i} className="card card-padded">
          <div className="eyebrow" style={{ marginBottom: 8 }}>{s.label}</div>
          <div className="mono" style={{ fontSize: 28, fontWeight: 500, letterSpacing: '-0.02em' }}>{s.val}</div>
          <div style={{ marginTop: 6, fontSize: 12, color: 'var(--text-tertiary)' }}>{s.sub}</div>
        </div>
      ))}
    </div>
  );
}

function SettingsTab({ indexName }) {
  return (
    <div style={{ maxWidth: 600 }}>
      <div className="card card-padded" style={{ marginBottom: 16 }}>
        <h4 style={{ fontSize: 14, fontWeight: 600, margin: '0 0 16px' }}>Index settings</h4>
        <div style={{ marginBottom: 14 }}>
          <label className="label">Name</label>
          <input className="input" defaultValue={indexName} />
        </div>
        <div>
          <label className="label">Description</label>
          <textarea className="input" rows={3} placeholder="Optional notes about this index…" />
        </div>
        <div style={{ marginTop: 16, display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
          <button className="btn btn-secondary">Cancel</button>
          <button className="btn btn-primary">Save changes</button>
        </div>
      </div>
      <div className="card card-padded" style={{ borderColor: 'var(--negative-bg)' }}>
        <h4 style={{ fontSize: 14, fontWeight: 600, margin: '0 0 6px', color: 'var(--negative)' }}>Danger zone</h4>
        <p style={{ fontSize: 12, color: 'var(--text-secondary)', margin: '0 0 14px' }}>Deleting this index removes all vectors and metadata. Source videos remain.</p>
        <button className="btn btn-secondary" style={{ color: 'var(--negative)', borderColor: 'var(--negative-bg)' }}>
          <Icon.Trash size={13} /> Delete index
        </button>
      </div>
    </div>
  );
}

Object.assign(window, { IndexesList, IndexDetail, CreateIndexModal, Modal, Checkbox });
