/* Shared components — PromptOptimizerModal, TrendChart, ReportChat
   Requires api.js to be loaded first. */

const { useState: useStateC, useEffect: useEffectC, useRef: useRefC } = React;

/* ============================================================
   PROMPT OPTIMIZER MODAL
   Props:
     rawPrompt  — string already built from form fields
     onClose    — () => void
     onLaunched — (simId: string) => void   called after simulation started
   ============================================================ */
function PromptOptimizerModal({ rawPrompt, onClose, onLaunched }) {
  const [phase, setPhase] = useStateC('optimizing'); // optimizing | review | launching | error
  const [result, setResult] = useStateC(null);
  const [edited, setEdited] = useStateC('');
  const [err, setErr] = useStateC('');

  useEffectC(() => {
    let live = true;
    window.RICS_API.optimizePrompt(rawPrompt)
      .then((r) => {
        if (!live) return;
        setResult(r);
        setEdited(r.improved);
        setPhase('review');
      })
      .catch((e) => {
        if (!live) return;
        setErr(e.message);
        setPhase('error');
      });
    return () => { live = false; };
  }, [rawPrompt]);

  const handleConfirm = async () => {
    setPhase('launching');
    try {
      // 3-Schritt-Lifecycle: create → prepare → start
      const created  = await window.RICS_API.createSimulation({ prompt: edited });
      const simId    = created.simulation_id || created.simulationId || created.id;
      await window.RICS_API.prepareSimulation({ simulation_id: simId });
      await window.RICS_API.startSimulation({ simulation_id: simId });
      onLaunched(simId);
    } catch (e) {
      setErr(e.message);
      setPhase('error');
    }
  };

  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 300,
      background: 'rgba(10,10,10,0.88)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      padding: 24,
    }}
    onClick={(e) => { if (e.target === e.currentTarget && phase !== 'launching') onClose(); }}
    >
      <div style={{
        background: 'var(--surface-lowest)',
        border: '1px solid var(--ghost-strong)',
        width: '100%', maxWidth: 860,
        maxHeight: '90vh', overflowY: 'auto',
        animation: 'fadeIn 280ms cubic-bezier(.2,.6,.2,1) both',
      }}>
        {/* Header */}
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start',
          padding: '28px 32px 20px', borderBottom: '1px solid var(--ghost)',
        }}>
          <div>
            <div className="mono" style={{ fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--on-surface-dim)', marginBottom: 10 }}>
              Prompt-Optimierung · KI-gestützt
            </div>
            <h2 style={{ margin: 0, fontSize: 22, fontWeight: 500, letterSpacing: '-0.018em', color: 'var(--primary)' }}>
              {phase === 'optimizing' ? 'Prompt wird strukturiert…' :
               phase === 'launching'  ? 'Simulation wird gestartet…' :
               phase === 'error'      ? 'Fehler aufgetreten' :
               'Prompt prüfen und bestätigen'}
            </h2>
          </div>
          {phase !== 'launching' && (
            <button onClick={onClose} style={{
              background: 'none', border: '1px solid var(--ghost-strong)',
              color: 'var(--on-surface-dim)', fontSize: 16, padding: '5px 10px',
              cursor: 'pointer',
            }}>✕</button>
          )}
        </div>

        {/* Body */}
        <div style={{ padding: '28px 32px' }}>
          {/* Loading state */}
          {(phase === 'optimizing' || phase === 'launching') && (
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '56px 0', gap: 24 }}>
              <div style={{
                width: 40, height: 40, border: '2px solid var(--ghost-strong)',
                borderTopColor: 'var(--primary)', borderRadius: '50%',
                animation: 'spin 0.9s linear infinite',
              }} />
              <div className="mono" style={{ fontSize: 12, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--on-surface-dim)' }}>
                {phase === 'optimizing' ? 'GeoStrat-Prompt-Engine · aktiv' : 'Backend-Simulation wird initialisiert…'}
              </div>
            </div>
          )}

          {/* Error state */}
          {phase === 'error' && (
            <div style={{ padding: '32px 0' }}>
              <div className="mono" style={{ fontSize: 11, letterSpacing: '0.1em', textTransform: 'uppercase', color: '#E5B25C', marginBottom: 12 }}>
                Fehler
              </div>
              <p style={{ margin: 0, color: 'var(--on-surface-variant)', fontSize: 14 }}>{err}</p>
              <button className="btn btn-secondary btn-sm" style={{ marginTop: 24 }} onClick={onClose}>
                Schließen
              </button>
            </div>
          )}

          {/* Review state */}
          {phase === 'review' && result && (
            <div>
              {/* Side-by-side comparison */}
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 1, background: 'var(--ghost-strong)', marginBottom: 24 }}>
                <div style={{ background: 'var(--surface)', padding: 22 }}>
                  <div className="label" style={{ marginBottom: 12, color: 'var(--on-surface-dim)' }}>Original</div>
                  <pre style={{
                    margin: 0, fontSize: 12.5, lineHeight: 1.6,
                    fontFamily: 'var(--font-mono)', color: 'var(--on-surface-variant)',
                    whiteSpace: 'pre-wrap', wordBreak: 'break-word',
                  }}>{result.original}</pre>
                </div>
                <div style={{ background: 'var(--surface-low)', padding: 22 }}>
                  <div className="label" style={{ marginBottom: 12 }}>Verbessert · editierbar</div>
                  <textarea
                    value={edited}
                    onChange={(e) => setEdited(e.target.value)}
                    rows={8}
                    style={{
                      width: '100%', boxSizing: 'border-box',
                      background: 'var(--surface)', border: '1px solid var(--ghost-strong)',
                      color: 'var(--on-surface)', fontSize: 12.5,
                      fontFamily: 'var(--font-mono)', lineHeight: 1.6,
                      padding: 12, resize: 'vertical',
                    }}
                  />
                </div>
              </div>

              {/* Changes list */}
              {result.changes && (
                <div style={{ marginBottom: 28 }}>
                  <div className="label" style={{ marginBottom: 12 }}>Verbesserungen</div>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                    {result.changes.split('\n').filter(Boolean).map((line, i) => (
                      <div key={i} className="mono" style={{ fontSize: 12, color: 'var(--on-surface-dim)', lineHeight: 1.5 }}>
                        {line}
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* Action bar */}
              <div style={{
                display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                paddingTop: 22, borderTop: '1px solid var(--ghost)',
              }}>
                <button className="btn btn-tertiary btn-sm" onClick={onClose}>
                  Zurück zum Formular
                </button>
                <button className="btn btn-primary" onClick={handleConfirm} disabled={!edited.trim()}>
                  Bericht anfordern — Simulation starten <span className="arrow">→</span>
                </button>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}


/* ============================================================
   TREND CHART
   Props:
     simId      (string)           — fetches own data if snapshotData not provided
     snapshotData (object, optional) — pre-fetched snapshot; skips internal fetch
   Renders two tabs: Szenarien-Wahrscheinlichkeiten | Portfolio-Gewichtungen
   ============================================================ */
function TrendChart({ simId, snapshotData }) {
  const [fetched, setFetched] = useStateC(null);
  const [tab, setTab] = useStateC('prob');
  const [loading, setLoading] = useStateC(!snapshotData);
  const [err, setErr] = useStateC('');

  useEffectC(() => {
    // If parent already fetched the snapshot, skip the request
    if (snapshotData !== undefined) { setLoading(false); return; }
    if (!simId) return;
    setLoading(true);
    window.RICS_API.getSnapshot(simId)
      .then((d) => { setFetched(d); setLoading(false); })
      .catch((e) => { setErr(e.message); setLoading(false); });
  }, [simId, snapshotData]);

  const data = snapshotData !== undefined ? snapshotData : fetched;
  const chartData = tab === 'prob' ? data?.probability_history : data?.weight_history;

  if (loading) {
    return (
      <div style={{ padding: '32px 0', textAlign: 'center' }}>
        <div className="mono" style={{ fontSize: 11, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--on-surface-dim)' }}>
          Verlaufsdaten werden geladen…
        </div>
      </div>
    );
  }

  if (err || !chartData || Object.keys(chartData).length === 0) {
    return (
      <div style={{ padding: '28px 0' }}>
        <div className="mono" style={{ fontSize: 11, letterSpacing: '0.1em', textTransform: 'uppercase', color: 'var(--on-surface-quiet)' }}>
          Verlaufsdaten noch nicht verfügbar
        </div>
        <div style={{ fontSize: 13, color: 'var(--on-surface-dim)', marginTop: 8, lineHeight: 1.55 }}>
          Zeitreihen erscheinen nach dem nächsten automatischen Agent-Run (täglich 00:00 + 12:00 UTC).
        </div>
      </div>
    );
  }

  return (
    <div>
      {/* Tab switcher */}
      <div style={{ display: 'flex', gap: 1, background: 'var(--ghost-strong)', marginBottom: 20, width: 'fit-content' }}>
        {[['prob', 'Szenarien · P(%)'], ['weight', 'Portfolio · Gewichtung']].map(([k, label]) => (
          <button key={k} onClick={() => setTab(k)} style={{
            padding: '8px 16px', fontSize: 12,
            fontFamily: 'var(--font-mono)', letterSpacing: '0.06em',
            background: tab === k ? 'var(--surface-high)' : 'var(--surface-lowest)',
            color: tab === k ? 'var(--on-surface)' : 'var(--on-surface-dim)',
            border: 0, cursor: 'pointer',
          }}>{label}</button>
        ))}
      </div>

      <SvgLineChart series={chartData} valueKey={tab === 'prob' ? 'probability' : 'weight'} />
    </div>
  );
}

function SvgLineChart({ series, valueKey }) {
  const W = 800, H = 220, PAD = { top: 12, right: 16, bottom: 36, left: 40 };
  const plotW = W - PAD.left - PAD.right;
  const plotH = H - PAD.top - PAD.bottom;

  // Collect all points
  const allPoints = Object.values(series).flatMap((s) => s.points || []);
  if (allPoints.length === 0) return null;

  const times = allPoints.map((p) => new Date(p.timestamp).getTime());
  const vals  = allPoints.map((p) => p[valueKey] ?? 0);
  const tMin = Math.min(...times), tMax = Math.max(...times);
  const vMin = 0, vMax = Math.max(...vals, 1);

  const tx = (t) => PAD.left + ((new Date(t).getTime() - tMin) / Math.max(tMax - tMin, 1)) * plotW;
  const ty = (v) => PAD.top + (1 - (v - vMin) / (vMax - vMin)) * plotH;

  const COLORS = ['#FFFFFF', '#C6C6C6', '#8A8887', '#5E5C5B', '#E5E2E1', '#9B9897', '#6E6C6B', '#3F3D3C'];

  const seriesKeys = Object.keys(series);

  // X-axis tick positions (up to 5 ticks)
  const tickCount = Math.min(5, allPoints.length);
  const xTicks = Array.from({ length: tickCount }, (_, i) => {
    const t = tMin + (i / Math.max(tickCount - 1, 1)) * (tMax - tMin);
    return { t, label: new Date(t).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' }) };
  });

  return (
    <div>
      <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', display: 'block', maxHeight: 240 }}>
        {/* Y gridlines */}
        {[0.25, 0.5, 0.75, 1].map((frac) => {
          const yy = PAD.top + (1 - frac) * plotH;
          return (
            <React.Fragment key={frac}>
              <line x1={PAD.left} x2={PAD.left + plotW} y1={yy} y2={yy}
                stroke="rgba(255,255,255,0.06)" strokeDasharray="2 6" />
              <text x={PAD.left - 6} y={yy + 4} textAnchor="end"
                fontFamily="JetBrains Mono, monospace" fontSize="9"
                fill="var(--on-surface-quiet)">
                {Math.round(frac * vMax * 100)}
              </text>
            </React.Fragment>
          );
        })}

        {/* X axis ticks */}
        {xTicks.map(({ t, label }) => (
          <text key={t} x={tx(t)} y={H - 6} textAnchor="middle"
            fontFamily="JetBrains Mono, monospace" fontSize="9"
            fill="var(--on-surface-quiet)">{label}</text>
        ))}

        {/* Data lines */}
        {seriesKeys.map((key, i) => {
          const pts = (series[key].points || []).map((p) => `${tx(p.timestamp)},${ty(p[valueKey] ?? 0)}`);
          if (pts.length < 2) return null;
          return (
            <polyline key={key}
              points={pts.join(' ')}
              fill="none"
              stroke={COLORS[i % COLORS.length]}
              strokeWidth="1.5"
              strokeOpacity="0.9"
            />
          );
        })}
      </svg>

      {/* Legend */}
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px 20px', marginTop: 12 }}>
        {seriesKeys.map((key, i) => (
          <div key={key} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <div style={{ width: 20, height: 2, background: COLORS[i % COLORS.length] }} />
            <span className="mono" style={{ fontSize: 11, color: 'var(--on-surface-dim)', letterSpacing: '0.04em' }}>
              {series[key].label || key}
            </span>
          </div>
        ))}
      </div>
    </div>
  );
}


/* ============================================================
   REPORT CHAT
   Props: simId (string)
   ============================================================ */
function ReportChat({ simId }) {
  const [messages, setMessages] = useStateC([]);
  const [input, setInput] = useStateC('');
  const [thinking, setThinking] = useStateC(false);
  const bottomRef = useRefC(null);

  const SUGGESTIONS = [
    'Erkläre das dominante Szenario.',
    'Welche Risiken bestehen?',
    'Welche Portfolio-Tilts empfiehlst du?',
    'Was sind die wichtigsten Trigger-Events?',
  ];

  useEffectC(() => {
    if (bottomRef.current) bottomRef.current.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  const send = async (text) => {
    if (!text.trim() || thinking) return;
    const userMsg = { role: 'user', content: text };
    setMessages((prev) => [...prev, userMsg]);
    setInput('');
    setThinking(true);

    const history = messages.slice(-10); // last 10 turns
    try {
      const res = await window.RICS_API.chatWithReport(simId, text, history);
      setMessages((prev) => [...prev, { role: 'assistant', content: res.response }]);
    } catch (e) {
      setMessages((prev) => [...prev, { role: 'assistant', content: `Fehler: ${e.message}` }]);
    } finally {
      setThinking(false);
    }
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', minHeight: 380 }}>
      {/* Header */}
      <div style={{ padding: '14px 20px', borderBottom: '1px solid var(--ghost)', flexShrink: 0 }}>
        <div className="label">Report-Agent</div>
        <div style={{ fontSize: 13, color: 'var(--on-surface-dim)', marginTop: 4 }}>
          Fragen zu diesem Report · Kontext vollständig bekannt
        </div>
      </div>

      {/* Messages */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '16px 20px', display: 'flex', flexDirection: 'column', gap: 14 }}>
        {messages.length === 0 && (
          <div>
            <div className="mono" style={{ fontSize: 11, letterSpacing: '0.1em', textTransform: 'uppercase', color: 'var(--on-surface-quiet)', marginBottom: 14 }}>
              Vorschläge
            </div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
              {SUGGESTIONS.map((s) => (
                <button key={s} onClick={() => send(s)} style={{
                  padding: '8px 14px', fontSize: 12, fontFamily: 'inherit',
                  background: 'var(--surface-low)', border: '1px solid var(--ghost-strong)',
                  color: 'var(--on-surface-variant)', cursor: 'pointer', textAlign: 'left',
                  transition: 'border-color 140ms ease, color 140ms ease',
                }}>
                  {s}
                </button>
              ))}
            </div>
          </div>
        )}

        {messages.map((m, i) => (
          <div key={i} style={{
            display: 'flex',
            justifyContent: m.role === 'user' ? 'flex-end' : 'flex-start',
          }}>
            <div style={{
              maxWidth: '80%', padding: '10px 14px',
              background: m.role === 'user' ? 'var(--surface-high)' : 'var(--surface-low)',
              fontSize: 13.5, lineHeight: 1.6, color: 'var(--on-surface)',
              border: '1px solid var(--ghost)',
            }}>
              {m.content}
            </div>
          </div>
        ))}

        {thinking && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, color: 'var(--on-surface-dim)' }}>
            <div style={{
              width: 14, height: 14, border: '1.5px solid var(--ghost-strong)',
              borderTopColor: 'var(--on-surface-dim)', borderRadius: '50%',
              animation: 'spin 0.9s linear infinite', flexShrink: 0,
            }} />
            <span className="mono" style={{ fontSize: 11, letterSpacing: '0.08em' }}>Agent denkt…</span>
          </div>
        )}
        <div ref={bottomRef} />
      </div>

      {/* Input */}
      <div style={{
        flexShrink: 0, padding: '12px 16px', borderTop: '1px solid var(--ghost)',
        display: 'flex', gap: 8,
      }}>
        <input
          className="input"
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={(e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(input); } }}
          placeholder="Frage stellen…"
          disabled={thinking}
          style={{ flex: 1, fontSize: 13 }}
        />
        <button
          className="btn btn-primary btn-sm"
          onClick={() => send(input)}
          disabled={!input.trim() || thinking}
        >
          Senden →
        </button>
      </div>
    </div>
  );
}

Object.assign(window, { PromptOptimizerModal, TrendChart, ReportChat });
