// assets/screen_deployments.jsx
const rnd = () => Math.random();
function ScreenDeployments({ go, t }) {
  const [statusFilter, setStatusFilter] = React.useState('all');
  const [search, setSearch] = React.useState('');

  const filtered = DEPLOYMENTS.filter(d =>
    (statusFilter === 'all' || d.status === statusFilter) &&
    (!search || d.id.includes(search) || d.project_id.includes(search) || d.project_name.toLowerCase().includes(search.toLowerCase()))
  );

  const stats = {
    succeeded: DEPLOYMENTS.filter(d => d.status === 'succeeded').length,
    failed:    DEPLOYMENTS.filter(d => d.status === 'failed').length,
    pending:   DEPLOYMENTS.filter(d => d.status === 'pending').length,
    building:  DEPLOYMENTS.filter(d => d.status === 'building').length,
  };
  const successRate = (stats.succeeded / (stats.succeeded + stats.failed) * 100).toFixed(1);
  const avgDuration = (DEPLOYMENTS.filter(d => d.duration).reduce((s, d) => s + d.duration, 0) / DEPLOYMENTS.filter(d => d.duration).length).toFixed(0);

  // Top errors
  const errorMap = {};
  DEPLOYMENTS.filter(d => d.status === 'failed').forEach(d => {
    const k = d.error_code || 'unknown';
    errorMap[k] = (errorMap[k] || 0) + 1;
  });
  const topErrors = Object.entries(errorMap).map(([label, value]) => ({ label, value })).sort((a, b) => b.value - a.value);

  return (
    <div className="page">
      <div className="page-head">
        <h1>Deployments</h1>
        <span className="page-sub">24h window · {DEPLOYMENTS.length} total</span>
        <div className="page-actions">
          <div className="segmented"><button>1h</button><button className="active">24h</button><button>7d</button></div>
          <button className="btn"><Icon name="refresh" size={12} /> Refresh</button>
        </div>
      </div>

      <div className="grid cols-4" style={{ marginBottom: 16 }}>
        <KpiCard label="Success rate" value={successRate} unit="%" delta={2.1} icon="check2" sparkData={timeSeries(24, 92, 4)} sparkColor="var(--success)" />
        <KpiCard label="Avg deploy time" value={avgDuration} unit="s" delta={-8} icon="zap" sparkData={timeSeries(24, 145, 30)} sparkColor="var(--chart-2)" />
        <KpiCard label="Failed (24h)" value={stats.failed} delta={5} icon="alert" sparkData={timeSeries(24, 3, 3)} sparkColor="var(--danger)" />
        <div className="card kpi">
          <div className="kpi-label"><Icon name="cpu" size={12} /> Active</div>
          <div className="kpi-value" style={{ fontSize: 22 }}>
            <span style={{ color: 'var(--info)' }}>{stats.building}</span>
            <span className="dim" style={{ fontSize: 14, margin: '0 8px' }}>·</span>
            <span style={{ color: 'var(--warning)' }}>{stats.pending}</span>
          </div>
          <div className="kpi-delta neutral" style={{ marginTop: 8, fontFamily: 'var(--font-mono)' }}>
            <span style={{ color: 'var(--info)' }}>{stats.building} building</span>
            <span style={{ marginLeft: 12, color: 'var(--warning)' }}>{stats.pending} pending</span>
          </div>
        </div>
      </div>

      {/* Top errors chart */}
      <div className="grid" style={{ gridTemplateColumns: '1fr 2fr', gap: 12, marginBottom: 16 }}>
        <div className="card">
          <div className="card-head"><h3>Top errors</h3><span className="sub">failed deploys 24h</span></div>
          <div className="card-body"><HBarChart data={topErrors} maxBars={8} color="var(--danger)" /></div>
        </div>

        <div className="card">
          <div className="card-head"><h3>Deploys per hour</h3><span className="sub">24h · stacked by status</span></div>
          <div className="card-body">
            <StackedBars data={Array.from({length: 24}, () => ({
              succeeded: Math.floor(rnd() * 12) + 4,
              failed: Math.floor(rnd() * 3),
              pending: Math.floor(rnd() * 2),
            }))} labels={Array.from({length: 24}, (_, i) => i + 'h')} keys={['succeeded', 'failed', 'pending']}
              colors={['var(--success)', 'var(--danger)', 'var(--warning)']} height={180} />
          </div>
        </div>
      </div>

      {/* Table */}
      <div className="card">
        <div className="card-head" style={{ gap: 8 }}>
          <select className="select" style={{ width: 'auto' }} value={statusFilter} onChange={e => setStatusFilter(e.target.value)}>
            <option value="all">All status</option>
            <option value="succeeded">succeeded</option>
            <option value="failed">failed</option>
            <option value="building">building</option>
            <option value="pending">pending</option>
          </select>
          <div style={{ position: 'relative', flex: 1, maxWidth: 320 }}>
            <Icon name="search" size={12} style={{ position: 'absolute', left: 8, top: 7, color: 'var(--text-tertiary)' }} />
            <input className="input" style={{ paddingLeft: 26 }} placeholder="id / project name" value={search} onChange={e => setSearch(e.target.value)} />
          </div>
          <span className="dim fs-11" style={{ marginLeft: 'auto' }}>{filtered.length} of {DEPLOYMENTS.length}</span>
        </div>
        <div className="table-wrap" style={{ maxHeight: 'calc(100vh - 480px)' }}>
          <table className="tbl">
            <thead><tr>
              <th>Deployment</th>
              <th>Project</th>
              <th>Status</th>
              <th>Created</th>
              <th className="num">Duration</th>
              <th className="num">Bundle</th>
              <th>Error</th>
              <th style={{ width: 28 }}></th>
            </tr></thead>
            <tbody>
              {filtered.slice(0, 50).map(d => (
                <tr key={d.id} className="clickable" onClick={() => go('/deployments/' + d.id)}>
                  <td className="id">{shortId(d.id)}</td>
                  <td>{d.project_name} <Mono dim>{shortId(d.project_id, 8)}</Mono></td>
                  <td><StatusBadge status={d.status} /></td>
                  <td className="dim"><Mono>{formatRel(d.created_at)}</Mono></td>
                  <td className="num"><Mono>{d.duration ? d.duration + 's' : '—'}</Mono></td>
                  <td className="num dim"><Mono>{d.bundle_size_kb ? d.bundle_size_kb + ' kB' : '—'}</Mono></td>
                  <td className="dim2" style={{ maxWidth: 320, overflow: 'hidden', textOverflow: 'ellipsis' }}>
                    {d.error_code && <><Badge kind="danger">{d.error_code}</Badge> <Mono dim>{d.error_msg}</Mono></>}
                  </td>
                  <td><Icon name="chevron" size={12} style={{ color: 'var(--text-tertiary)' }} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

// ─── Deployment Detail ─────────────────────────────────────────────────────
function ScreenDeploymentDetail({ id, go }) {
  const d = DEPLOYMENTS.find(x => x.id === id) || DEPLOYMENTS.find(x => x.id.startsWith(id)) || DEPLOYMENTS[0];
  const log = React.useMemo(() => mkBuildLog(d), [d.id]);
  const [showSanitizer, setShowSanitizer] = React.useState(true);
  const [showBuild, setShowBuild] = React.useState(true);
  const [showS3, setShowS3] = React.useState(false);
  const [logSearch, setLogSearch] = React.useState('');

  const linkedSession = SESSIONS.find(s => s.id === d.session_id) || SESSIONS[0];

  const filteredLog = log.filter(l => !logSearch || l.msg.toLowerCase().includes(logSearch.toLowerCase()));

  return (
    <div className="page">
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 16, marginBottom: 14 }}>
        <div style={{ flex: 1 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <span style={{ fontSize: 19, fontWeight: 600, fontFamily: 'var(--font-mono)' }}>{shortId(d.id, 16)}</span>
            <CopyButton text={d.id} />
            <StatusBadge status={d.status} />
          </div>
          <div style={{ display: 'flex', gap: 16, fontSize: 12, color: 'var(--text-secondary)', marginTop: 4 }}>
            <span><span className="dim">project</span> <span style={{ color: 'var(--text-primary)' }}>{d.project_name}</span> <Mono dim>{shortId(d.project_id, 8)}</Mono></span>
            <span><span className="dim">created</span> <Mono>{formatRel(d.created_at)}</Mono></span>
            {d.duration && <span><span className="dim">duration</span> <Mono>{d.duration}s</Mono></span>}
            {d.bundle_size_kb && <span><span className="dim">bundle</span> <Mono>{d.bundle_size_kb} kB</Mono></span>}
            {d.cdn_url && <span><span className="dim">live</span> <a className="text-accent" href="#"><Mono>{d.cdn_url}</Mono></a></span>}
          </div>
        </div>
        <div style={{ display: 'flex', gap: 6 }}>
          <a href="#/deployments" className="btn ghost"><Icon name="chevron" size={13} style={{ transform: 'rotate(180deg)' }} /> All deploys</a>
          {d.cdn_url && <button className="btn"><Icon name="external" size={12} /> Open live</button>}
          <button className="btn"><Icon name="refresh" size={12} /> Rebuild</button>
        </div>
      </div>

      <div className="grid" style={{ gridTemplateColumns: '1fr 320px', gap: 12 }}>
        {/* Logs column */}
        <div className="flex col gap-3" style={{ gap: 12 }}>
          {d.status === 'failed' && (
            <div style={{ padding: 12, background: 'var(--danger-muted)', border: '1px solid var(--danger)', borderRadius: 'var(--radius-lg)', display: 'flex', gap: 12, alignItems: 'flex-start' }}>
              <Icon name="alert" size={16} style={{ color: 'var(--danger)', flexShrink: 0, marginTop: 1 }} />
              <div style={{ flex: 1 }}>
                <div style={{ fontWeight: 600, color: 'var(--danger)', marginBottom: 4 }}>{d.error_code}: {d.error_msg}</div>
                <div className="mono" style={{ fontSize: 11, color: 'var(--text-secondary)' }}>{d.error_file}</div>
              </div>
              <button className="btn xs" onClick={() => go('/sessions/' + d.session_id)}><Icon name="trace" size={11} /> View session trace</button>
            </div>
          )}

          {/* Build log */}
          <div className="card">
            <div className="card-head" style={{ gap: 8 }}>
              <button className="btn xs ghost" onClick={() => setShowBuild(b => !b)}>
                <Icon name={showBuild ? 'chevronD' : 'chevron'} size={12} />
              </button>
              <h3>Build log</h3>
              <span className="sub">{log.length} lines</span>
              <div className="actions" style={{ display: 'flex', gap: 6 }}>
                <input className="input" style={{ width: 160, paddingLeft: 8 }} placeholder="search…" value={logSearch} onChange={e => setLogSearch(e.target.value)} />
                <button className="btn xs"><Icon name="download" size={11} /></button>
              </div>
            </div>
            {showBuild && (
              <div className="card-body flush">
                <div className="code-block" style={{ borderRadius: 0, border: 0, maxHeight: 360, overflow: 'auto', padding: '10px 14px' }}>
                  {filteredLog.map((l, i) => (
                    <div key={i} style={{ display: 'grid', gridTemplateColumns: '60px 1fr', gap: 8 }}>
                      <span style={{ color: l.level === 'error' ? 'var(--danger)' : l.level === 'warn' ? 'var(--warning)' : 'var(--text-tertiary)', textTransform: 'uppercase', fontSize: 10 }}>{l.level}</span>
                      <span style={{ color: l.level === 'error' ? 'var(--danger)' : 'var(--text-secondary)' }}>{l.msg}</span>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>

          {/* Sanitizer */}
          <div className="card">
            <div className="card-head" style={{ gap: 8 }}>
              <button className="btn xs ghost" onClick={() => setShowSanitizer(b => !b)}><Icon name={showSanitizer ? 'chevronD' : 'chevron'} size={12} /></button>
              <h3>Sanitizer log</h3>
              <span className="sub">{d.sanitizer_warnings || 0} warnings · 14 files scanned</span>
              <Badge kind="success" style={{ marginLeft: 'auto' }}>passed</Badge>
            </div>
            {showSanitizer && <div className="card-body">
              <div className="code-block" style={{ maxHeight: 200, overflow: 'auto' }}>
                <span className="c"># DOMPurify pass</span>{'\n'}
                <span className="k">REMOVED</span> <span className="s">dangerouslySetInnerHTML</span> from <span className="n">src/components/Hero.tsx:42</span>{'\n'}
                <span className="k">REMOVED</span> <span className="s">javascript:</span> URI from <span className="n">src/components/Footer.tsx:18</span>{'\n'}
                <span className="k">STRIPPED</span> <span className="s">&lt;script&gt;</span> tag from <span className="n">src/components/Newsletter.tsx:55</span>{'\n'}
                <span className="c"># Tailwind safelist verified</span>{'\n'}
                <span className="k">OK</span> 24 utility classes pinned{'\n'}
                <span className="c"># Static analysis</span>{'\n'}
                <span className="k">OK</span> No eval() / Function() constructors{'\n'}
                <span className="k">OK</span> No process.env access in client bundle
              </div>
            </div>}
          </div>

          {/* S3 manifest */}
          {d.status === 'succeeded' && (
            <div className="card">
              <div className="card-head" style={{ gap: 8 }}>
                <button className="btn xs ghost" onClick={() => setShowS3(b => !b)}><Icon name={showS3 ? 'chevronD' : 'chevron'} size={12} /></button>
                <h3>S3 upload manifest</h3>
                <span className="sub">24 files · {d.bundle_size_kb} kB gzipped</span>
                <Badge kind="success" style={{ marginLeft: 'auto' }}>uploaded</Badge>
              </div>
              {showS3 && <div className="card-body">
                <div className="code-block" style={{ maxHeight: 200, overflow: 'auto' }}>
                  <span className="c"># bucket: sq-cdn  prefix: sites/{shortId(d.project_id, 8)}/</span>{'\n'}
                  index.html               <span className="n">  4.2 kB</span>{'\n'}
                  _next/static/chunks/main.js<span className="n"> 142.8 kB</span>{'\n'}
                  _next/static/chunks/framework.js<span className="n"> 88.4 kB</span>{'\n'}
                  _next/static/css/styles.css<span className="n">  18.1 kB</span>{'\n'}
                  images/hero-1280.webp     <span className="n"> 62.7 kB</span>{'\n'}
                  images/hero-640.webp      <span className="n"> 28.1 kB</span>{'\n'}
                  <span className="c">… (18 more)</span>{'\n'}
                  <span className="c"># CloudFront invalidation: I1KRSY18ABC (submitted)</span>
                </div>
              </div>}
            </div>
          )}
        </div>

        {/* Right sidebar */}
        <div className="card" style={{ padding: 14, height: 'fit-content' }}>
          <h4 style={{ margin: '0 0 8px', fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--text-tertiary)', fontWeight: 600 }}>Linked session</h4>
          <div className="card" style={{ padding: 10, background: 'var(--bg-base)', borderColor: 'var(--border-subtle)', cursor: 'pointer' }} onClick={() => go('/sessions/' + linkedSession.id)}>
            <div className="flex between center">
              <Mono>{shortId(linkedSession.id, 12)}</Mono>
              <Icon name="external" size={11} className="dim" />
            </div>
            <div className="fs-12 dim2" style={{ marginTop: 4 }}>{linkedSession.project_name}</div>
            <div style={{ display: 'flex', gap: 10, marginTop: 6, fontSize: 11 }}>
              <StatusBadge status={linkedSession.status} />
              <span className="dim"><Mono>{formatDur(linkedSession.duration)}</Mono></span>
              <span className="dim"><Mono>${linkedSession.cost.toFixed(2)}</Mono></span>
            </div>
          </div>

          <h4 style={{ margin: '16px 0 8px', fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--text-tertiary)', fontWeight: 600 }}>Pipeline stages</h4>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {[
              ['fetch source',     'ok', '0.4s'],
              ['sanitizer',        'ok', '1.2s'],
              ['install deps',     'ok', '8.2s'],
              ['type-check',       d.status === 'failed' ? 'err' : 'ok', d.status === 'failed' ? 'failed' : '3.1s'],
              ['next build',       d.status === 'failed' ? 'idle' : 'ok', d.status === 'failed' ? '—' : '18.7s'],
              ['s3 upload',        d.status === 'failed' ? 'idle' : 'ok', d.status === 'failed' ? '—' : '4.1s'],
              ['cloudfront inv.',  d.status === 'failed' ? 'idle' : 'ok', d.status === 'failed' ? '—' : '0.8s'],
            ].map(([n, s, t]) => (
              <div key={n} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12 }}>
                <span style={{ width: 8, height: 8, borderRadius: '50%', background: s === 'ok' ? 'var(--success)' : s === 'err' ? 'var(--danger)' : 'var(--text-tertiary)', flexShrink: 0 }} />
                <span style={{ color: 'var(--text-secondary)', flex: 1 }}>{n}</span>
                <Mono dim>{t}</Mono>
              </div>
            ))}
          </div>

          <h4 style={{ margin: '16px 0 8px', fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--text-tertiary)', fontWeight: 600 }}>Merchant</h4>
          <Mono>{d.merchant}</Mono>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ScreenDeployments, ScreenDeploymentDetail });
