(function () {
 const { useState, useEffect, useCallback, useRef } = React;

 /* 
 HELPERS
 */
 function fmtDate(iso) {
 // parseUTC: backend Z'siz naive UTC string'leri yerel saate doğru çevirir.
 const d = parseUTC(iso);
 if (!d) return '—';
 const pad = n => String(n).padStart(2, '0');
 return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
 }

 function scoreColor(score) {
 if (score == null) return 'var(--text-dim)';
 if (score >= 70) return 'var(--green)';
 if (score >= 40) return 'var(--amber)';
 return 'var(--red)';
 }

 const SENTIMENT_CFG = {
 positive: { label: 'Pozitif', color: 'var(--green)', emoji: '' },
 neutral: { label: 'Nötr', color: 'var(--amber)', emoji: '' },
 negative: { label: 'Negatif', color: 'var(--red)', emoji: '' },
 };

 const CATEGORIES = ['Satış', 'Şikayet', 'Teknik', 'Genel'];

 const PAGE_SIZE = 20;

 /* 
 STAT CARD
 */
 function StatCard({ icon, label, value, sub, color, bar, barMax }) {
 return (
 <div style={{
 background: 'var(--surface)',
 border: '1px solid var(--border)',
 borderRadius: 14,
 padding: '20px 22px',
 display: 'flex',
 flexDirection: 'column',
 gap: 6,
 minWidth: 0,
 }}>
 <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
 <div style={{
 width: 38, height: 38, borderRadius: 10,
 background: (color || 'var(--blue)') + '18',
 color: color || 'var(--blue)',
 display: 'flex', alignItems: 'center', justifyContent: 'center',
 fontSize: 18, flexShrink: 0,
 }}>{icon}</div>
 <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-dim)', textTransform: 'uppercase', letterSpacing: '.04em' }}>{label}</div>
 </div>
 <div style={{ fontSize: 30, fontWeight: 600, color: color || 'var(--text)', fontFamily: 'var(--mono)', lineHeight: 1.1 }}>{value}</div>
 {sub && <div style={{ fontSize: 13, color: 'var(--text-dim)', fontWeight: 500 }}>{sub}</div>}
 {bar != null && barMax != null && barMax > 0 && (
 <div style={{ height: 6, borderRadius: 3, background: 'var(--surface2)', marginTop: 4, overflow: 'hidden' }}>
 <div style={{
 width: `${Math.min(100, (bar / barMax) * 100)}%`,
 height: '100%',
 borderRadius: 3,
 background: color || 'var(--blue)',
 transition: 'width .5s ease',
 }} />
 </div>
 )}
 </div>
 );
 }

 /* 
 SENTIMENT BAR (inline mini breakdown)
 */
 function SentimentBar({ by_sentiment, total }) {
 if (!by_sentiment || !total) return null;
 const segments = [
 { key: 'positive', color: 'var(--green)' },
 { key: 'neutral', color: 'var(--amber)' },
 { key: 'negative', color: 'var(--red)' },
 ];
 return (
 <div style={{ display: 'flex', borderRadius: 6, overflow: 'hidden', height: 10, gap: 1 }}>
 {segments.map(({ key, color }) => {
 const count = by_sentiment[key] || 0;
 const pct = total > 0 ? (count / total) * 100 : 0;
 if (pct < 0.5) return null;
 return (
 <div key={key} title={`${SENTIMENT_CFG[key].label}: ${count} (${pct.toFixed(1)}%)`} style={{
 width: `${pct}%`, background: color, transition: 'width .5s ease',
 }} />
 );
 })}
 </div>
 );
 }

 /* 
 ANALYSIS DETAIL PANEL (expanded row)
 */
 function AnalysisDetail({ item }) {
 const sc = SENTIMENT_CFG[item.sentiment] || SENTIMENT_CFG.neutral;
 const perf = item.agent_performance || {};
 const perfKeys = ['empathy', 'clarity', 'resolution', 'professionalism'];
 const perfLabels = { empathy: 'Empati', clarity: 'Netlik', resolution: 'Çözüm', professionalism: 'Profesyonellik' };

 return (
 <div style={{
 background: '#0d0f1a',
 border: '1px solid var(--border)',
 borderRadius: 12,
 padding: 20,
 display: 'grid',
 gridTemplateColumns: '1fr 1fr',
 gap: 20,
 }}>
 {/* Sol: Özet + intent + resolution */}
 <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
 {item.summary && (
 <div>
 <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-dim)', textTransform: 'uppercase', marginBottom: 6 }}>Özet</div>
 <div style={{ fontSize: 13, lineHeight: 1.65, color: 'var(--text)' }}>{item.summary}</div>
 </div>
 )}
 {item.customer_intent && (
 <div>
 <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-dim)', textTransform: 'uppercase', marginBottom: 6 }}>Müşteri Niyeti</div>
 <div style={{ fontSize: 13, color: 'var(--text)' }}>{item.customer_intent}</div>
 </div>
 )}
 {item.resolution && (
 <div>
 <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-dim)', textTransform: 'uppercase', marginBottom: 6 }}>Çözüm</div>
 <div style={{ fontSize: 13, color: 'var(--text)' }}>{item.resolution}</div>
 </div>
 )}
 {item.key_topics && item.key_topics.length > 0 && (
 <div>
 <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-dim)', textTransform: 'uppercase', marginBottom: 6 }}>Konular</div>
 <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
 {item.key_topics.map((t, i) => (
 <span key={i} style={{
 fontSize: 12, fontWeight: 600,
 padding: '3px 10px', borderRadius: 6,
 background: 'rgba(59,109,240,.1)', color: 'var(--blue)',
 }}>{t}</span>
 ))}
 </div>
 </div>
 )}
 </div>

 {/* Sağ: Temsilci performansı + duygu skoru */}
 <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
 <div>
 <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-dim)', textTransform: 'uppercase', marginBottom: 10 }}>Duygu Skoru</div>
 <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
 <div style={{
 width: 54, height: 54, borderRadius: '50%',
 border: `3px solid ${scoreColor(item.score)}`,
 display: 'flex', alignItems: 'center', justifyContent: 'center',
 fontSize: 16, fontWeight: 600, color: scoreColor(item.score),
 fontFamily: 'var(--mono)',
 }}>{item.score ?? '—'}</div>
 <div>
 <div style={{ fontSize: 16, fontWeight: 600, color: sc.color }}>{sc.emoji} {sc.label}</div>
 <div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 2 }}>0–100 arası puan</div>
 </div>
 </div>
 </div>

 {Object.keys(perf).length > 0 && (
 <div>
 <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-dim)', textTransform: 'uppercase', marginBottom: 10 }}>Temsilci Performansı</div>
 <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
 {perfKeys.filter(k => perf[k] != null).map(k => {
 const val = Math.min(100, Math.max(0, perf[k]));
 return (
 <div key={k}>
 <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>
 <span style={{ fontSize: 12, fontWeight: 600, color: 'var(--text)' }}>{perfLabels[k] || k}</span>
 <span className="mono" style={{ fontSize: 12, fontWeight: 700, color: scoreColor(val) }}>{val}</span>
 </div>
 <div style={{ height: 5, borderRadius: 3, background: 'var(--surface2)' }}>
 <div style={{
 width: `${val}%`, height: '100%', borderRadius: 3,
 background: scoreColor(val), transition: 'width .5s ease',
 }} />
 </div>
 </div>
 );
 })}
 </div>
 </div>
 )}

 {item.flags && item.flags.length > 0 && (
 <div>
 <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-dim)', textTransform: 'uppercase', marginBottom: 6 }}>Bayraklar</div>
 <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
 {item.flags.map((f, i) => (
 <span key={i} style={{
 fontSize: 12, fontWeight: 600,
 padding: '3px 10px', borderRadius: 6,
 background: 'rgba(239,68,68,.1)', color: 'var(--red)',
 border: '1px solid rgba(239,68,68,.2)',
 }}> {f}</span>
 ))}
 </div>
 </div>
 )}
 </div>
 </div>
 );
 }

 /* 
 KEYWORD ROW
 */
 function KeywordRow({ kw, onDelete }) {
 const [deleting, setDeleting] = useState(false);
 const handleDelete = async () => {
 if (!window.confirm(`"${kw.keyword}" anahtar kelimesini silmek istiyor musunuz?`)) return;
 setDeleting(true);
 try {
 const r = await authFetch(`/api/analysis/keywords/${kw.id}`, { method: 'DELETE' });
 if (r.ok) onDelete(kw.id);
 } finally {
 setDeleting(false);
 }
 };

 return (
 <div style={{
 display: 'flex', alignItems: 'center', gap: 10,
 padding: '8px 12px', borderRadius: 8,
 background: 'var(--surface2)',
 border: '1px solid var(--border)',
 }}>
 <div style={{
 width: 10, height: 10, borderRadius: '50%',
 background: kw.color || '#94a3b8', flexShrink: 0,
 }} />
 <span style={{ fontSize: 13, fontWeight: 700, color: 'var(--text)', flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{kw.keyword}</span>
 <span style={{
 fontSize: 11, fontWeight: 700, padding: '2px 7px', borderRadius: 5,
 background: (kw.color || '#94a3b8') + '18', color: kw.color || 'var(--text-dim)',
 flexShrink: 0,
 }}>{kw.category || 'Genel'}</span>
 <button
 onClick={handleDelete}
 disabled={deleting}
 style={{
 background: 'none', border: 'none', cursor: deleting ? 'not-allowed' : 'pointer',
 color: 'var(--text-dim)', fontSize: 15, lineHeight: 1, padding: '0 2px',
 opacity: deleting ? .4 : 1, transition: 'color .15s', flexShrink: 0,
 }}
 onMouseEnter={e => e.currentTarget.style.color = 'var(--red)'}
 onMouseLeave={e => e.currentTarget.style.color = 'var(--text-dim)'}
 title="Sil"
 ></button>
 </div>
 );
 }

 /* 
 MAIN COMPONENT
 */
 function SpeechAnalyticsTab({ toast }) {
 /* State */
 const [stats, setStats] = useState(null);
 const [statsLoading, setStatsLoading] = useState(true);
 const [keywords, setKeywords] = useState([]);
 const [kwLoading, setKwLoading] = useState(true);

 // Keyword form
 const [newKw, setNewKw] = useState('');
 const [newCat, setNewCat] = useState('Genel');
 const [newCol, setNewCol] = useState('#3b6df0');
 const [kwSaving, setKwSaving] = useState(false);

 // Batch
 const [daysBack, setDaysBack] = useState(7);
 const [batchLoading, setBatchLoading] = useState(false);

 // Table
 const [page, setPage] = useState(0);
 const [expandedId, setExpandedId] = useState(null);

 const timerRef = useRef(null);

 /* Fetch helpers */
 const loadStats = useCallback(async () => {
 setStatsLoading(true);
 try {
 const r = await authFetch('/api/analysis/stats');
 if (r.ok) setStats(await r.json());
 } finally {
 setStatsLoading(false);
 }
 }, []);

 const loadKeywords = useCallback(async () => {
 setKwLoading(true);
 try {
 const r = await authFetch('/api/analysis/keywords');
 if (r.ok) setKeywords(await r.json());
 } finally {
 setKwLoading(false);
 }
 }, []);

 /* Auto-refresh every 30s */
 useEffect(() => {
 loadStats();
 loadKeywords();
 timerRef.current = setInterval(() => { loadStats(); }, 30000);
 return () => clearInterval(timerRef.current);
 }, [loadStats, loadKeywords]);

 /* Keyword add */
 const handleAddKeyword = async () => {
 if (!newKw.trim()) return;
 setKwSaving(true);
 try {
 const r = await authFetch('/api/analysis/keywords', {
 method: 'POST',
 headers: { 'Content-Type': 'application/json' },
 body: JSON.stringify({ keyword: newKw.trim(), category: newCat, color: newCol }),
 });
 if (r.ok) {
 const created = await r.json();
 setKeywords(k => [...k, created]);
 setNewKw('');
 toast && toast('Anahtar kelime eklendi', 'success');
 } else {
 toast && toast('Eklenemedi', 'error');
 }
 } finally {
 setKwSaving(false);
 }
 };

 /* Keyword delete */
 const handleDeleteKeyword = (id) => {
 setKeywords(k => k.filter(x => x.id !== id));
 toast && toast('Anahtar kelime silindi', 'success');
 };

 /* Batch analyze */
 const handleBatchAnalyze = async () => {
 setBatchLoading(true);
 try {
 const r = await authFetch('/api/analysis/analyze-batch', {
 method: 'POST',
 headers: { 'Content-Type': 'application/json' },
 body: JSON.stringify({ days_back: daysBack }),
 });
 if (r.ok) {
 const result = await r.json();
 toast && toast(`Analiz tamamlandı: ${result.analyzed_count ?? result.count ?? '?'} çağrı`, 'success');
 await loadStats();
 } else {
 toast && toast('Analiz başlatılamadı', 'error');
 }
 } finally {
 setBatchLoading(false);
 }
 };

 /* Derived stats */
 const total = stats?.total_analyzed || 0;
 const byS = stats?.by_sentiment || {};
 const posCount = byS.positive || 0;
 const neuCount = byS.neutral || 0;
 const negCount = byS.negative || 0;
 const posPct = total > 0 ? ((posCount / total) * 100).toFixed(1) : '0';
 const neuPct = total > 0 ? ((neuCount / total) * 100).toFixed(1) : '0';
 const negPct = total > 0 ? ((negCount / total) * 100).toFixed(1) : '0';
 const avgScore = stats?.avg_score != null ? Math.round(stats.avg_score) : null;
 const topKw = stats?.top_keywords || [];
 const recentAll = stats?.recent_analyses || [];
 const flaggedCount = stats?.flagged_count || 0;

 /* Pagination */
 const totalPages = Math.ceil(recentAll.length / PAGE_SIZE);
 const pageItems = recentAll.slice(page * PAGE_SIZE, page * PAGE_SIZE + PAGE_SIZE);

 /* Row click */
 const handleRowClick = (id) => {
 setExpandedId(prev => prev === id ? null : id);
 };

 /* RENDER */
 return (
 <div className="fade-in" style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>

 {/* HEADER */}
 <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', flexWrap: 'wrap', gap: 12 }}>
 <div>
 <h2 style={{ fontSize: 24, fontWeight: 600, color: 'var(--text)', margin: 0 }}>Konuşma Analizi</h2>
 <p style={{ fontSize: 14, color: 'var(--text-dim)', marginTop: 6, marginBottom: 0 }}>
 Çağrıların duygu ve içerik analizini görüntüleyin, anahtar kelimeleri yönetin.
 </p>
 </div>
 <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
 <div style={{
 fontSize: 11, fontWeight: 600, color: 'var(--text-dim)',
 display: 'flex', alignItems: 'center', gap: 5,
 }}>
 <span style={{ width: 7, height: 7, borderRadius: '50%', background: statsLoading ? 'var(--amber)' : 'var(--green)', display: 'inline-block' }} />
 {statsLoading ? 'Yükleniyor...' : 'Otomatik güncelleme: 30sn'}
 </div>
 <button
 className="btn outline"
 onClick={() => { loadStats(); loadKeywords(); }}
 disabled={statsLoading}
 style={{ padding: '6px 14px', fontSize: 13 }}
 >↻ Yenile</button>
 </div>
 </div>

 {/* STATS OVERVIEW */}
 <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 16 }}>
 <StatCard
 icon=""
 label="Analiz Edilen"
 value={statsLoading ? '...' : total.toLocaleString('tr-TR')}
 sub="toplam çağrı"
 color="var(--blue)"
 />
 <StatCard
 icon=""
 label="Pozitif"
 value={statsLoading ? '...' : `%${posPct}`}
 sub={`${posCount} çağrı`}
 color="var(--green)"
 bar={posCount}
 barMax={total}
 />
 <StatCard
 icon=""
 label="Nötr"
 value={statsLoading ? '...' : `%${neuPct}`}
 sub={`${neuCount} çağrı`}
 color="var(--amber)"
 bar={neuCount}
 barMax={total}
 />
 <StatCard
 icon=""
 label="Negatif"
 value={statsLoading ? '...' : `%${negPct}`}
 sub={`${negCount} çağrı`}
 color="var(--red)"
 bar={negCount}
 barMax={total}
 />
 <StatCard
 icon=""
 label="Ortalama Puan"
 value={statsLoading ? '...' : (avgScore != null ? avgScore : '—')}
 sub="0–100 arası"
 color={avgScore != null ? scoreColor(avgScore) : 'var(--text-dim)'}
 bar={avgScore}
 barMax={100}
 />
 <StatCard
 icon=""
 label="Bayraklı"
 value={statsLoading ? '...' : flaggedCount}
 sub="dikkat gerektiren"
 color="var(--red)"
 />
 </div>

 {/* SENTIMENT BAR */}
 {!statsLoading && total > 0 && (
 <div style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 14, padding: '16px 22px' }}>
 <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
 <span style={{ fontSize: 13, fontWeight: 700, color: 'var(--text)' }}>Duygu Dağılımı</span>
 <div style={{ display: 'flex', gap: 16 }}>
 {[
 { key: 'positive', color: 'var(--green)', label: 'Pozitif', pct: posPct },
 { key: 'neutral', color: 'var(--amber)', label: 'Nötr', pct: neuPct },
 { key: 'negative', color: 'var(--red)', label: 'Negatif', pct: negPct },
 ].map(({ key, color, label, pct }) => (
 <div key={key} style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
 <div style={{ width: 9, height: 9, borderRadius: '50%', background: color }} />
 <span style={{ fontSize: 12, fontWeight: 600, color: 'var(--text-dim)' }}>{label}</span>
 <span className="mono" style={{ fontSize: 12, fontWeight: 600, color }}>{pct}%</span>
 </div>
 ))}
 </div>
 </div>
 <SentimentBar by_sentiment={byS} total={total} />
 </div>
 )}

 {/* MAIN BODY: Table + Sidebar */}
 <div style={{ display: 'grid', gridTemplateColumns: '1fr 300px', gap: 20, alignItems: 'start' }}>

 {/* LEFT: Batch + Recent Analyses */}
 <div style={{ display: 'flex', flexDirection: 'column', gap: 20, minWidth: 0 }}>

 {/* Batch Analysis */}
 <div style={{
 background: 'var(--surface)', border: '1px solid var(--border)',
 borderRadius: 14, padding: '18px 22px',
 display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap',
 }}>
  <div style={{ flex: 1, minWidth: 160 }}>
 <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--text)' }}>Toplu Analiz</div>
 <div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 2 }}>Seçili gün aralığındaki tüm çağrıları analiz edin</div>
 </div>
 <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
 <span style={{ fontSize: 13, color: 'var(--text-dim)', fontWeight: 600, whiteSpace: 'nowrap' }}>Son</span>
 <input
 type="number"
 min={1} max={90}
 value={daysBack}
 onChange={e => setDaysBack(Math.max(1, Math.min(90, parseInt(e.target.value) || 7)))}
 style={{
 width: 60, padding: '7px 10px', borderRadius: 8,
 background: 'var(--surface2)', border: '1px solid var(--border)',
 color: 'var(--text)', fontSize: 14, fontWeight: 700, fontFamily: 'var(--mono)',
 textAlign: 'center', outline: 'none',
 }}
 />
 <span style={{ fontSize: 13, color: 'var(--text-dim)', fontWeight: 600, whiteSpace: 'nowrap' }}>gün</span>
 </div>
 <button
 className="btn primary"
 onClick={handleBatchAnalyze}
 disabled={batchLoading}
 style={{ minWidth: 140, position: 'relative', overflow: 'hidden' }}
 >
 {batchLoading ? (
 <span style={{ display: 'flex', alignItems: 'center', gap: 8, justifyContent: 'center' }}>
 <span style={{
 width: 14, height: 14, borderRadius: '50%',
 border: '2px solid rgba(255,255,255,.3)',
 borderTopColor: '#fff',
 display: 'inline-block',
 animation: 'spin 0.8s linear infinite',
 }} />
 Analiz ediliyor...
 </span>
 ) : `Son ${daysBack} günü analiz et`}
 </button>
 </div>

 {/* Recent Analyses Table */}
 <div style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 14, overflow: 'hidden' }}>
 {/* Panel header */}
 <div style={{
 display: 'flex', justifyContent: 'space-between', alignItems: 'center',
 padding: '16px 22px', borderBottom: '1px solid var(--border)',
 }}>
 <span style={{ fontSize: 15, fontWeight: 600, color: 'var(--text)' }}>Son Analizler</span>
 <span style={{
 fontSize: 12, fontWeight: 700, padding: '3px 10px', borderRadius: 20,
 background: 'var(--surface2)', color: 'var(--text-dim)',
 }}>{recentAll.length} kayıt</span>
 </div>

 {/* Table */}
 <div style={{ overflowX: 'auto' }}>
 <table style={{ width: '100%', borderCollapse: 'collapse' }}>
 <thead>
 <tr style={{ borderBottom: '1px solid var(--border)' }}>
 {['Tarih', 'Telefon', 'Temsilci', 'Duygu', 'Puan', 'Bayraklar', 'Özet'].map(h => (
 <th key={h} style={{
 padding: '10px 14px', textAlign: 'left',
 fontSize: 11, fontWeight: 700, color: 'var(--text-dim)',
 textTransform: 'uppercase', letterSpacing: '.05em',
 background: 'var(--surface)', whiteSpace: 'nowrap',
 }}>{h}</th>
 ))}
 </tr>
 </thead>
 <tbody>
 {statsLoading ? (
 <tr>
 <td colSpan={7} style={{ padding: '40px 20px', textAlign: 'center', color: 'var(--text-dim)', fontSize: 14 }}>
 Yükleniyor...
 </td>
 </tr>
 ) : pageItems.length === 0 ? (
 <tr>
 <td colSpan={7} style={{ padding: '40px 20px', textAlign: 'center' }}>
  <div style={{ fontSize: 14, color: 'var(--text-dim)', fontWeight: 600 }}>Henüz analiz yapılmamış</div>
 </td>
 </tr>
 ) : (
 pageItems.map((item, idx) => {
 const sc = SENTIMENT_CFG[item.sentiment] || SENTIMENT_CFG.neutral;
 const sc2 = scoreColor(item.score);
 const isExpanded = expandedId === (item.call_id || item.call_uuid || idx);
 const rowId = item.call_id || item.call_uuid || idx;
 return (
 <React.Fragment key={rowId}>
 <tr
 onClick={() => handleRowClick(rowId)}
 style={{
 borderBottom: isExpanded ? 'none' : '1px solid var(--border)',
 cursor: 'pointer',
 background: isExpanded
 ? 'rgba(59,109,240,.04)'
 : (idx % 2 === 0 ? 'transparent' : 'rgba(255,255,255,.01)'),
 transition: 'background .15s',
 }}
 onMouseEnter={e => { if (!isExpanded) e.currentTarget.style.background = 'rgba(255,255,255,.03)'; }}
 onMouseLeave={e => { if (!isExpanded) e.currentTarget.style.background = idx % 2 === 0 ? 'transparent' : 'rgba(255,255,255,.01)'; }}
 >
 {/* Tarih */}
 <td style={{ padding: '11px 14px', fontSize: 12, color: 'var(--text-dim)', fontFamily: 'var(--mono)', whiteSpace: 'nowrap' }}>
 {fmtDate(item.analyzed_at)}
 </td>
 {/* Telefon */}
 <td style={{ padding: '11px 14px' }}>
 <span style={{ fontFamily: 'var(--mono)', fontSize: 13, fontWeight: 700, color: 'var(--text)' }}>
 {item.phone_number || '—'}
 </span>
 </td>
 {/* Temsilci */}
 <td style={{ padding: '11px 14px', fontSize: 13, color: 'var(--text)', fontWeight: 500, maxWidth: 120, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
 {item.agent_name || '—'}
 </td>
 {/* Duygu */}
 <td style={{ padding: '11px 14px' }}>
 <span style={{
 display: 'inline-flex', alignItems: 'center', gap: 5,
 fontSize: 12, fontWeight: 700,
 padding: '3px 9px', borderRadius: 6,
 background: sc.color + '14', color: sc.color,
 whiteSpace: 'nowrap',
 }}>
 {sc.emoji} {sc.label}
 </span>
 </td>
 {/* Puan */}
 <td style={{ padding: '11px 14px' }}>
 {item.score != null ? (
 <span style={{
 fontFamily: 'var(--mono)', fontSize: 14, fontWeight: 600,
 color: sc2,
 }}>{item.score}</span>
 ) : <span style={{ color: 'var(--text-dim)', fontSize: 13 }}>—</span>}
 </td>
 {/* Bayraklar */}
 <td style={{ padding: '11px 14px' }}>
 {item.flags && item.flags.length > 0 ? (
 <span style={{
 fontSize: 11, fontWeight: 700,
 padding: '2px 8px', borderRadius: 5,
 background: 'rgba(239,68,68,.1)', color: 'var(--red)',
 whiteSpace: 'nowrap',
 }}> {item.flags.length}</span>
 ) : (
 <span style={{ color: 'var(--text-dim)', fontSize: 12 }}>—</span>
 )}
 </td>
 {/* Özet */}
 <td style={{ padding: '11px 14px', fontSize: 13, color: 'var(--text-dim)', maxWidth: 220, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
 <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
 {item.summary ? item.summary.substring(0, 80) + (item.summary.length > 80 ? '…' : '') : '—'}
 <span style={{ fontSize: 11, color: 'var(--text-dim)', opacity: .6, flexShrink: 0 }}>
 {isExpanded ? '' : ''}
 </span>
 </span>
 </td>
 </tr>

 {/* Expanded detail row */}
 {isExpanded && (
 <tr style={{ borderBottom: '1px solid var(--border)' }}>
 <td colSpan={7} style={{ padding: '0 14px 14px' }}>
 <AnalysisDetail item={item} />
 </td>
 </tr>
 )}
 </React.Fragment>
 );
 })
 )}
 </tbody>
 </table>
 </div>

 {/* Pagination */}
 {totalPages > 1 && (
 <div style={{
 display: 'flex', justifyContent: 'space-between', alignItems: 'center',
 padding: '12px 22px', borderTop: '1px solid var(--border)',
 }}>
 <span style={{ fontSize: 12, color: 'var(--text-dim)', fontWeight: 500 }}>
 {page * PAGE_SIZE + 1}–{Math.min((page + 1) * PAGE_SIZE, recentAll.length)} / {recentAll.length}
 </span>
 <div style={{ display: 'flex', gap: 4 }}>
 <button
 className="btn-sm"
 onClick={() => setPage(p => Math.max(0, p - 1))}
 disabled={page === 0}
 style={{ padding: '4px 10px' }}
 >← Önceki</button>
 {Array.from({ length: Math.min(totalPages, 5) }, (_, i) => {
 let p;
 if (totalPages <= 5) { p = i; }
 else if (page < 3) { p = i; }
 else if (page > totalPages - 4) { p = totalPages - 5 + i; }
 else { p = page - 2 + i; }
 return (
 <button
 key={p}
 className="btn-sm"
 onClick={() => setPage(p)}
 style={{
 padding: '4px 10px',
 background: page === p ? 'var(--blue)' : undefined,
 color: page === p ? '#fff' : undefined,
 borderColor: page === p ? 'var(--blue)' : undefined,
 }}
 >{p + 1}</button>
 );
 })}
 <button
 className="btn-sm"
 onClick={() => setPage(p => Math.min(totalPages - 1, p + 1))}
 disabled={page === totalPages - 1}
 style={{ padding: '4px 10px' }}
 >Sonraki →</button>
 </div>
 </div>
 )}
 </div>
 </div>

 {/* RIGHT SIDEBAR */}
 <div style={{ display: 'flex', flexDirection: 'column', gap: 16, position: 'sticky', top: 20 }}>

 {/* Top Keywords */}
 {topKw.length > 0 && (
 <div style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 14, overflow: 'hidden' }}>
 <div style={{ padding: '14px 18px', borderBottom: '1px solid var(--border)' }}>
 <span style={{ fontSize: 14, fontWeight: 600, color: 'var(--text)' }}>En Çok Geçen Kelimeler</span>
 </div>
 <div style={{ padding: 12, display: 'flex', flexDirection: 'column', gap: 6 }}>
 {topKw.slice(0, 10).map((kw, i) => {
 const maxCount = topKw[0]?.count || 1;
 const pct = (kw.count / maxCount) * 100;
 return (
 <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
 <div style={{
 width: 7, height: 7, borderRadius: '50%', flexShrink: 0,
 background: kw.color || 'var(--blue)',
 }} />
 <div style={{ flex: 1, minWidth: 0 }}>
 <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 3 }}>
 <span style={{ fontSize: 12, fontWeight: 700, color: 'var(--text)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{kw.keyword}</span>
 <span className="mono" style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-dim)', flexShrink: 0, marginLeft: 4 }}>{kw.count}</span>
 </div>
 <div style={{ height: 4, borderRadius: 2, background: 'var(--surface2)' }}>
 <div style={{
 width: `${pct}%`, height: '100%', borderRadius: 2,
 background: kw.color || 'var(--blue)',
 transition: 'width .5s ease',
 }} />
 </div>
 </div>
 </div>
 );
 })}
 </div>
 </div>
 )}

 {/* Keyword Management */}
 <div style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 14, overflow: 'hidden' }}>
 <div style={{ padding: '14px 18px', borderBottom: '1px solid var(--border)' }}>
 <span style={{ fontSize: 14, fontWeight: 600, color: 'var(--text)' }}>Anahtar Kelimeler</span>
 </div>

 {/* Add form */}
 <div style={{ padding: '14px 16px', borderBottom: '1px solid var(--border)', display: 'flex', flexDirection: 'column', gap: 8 }}>
 <input
 className="form-input"
 placeholder="Yeni kelime ekle..."
 value={newKw}
 onChange={e => setNewKw(e.target.value)}
 onKeyDown={e => { if (e.key === 'Enter') handleAddKeyword(); }}
 style={{ fontSize: 13, padding: '8px 12px' }}
 />
 <div style={{ display: 'flex', gap: 6 }}>
 <select
 className="form-select"
 value={newCat}
 onChange={e => setNewCat(e.target.value)}
 style={{ flex: 1, fontSize: 12, padding: '6px 8px' }}
 >
 {CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}
 </select>
 <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
 <input
 type="color"
 value={newCol}
 onChange={e => setNewCol(e.target.value)}
 style={{ width: 32, height: 32, padding: 2, borderRadius: 6, border: '1px solid var(--border)', cursor: 'pointer', background: 'var(--surface2)' }}
 title="Renk seç"
 />
 </div>
 <button
 className="btn primary"
 onClick={handleAddKeyword}
 disabled={kwSaving || !newKw.trim()}
 style={{ padding: '6px 12px', fontSize: 13, flexShrink: 0 }}
 >{kwSaving ? '...' : '+ Ekle'}</button>
 </div>
 </div>

 {/* Keyword list */}
 <div style={{ padding: 12, maxHeight: 320, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 6 }}>
 {kwLoading ? (
 <div style={{ padding: '20px 0', textAlign: 'center', color: 'var(--text-dim)', fontSize: 13 }}>Yükleniyor...</div>
 ) : keywords.length === 0 ? (
 <div style={{ padding: '20px 0', textAlign: 'center', color: 'var(--text-dim)', fontSize: 13 }}>
  Henüz kelime eklenmemiş
 </div>
 ) : (
 keywords.map(kw => (
 <KeywordRow key={kw.id} kw={kw} onDelete={handleDeleteKeyword} />
 ))
 )}
 </div>

 {keywords.length > 0 && (
 <div style={{ padding: '8px 16px 12px', borderTop: '1px solid var(--border)', fontSize: 11, color: 'var(--text-dim)', textAlign: 'center' }}>
 {keywords.length} kelime aktif
 </div>
 )}
 </div>

 </div>
 </div>

 {/* Spinner keyframe — injected once */}
 <style>{`
 @keyframes spin { to { transform: rotate(360deg); } }
 `}</style>
 </div>
 );
 }

 window.SpeechAnalyticsTab = SpeechAnalyticsTab;
})();
