/* global React */
// triage-chat.jsx — React chat component for the CentralReach triage demo.
//
// Mounts to #triage-chat-root in chat.html.
// Talks to /api/triage-chat which runs an Anthropic tool-use loop.
// Visible tool-call badges so interviewer can see which tools the bot chose.

const { useState, useRef, useEffect } = React;

const STARTERS = [
  "What deals are at risk this week?",
  "Tell me about Acme ABA Clinic",
  "Run a triage on Beacon Behavioral Health",
  "Show me the dashboard",
];

const FALLBACKS = {
  default: "Live mode's offline right now. The 3 working demos (CLI, HTTP API, Salesforce LWC) are documented at github.com/mikecutillo/centralreach-bot-demo.",
  risk: "Without a live LLM, I can't dynamically triage. The static dashboard at /dashboard.html shows the pre-computed at-risk opps across 30 synthetic ABA-clinic accounts.",
  account: "I can't fetch account data right now. The fixtures live in tests/fixtures.py on GitHub — the 5 hand-crafted patterns are Acme (at-risk renewal), Beacon (healthy upgrade), Cedar (active negotiation), Foothills (stale), Daybreak (mixed).",
  dashboard: "Dashboard at /dashboard.html — 30 accounts, revenue-at-risk by industry, risk-level × stage heatmap, top-10 actionable list. Same data the triage bot generated.",
};

function pickFallback(text) {
  const t = text.toLowerCase();
  if (t.includes("risk") || t.includes("deal") || t.includes("opp") || t.includes("churn")) return FALLBACKS.risk;
  if (t.includes("account") || t.includes("acme") || t.includes("beacon") || t.includes("cedar") || t.includes("foothills") || t.includes("daybreak")) return FALLBACKS.account;
  if (t.includes("dashboard") || t.includes("visual") || t.includes("chart") || t.includes("tableau")) return FALLBACKS.dashboard;
  return FALLBACKS.default;
}

function ToolBadge({ name }) {
  const label = ({
    list_at_risk_opps: "list_at_risk_opps",
    read_account_graph: "read_account_graph",
    run_triage: "run_triage",
    show_dashboard: "show_dashboard",
  }[name]) || name;
  return (
    <span style={{
      display: "inline-flex",
      alignItems: "center",
      gap: 6,
      padding: "2px 8px",
      marginRight: 6,
      marginBottom: 4,
      fontSize: 11,
      fontFamily: "var(--font-mono)",
      letterSpacing: "0.04em",
      background: "var(--paper-2)",
      color: "var(--ink-3)",
      border: "1px solid var(--ink-5)",
      borderRadius: 2,
    }}>
      <span style={{ opacity: 0.6 }}>tool:</span>{label}
    </span>
  );
}

function ChatMessage({ role, text, pending, toolCalls }) {
  const isBot = role === "bot";
  return (
    <div style={{
      display: "flex",
      flexDirection: isBot ? "row" : "row-reverse",
      gap: 12,
      marginBottom: 14,
      alignItems: "flex-start",
    }}>
      {isBot && (
        <div style={{
          width: 38, height: 38, flexShrink: 0,
          background: "var(--accent)",
          color: "#fff",
          display: "flex", alignItems: "center", justifyContent: "center",
          fontFamily: "var(--font-mono)",
          fontWeight: 700,
          fontSize: 14,
          letterSpacing: "0.04em",
        }}>CR</div>
      )}
      <div style={{ maxWidth: "78%" }}>
        {toolCalls && toolCalls.length > 0 && (
          <div style={{ marginBottom: 6 }}>
            {toolCalls.map((tc, i) => <ToolBadge key={i} name={tc.name} />)}
          </div>
        )}
        <div style={{
          background: isBot ? "transparent" : "var(--ink)",
          color: isBot ? "var(--ink)" : "var(--paper)",
          border: isBot ? "1px solid var(--ink-5)" : "none",
          padding: "10px 16px",
          fontSize: 17,
          lineHeight: 1.5,
          fontFamily: "var(--font-sans)",
          whiteSpace: "pre-wrap",
        }}>
          {pending ? (
            <span style={{ color: "var(--ink-4)" }}>
              <span className="pulse">●</span>{" "}
              <span className="pulse" style={{ animationDelay: "0.2s" }}>●</span>{" "}
              <span className="pulse" style={{ animationDelay: "0.4s" }}>●</span>
            </span>
          ) : text}
        </div>
      </div>
    </div>
  );
}

window.TriageChat = function TriageChat() {
  const [messages, setMessages] = useState([
    {
      role: "bot",
      text: "I'm the conversational layer over the CentralReach triage demo. Ask me about at-risk deals, dig into a specific account, or jump to the dashboard view. Same bot that powers the CLI, HTTP API, and Salesforce LWC — just with tool-use so I can route your questions.",
    },
  ]);
  const [input, setInput] = useState("");
  const [busy, setBusy] = useState(false);
  const [usedLive, setUsedLive] = useState(null);
  const scrollRef = useRef(null);

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

  async function send(text) {
    if (!text.trim() || busy) return;
    const userMsg = { role: "user", text };
    setMessages((m) => [...m, userMsg, { role: "bot", text: "", pending: true }]);
    setInput("");
    setBusy(true);

    const history = [...messages, userMsg]
      .filter((m) => !m.pending)
      .map((m) => ({ role: m.role === "user" ? "user" : "assistant", content: m.text }));

    let reply = null;
    let toolCalls = [];
    let live = false;

    try {
      const res = await Promise.race([
        fetch("/api/triage-chat", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ messages: history }),
        }),
        new Promise((_, rej) => setTimeout(() => rej(new Error("timeout")), 30000)),
      ]);
      if (res && res.ok) {
        const data = await res.json();
        if (data && typeof data.reply === "string" && data.reply.trim().length > 0) {
          reply = data.reply.trim();
          toolCalls = data.tool_calls || [];
          live = true;
        }
      }
    } catch (e) {}

    if (!reply) {
      reply = pickFallback(text);
      live = false;
    }
    setUsedLive(live);

    setMessages((m) => {
      const next = m.slice(0, -1);
      next.push({ role: "bot", text: reply, toolCalls });
      return next;
    });
    setBusy(false);
  }

  return (
    <div style={{
      width: "100%", height: "100%",
      display: "flex", flexDirection: "column",
      background: "var(--paper-2)",
      border: "1px solid var(--ink-5)",
      overflow: "hidden",
    }}>
      <div style={{
        padding: "12px 18px",
        background: "var(--ink)",
        color: "var(--paper)",
        display: "flex", alignItems: "center", gap: 10,
        flexShrink: 0,
      }}>
        <div style={{
          width: 9, height: 9, borderRadius: "50%",
          background: usedLive === false ? "#D4923A" : "#7DB069",
          flexShrink: 0,
        }} />
        <div style={{ fontFamily: "var(--font-mono)", fontSize: 13, letterSpacing: "0.12em", textTransform: "uppercase", whiteSpace: "nowrap" }}>
          Triage Bot · Tool-Use
        </div>
        <div style={{ marginLeft: "auto", fontSize: 12, opacity: 0.65, fontFamily: "var(--font-mono)", whiteSpace: "nowrap", letterSpacing: "0.1em", textTransform: "uppercase" }}>
          {usedLive === false ? "fallback" : "live"}
        </div>
      </div>

      <div ref={scrollRef} style={{
        flex: 1, minHeight: 0, overflowY: "auto",
        padding: 18,
        background: "var(--paper)",
      }}>
        {messages.map((m, i) => (
          <ChatMessage
            key={i}
            role={m.role}
            text={m.text}
            pending={m.pending}
            toolCalls={m.toolCalls}
          />
        ))}
      </div>

      <div style={{
        padding: "10px 16px",
        background: "var(--paper-2)",
        borderTop: "1px solid var(--ink-5)",
        display: "flex", flexWrap: "wrap", gap: 6,
        flexShrink: 0,
      }}>
        {STARTERS.map((s, i) => (
          <button
            key={i}
            onClick={() => send(s)}
            disabled={busy}
            style={{
              padding: "5px 12px",
              fontSize: 12,
              fontFamily: "var(--font-mono)",
              letterSpacing: "0.04em",
              background: "transparent",
              color: "var(--ink-2)",
              border: "1px solid var(--ink-5)",
              cursor: busy ? "not-allowed" : "pointer",
              opacity: busy ? 0.5 : 1,
            }}
          >{s}</button>
        ))}
      </div>

      <form
        onSubmit={(e) => { e.preventDefault(); send(input); }}
        style={{
          padding: 14,
          background: "var(--paper)",
          borderTop: "1px solid var(--ink-5)",
          display: "flex", gap: 10, alignItems: "center",
          flexShrink: 0,
        }}
      >
        <input
          type="text"
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Ask about at-risk deals, a specific account, or the dashboard…"
          disabled={busy}
          style={{
            flex: 1,
            padding: "10px 14px",
            fontSize: 16,
            border: "1px solid var(--ink-5)",
            background: "var(--paper)",
            fontFamily: "var(--font-sans)",
            color: "var(--ink)",
            outline: "none",
          }}
        />
        <button
          type="submit"
          disabled={busy || !input.trim()}
          className="btn btn--accent"
          style={{ fontSize: 14, padding: "10px 20px", fontFamily: "var(--font-mono)", letterSpacing: "0.1em", textTransform: "uppercase" }}
        >
          {busy ? "…" : "Send"}
        </button>
      </form>
    </div>
  );
};
