// Apex — Race Engineer AI copilot panel
// Uses window.claude.complete for live AI moments. Falls back to canned cards.

const { useState: useStateE, useEffect: useEffectE, useRef: useRefE } = React;

function StrategyCard({ card, isLive = false }) {
  const sev = card.severity || "advisory";
  return (
    <div className={`ax-strat ax-strat-${sev}`}>
      <div className="ax-strat-hd">
        <div className="ax-strat-meta">
          <span className={`ax-strat-sev sev-${sev}`}>{sev.toUpperCase()}</span>
          <span className="ax-strat-driver mono">CAR 16 · LEC</span>
          {isLive && <span className="ax-strat-live"><span className="ax-strat-live-dot"></span>GRANITE</span>}
        </div>
        <div className="ax-strat-conf mono">{Math.round((card.confidence || 0.8) * 100)}%</div>
      </div>

      <h3 className="ax-strat-headline">{card.headline}</h3>

      <div className="ax-strat-call">
        <span className="ax-strat-call-label">CALL</span>
        <span className="ax-strat-call-value mono">{card.call}</span>
      </div>

      <ul className="ax-strat-reasons">
        {(card.reasoning || []).map((r, i) => (
          <li key={i}>
            <span className="ax-strat-r-label">{r.label}</span>
            <span className="ax-strat-r-value">{r.value}</span>
          </li>
        ))}
      </ul>

      {card.risk && (
        <div className="ax-strat-risk">
          <span className="ax-strat-risk-label">RISK</span>
          <span>{card.risk}</span>
        </div>
      )}
    </div>
  );
}

function ThinkingTrace({ steps }) {
  return (
    <div className="ax-think">
      {steps.map((s, i) => (
        <div key={i} className={`ax-think-step ${s.done ? "done" : "pending"}`}>
          <span className="ax-think-dot"></span>
          <span className="ax-think-text">{s.text}</span>
        </div>
      ))}
    </div>
  );
}

function EngineerPanel({ scenario, focusDriver, onScenarioChange }) {
  const [messages, setMessages] = useStateE([
    {
      kind: "engineer",
      content: STRATEGY_CARDS.default,
      lap: 32,
      time: "14:53:02",
    },
  ]);
  const [input, setInput] = useStateE("");
  const [thinking, setThinking] = useStateE(null);
  const [liveCard, setLiveCard] = useStateE(null);
  const scrollRef = useRefE(null);

  // When scenario changes, push the corresponding card
  useEffectE(() => {
    if (scenario === "default") return;
    const card = STRATEGY_CARDS[scenario];
    if (!card) return;
    runStrategyThink(card);
  }, [scenario]);

  useEffectE(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [messages, thinking, liveCard]);

  function runStrategyThink(targetCard) {
    const steps = [
      { text: "Ingesting telemetry snapshot · 32 laps · 10 cars", done: false },
      { text: "Computing tire-deg regression vs reference compound", done: false },
      { text: "Solving undercut/overcut delta (pit-loss = 22.4s)", done: false },
      { text: "Cross-checking weather forecast · 20-lap horizon", done: false },
      { text: "Drafting structured recommendation", done: false },
    ];
    setThinking(steps);
    let i = 0;
    const interval = setInterval(() => {
      i++;
      setThinking(prev => prev?.map((s, idx) => idx < i ? { ...s, done: true } : s));
      if (i >= steps.length) {
        clearInterval(interval);
        setTimeout(() => {
          setThinking(null);
          setMessages(prev => [...prev, {
            kind: "engineer",
            content: targetCard,
            lap: 32,
            time: nowStamp(),
          }]);
        }, 380);
      }
    }, 320);
  }

  async function send(text) {
    if (!text.trim()) return;
    setInput("");
    setMessages(prev => [...prev, { kind: "user", text, time: nowStamp() }]);

    // Quick-prompt shortcuts to canned scenarios
    const t = text.toLowerCase();
    if (t.includes("undercut") || t.includes("box now") || t.includes("pit now")) {
      runStrategyThink(STRATEGY_CARDS.undercut);
      onScenarioChange?.("undercut");
      return;
    }
    if (t.includes("rain") || t.includes("weather")) {
      runStrategyThink(STRATEGY_CARDS.rain);
      onScenarioChange?.("rain");
      return;
    }
    if (t.includes("safety") || t.includes("vsc")) {
      runStrategyThink(STRATEGY_CARDS.safety);
      onScenarioChange?.("safety");
      return;
    }

    // Live Granite call
    setThinking([
      { text: "Building telemetry snapshot for Granite", done: false },
      { text: "Calling ibm-granite/granite-4.0-h-small", done: false },
      { text: "Parsing structured output", done: false },
    ]);

    try {
      const snapshot = buildSnapshot();
      const prompt = `You are APEX, an F1 race-engineer strategy copilot. Speak like a senior strategist on the pit wall — calm, technical, decisive. Use F1 vocabulary (undercut, overcut, delta, stint, cliff, pit window).

Race state snapshot (JSON):
${JSON.stringify(snapshot, null, 2)}

Engineer asks: "${text}"

Respond ONLY with a JSON object matching this schema (no markdown, no prose outside JSON):
{
  "severity": "advisory" | "action" | "critical",
  "headline": "one sentence, <80 chars, decisive",
  "call": "STAY OUT" | "BOX BOX" | "HOLD" | "PUSH" | "LIFT & COAST" | other short imperative",
  "confidence": 0.0-1.0,
  "reasoning": [{ "label": "short label", "value": "specific numeric reasoning" }, ... 3-4 items],
  "risk": "one sentence on the failure mode"
}`;

      // step through visual thinking
      setTimeout(() => setThinking(prev => prev?.map((s, i) => i < 1 ? { ...s, done: true } : s)), 240);
      setTimeout(() => setThinking(prev => prev?.map((s, i) => i < 2 ? { ...s, done: true } : s)), 700);

      const raw = await window.claude.complete(prompt);
      const card = parseGraniteJson(raw);

      setThinking(prev => prev?.map(s => ({ ...s, done: true })));
      setTimeout(() => {
        setThinking(null);
        setMessages(prev => [...prev, {
          kind: "engineer",
          content: card,
          lap: 32,
          time: nowStamp(),
          live: true,
        }]);
      }, 240);
    } catch (err) {
      setThinking(null);
      setMessages(prev => [...prev, {
        kind: "engineer",
        content: {
          ...STRATEGY_CARDS.default,
          headline: "Falling back to local strategy model. " + STRATEGY_CARDS.default.headline,
        },
        lap: 32,
        time: nowStamp(),
      }]);
    }
  }

  function buildSnapshot() {
    return {
      event: RACE_META.event,
      lap: RACE_META.currentLap,
      totalLaps: RACE_META.totalLaps,
      weather: { airTempC: RACE_META.airTempC, trackTempC: RACE_META.trackTempC, rainPct: RACE_META.rainChance },
      driver: {
        code: focusDriver,
        ...STATE[focusDriver],
        degPerLap: degAt(STATE[focusDriver].compound, STATE[focusDriver].tireAge) -
                    degAt(STATE[focusDriver].compound, STATE[focusDriver].tireAge - 1),
      },
      threats: ORDER.slice(0, 4).filter(c => c !== focusDriver).map(c => ({
        code: c, gap: STATE[c].gap, compound: STATE[c].compound, tireAge: STATE[c].tireAge,
      })),
      pitWindow: PIT_WINDOW,
      pitLossSeconds: PIT_LOSS_S,
    };
  }

  const quickPrompts = [
    "Pit now?",
    "Undercut risk?",
    "Tire cliff ETA?",
    "Rain impact?",
    "VSC strategy",
    "Fuel saving?",
    "Best post-L40 compound?",
    "Compare LEC vs VER",
  ];

  return (
    <aside className="ax-engineer">
      <header className="ax-engineer-hd">
        <div className="ax-engineer-title">
          <div className="ax-engineer-mark">
            <ApexChevron size={14} color="#FFB020" />
          </div>
          <div>
            <div className="ax-engineer-name">APEX · Race Engineer</div>
            <div className="ax-engineer-sub mono">granite-4.0-h-small · session live</div>
          </div>
        </div>
        <div className="ax-engineer-status">
          <span className="ax-engineer-status-dot"></span>
          <span className="mono">CONNECTED</span>
        </div>
      </header>

      <div className="ax-engineer-feed" ref={scrollRef}>
        {messages.map((m, i) => {
          if (m.kind === "user") {
            return (
              <div key={i} className="ax-msg-user">
                <div className="ax-msg-meta mono">L{m.lap || RACE_META.currentLap} · {m.time} · STRATEGY ENG.</div>
                <div className="ax-msg-user-bubble">{m.text}</div>
              </div>
            );
          }
          return (
            <div key={i} className="ax-msg-eng">
              <div className="ax-msg-meta mono">L{m.lap} · {m.time}</div>
              <StrategyCard card={m.content} isLive={m.live} />
            </div>
          );
        })}
        {thinking && (
          <div className="ax-msg-eng">
            <div className="ax-msg-meta mono">L{RACE_META.currentLap} · THINKING</div>
            <ThinkingTrace steps={thinking} />
          </div>
        )}
      </div>

      <div className="ax-engineer-quick">
        {quickPrompts.map(p => (
          <button key={p} className="ax-chip" onClick={() => send(p)}>{p}</button>
        ))}
      </div>

      <form className="ax-engineer-input" onSubmit={(e) => { e.preventDefault(); send(input); }}>
        <input
          type="text"
          value={input}
          placeholder="Ask the engineer…"
          onChange={(e) => setInput(e.target.value)}
        />
        <button type="submit" className="ax-engineer-send">
          <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
            <path d="M2 7 L12 7 M8 3 L12 7 L8 11" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
        </button>
      </form>
    </aside>
  );
}

function parseGraniteJson(raw) {
  try {
    // Extract JSON object from a possibly-noisy response
    const m = raw.match(/\{[\s\S]*\}/);
    if (!m) throw new Error("no json");
    const obj = JSON.parse(m[0]);
    // Validate shape
    if (!obj.headline || !obj.call) throw new Error("bad shape");
    if (!Array.isArray(obj.reasoning)) obj.reasoning = [];
    return obj;
  } catch (e) {
    return STRATEGY_CARDS.default;
  }
}

function nowStamp() {
  const d = new Date();
  return `${String(d.getHours()).padStart(2,"0")}:${String(d.getMinutes()).padStart(2,"0")}:${String(d.getSeconds()).padStart(2,"0")}`;
}

// Apex chevron logo mark
function ApexChevron({ size = 16, color = "#FAFAFA" }) {
  return (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none">
      <path d="M2 12 L8 3 L14 12" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
      <path d="M5.5 12 L8 8 L10.5 12" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

Object.assign(window, { EngineerPanel, StrategyCard, ThinkingTrace, ApexChevron });
