/* global React, Panel, BarChart, fmtEur, fmtEurM, fmtN, fmtPct, fmtSignPct, renderBriefingMd */ /* Senaryo Simülasyonu (C3) — NL "ya olursa" → Claude param çıkarımı → deterministik OR sim. */ const ScnDelta = ({ label, value, pct, sub, neg }) => { const isNeg = neg || (typeof value === 'string' && (value.startsWith('-') || value.startsWith('−'))); return React.createElement('div', { className: 'kpi' }, React.createElement('div', { className: 'kpi-label' }, label), React.createElement('div', { className: 'kpi-value', style: { color: isNeg ? 'var(--neg)' : 'var(--ink)' } }, value), React.createElement('div', { className: 'kpi-sub' }, pct != null ? React.createElement('span', { className: 'mono ' + (pct >= 0 ? 'text-pos' : 'text-neg') }, fmtSignPct(pct)) : null, sub ? React.createElement('span', { style: { marginLeft: pct != null ? 6 : 0 } }, sub) : null)); }; const Scenario = () => { const [q, setQ] = useState(''); const [reply, setReply] = useState(''); const [result, setResult] = useState(null); const [loading, setLoading] = useState(false); const [err, setErr] = useState(null); const examples = [ 'Belek 5★ otellerde fiyatları %6 artırırsak yaz gelirine etkisi ne olur?', 'Moskova pazarında talep %10 düşerse sezon boyunca ne kaybederiz?', 'Antalya bölgesinde rakipler Temmuz fiyatlarını %8 düşürürse bize etkisi ne?', 'Bodrum 5★ kontenjanını %15 artırıp fiyatı %3 düşürürsek ağustos doluluğu ve geliri nasıl değişir?', ]; const run = async (text) => { if (!text.trim() || loading) return; setLoading(true); setErr(null); setReply(''); setResult(null); try { const base = (typeof window !== 'undefined' && window.API_BASE_URL) || ''; const res = await fetch(base + '/api/scenario', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ messages: [{ role: 'user', content: text }] }) }); if (!res.ok) throw new Error('HTTP ' + res.status); const data = await res.json(); if (data.configured === false) { setErr('demo'); return; } setReply(data.reply || ''); setResult(data.result || null); } catch (e) { setErr('demo'); } finally { setLoading(false); } }; const r = result, d = r && r.delta, b = r && r.baseline, s = r && r.scenario, a = r && r.assumptions; const kpiStrip = (r && !r.error) ? React.createElement('div', { className: 'grid grid-4 gap-3', style: { marginBottom: 14 } }, React.createElement(ScnDelta, { label: 'Δ Gelir', value: (d.revenue_eur >= 0 ? '+' : '−') + fmtEurM(Math.abs(d.revenue_eur)), pct: d.revenue_pct, sub: r.scope_label }), React.createElement(ScnDelta, { label: 'Δ Yolcu', value: (d.pax >= 0 ? '+' : '−') + fmtN(Math.abs(d.pax)), sub: (r.horizon && r.horizon.label) || '', neg: d.pax < 0 }), React.createElement(ScnDelta, { label: 'Δ Doluluk', value: fmtSignPct(d.occupancy_pts) + ' puan', sub: (b ? '%' + b.occupancy_pct : '') + ' → ' + (s ? '%' + s.occupancy_pct : ''), neg: d.occupancy_pts < 0 }), React.createElement(ScnDelta, { label: 'Δ Marj', value: (d.margin_eur >= 0 ? '+' : '−') + fmtEurM(Math.abs(d.margin_eur)), sub: s && s.spilled_pax ? fmtN(s.spilled_pax) + ' spill pax' : 'brüt marj', neg: d.margin_eur < 0 })) : null; const monthChart = (r && r.by_month && r.by_month.length > 1) ? React.createElement(Panel, { title: 'Aylık Gelir · Baz vs Senaryo', sub: '€ milyon · ' + (r.horizon ? r.horizon.label : '') }, React.createElement(BarChart, { data: r.by_month, height: 230, valueKey: 'base_rev_M', secondaryKey: 'scn_rev_M', labelKey: 'ay', format: v => '€' + v.toFixed(0) + 'M', color: 'color-mix(in srgb, var(--text-dim) 40%, transparent)', secondaryColor: 'var(--brand)', valueLabel: false })) : null; const segTable = (r && r.by_segment && r.by_segment.length) ? React.createElement(Panel, { title: 'En çok etkilenen', sub: 'Δ gelir (€M)', flush: true }, React.createElement('div', { style: { maxHeight: 420, overflowY: 'auto' } }, React.createElement('table', { className: 'tbl tbl-zebra' }, React.createElement('thead', null, React.createElement('tr', null, ['Segment', 'Baz', 'Senaryo', 'Δ Gelir', 'Δ Pax'].map((h, i) => React.createElement('th', { key: i, className: i ? 'num' : '' }, h)))), React.createElement('tbody', null, r.by_segment.map((x, i) => React.createElement('tr', { key: i }, React.createElement('td', { style: { fontWeight: 500 } }, x.segment), React.createElement('td', { className: 'num mono text-muted' }, '€' + x.base_rev_M + 'M'), React.createElement('td', { className: 'num mono' }, '€' + x.scn_rev_M + 'M'), React.createElement('td', { className: 'num mono ' + (x.d_rev_M >= 0 ? 'text-pos' : 'text-neg') }, (x.d_rev_M >= 0 ? '+' : '') + x.d_rev_M + 'M'), React.createElement('td', { className: 'num mono text-muted' }, fmtN(x.d_pax)))))))) : null; const readout = React.createElement(Panel, { title: 'Analist okuması', sub: 'Anthropic Claude · OR simülatörü üzerinde' }, React.createElement('div', { className: 'brf-paper', style: { background: 'transparent', border: 'none', padding: '2px 0' } }, renderBriefingMd(reply)), a ? React.createElement('div', { style: { marginTop: 10, paddingTop: 10, borderTop: '1px solid var(--rule-dim)', fontSize: 10.5, color: 'var(--text-muted)', fontFamily: 'var(--mono)' } }, `varsayım · fiyat ${fmtSignPct(a.our_price_change_pct)} · rakip ${fmtSignPct(a.competitor_price_change_pct)} · talep ${fmtSignPct(a.demand_shock_pct)} · kontenjan ${fmtSignPct(a.capacity_change_pct)} · esneklik: ${a.elasticity_model}`) : null); let body; if (loading) { body = React.createElement('div', { className: 'insight-loading', style: { padding: 30, justifyContent: 'center' } }, React.createElement('span', { className: 'insight-shimmer' }), 'soru ayrıştırılıyor ve ağ simülasyonu çalıştırılıyor…'); } else if (err === 'demo') { body = React.createElement('div', { className: 'insight-demo', style: { padding: 24 } }, 'Senaryo simülatörü canlı veri ambarına bağlandığında çalışır. (Demo modu — Copilot servisi şu anda kapalı.)'); } else if (r && r.error) { body = React.createElement('div', { className: 'text-neg', style: { padding: 16 } }, r.error); } else if (r) { body = React.createElement('div', { style: { marginTop: 16 } }, kpiStrip, React.createElement('div', { className: 'grid gap-3', style: { gridTemplateColumns: segTable ? '1.45fr 1fr' : '1fr', alignItems: 'start' } }, React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 12 } }, readout, monthChart), segTable)); } else { body = React.createElement('div', { style: { padding: 44, textAlign: 'center', color: 'var(--text-faint)', fontFamily: 'var(--serif)', fontSize: 18, fontStyle: 'italic' } }, 'Yukarıya bir "ya olursa" yaz veya bir örnek seç — nicel senaryo saniyeler içinde çalışır.'); } return React.createElement('div', { style: { padding: 16, display: 'flex', flexDirection: 'column', gap: 14 } }, React.createElement('div', null, React.createElement('div', { className: 'eyebrow', style: { marginBottom: 6 } }, 'Senaryo Simülasyonu · C3'), React.createElement('h1', { className: 'headline', style: { fontSize: 40, margin: 0 } }, 'Sade Türkçe bir ', React.createElement('em', { style: { fontStyle: 'italic' } }, 'ya olursa'), ' sor.'), React.createElement('div', { style: { fontSize: 13.5, color: 'var(--text-dim)', marginTop: 6, maxWidth: 760, lineHeight: 1.5 } }, 'Copilot sorunu simülasyon parametrelerine çevirir; deterministik bir talep modeli (fiyat esnekliği, rakip çapraz-fiyat, kontenjan/spill) nicel cevabı saniyeler içinde döndürür.')), React.createElement(Panel, null, React.createElement('div', { className: 'row gap-2', style: { marginBottom: 10 } }, React.createElement('input', { className: 'input', style: { flex: 1, height: 40, fontSize: 13.5 }, placeholder: 'ör. Belek 5★ fiyatları %6 artırırsak yaz gelirine etkisi ne olur?', value: q, onChange: e => setQ(e.target.value), onKeyDown: e => e.key === 'Enter' && run(q), disabled: loading }), React.createElement('button', { className: 'btn btn-primary', style: { height: 40, paddingLeft: 18, paddingRight: 18 }, onClick: () => run(q), disabled: loading }, loading ? 'Simüle ediliyor…' : 'Senaryo çalıştır')), React.createElement('div', { className: 'filterbar', style: { border: 'none', padding: 0, gap: 6, flexWrap: 'wrap' } }, examples.map((x, i) => React.createElement('div', { key: i, className: 'filter-chip', onClick: () => { setQ(x); run(x); } }, x.length > 60 ? x.slice(0, 58) + '…' : x)))), body); }; window.Scenario = Scenario;