// financial/src/coach.jsx — the Financial Hub coach.
//
// A chat panel available from every tab (the "Coach" button bottom-right).
// The turn runs server-side in the `financialCoach` callable, which reads
// EVERY dataset the hub stores — Monarch accounts, the full transaction
// history, holdings, comp and payslips, equity, tax, retirement/kids/estate
// inputs, career — and has read-only tools to drill into any of it. The
// browser sends what Firestore does not hold — the historical comp table from
// shared.jsx and which tab is open — plus its loaded copy of the household
// profile (users/{uid}/profile/household), which the server only falls back
// to when it cannot read the document itself.
//
// The transcript lives at users/{uid}/financialCoach/chat and is read here
// directly, so the conversation survives a reload and another device.
//
// Slices run in their own Babel scope; src/shared.jsx runs first and
// publishes window.FinanceShared.

const { useState, useEffect, useRef, useCallback } = React;
const { callFn, MarkdownView, USER_PROFILE, HISTORICAL_COMP } = window.FinanceShared;

const COACH_SUGGESTIONS = [
  "How much did we spend on eating out in the last 3 months vs. the same period last year?",
  "Summarize our net worth and where it sits by account type.",
  "Am I on pace to max my 401(k) this year, based on my payslips?",
  "What in our retirement inputs would you question first?",
];

function CoachPanel({ uid, tab, onClose }) {
  const [messages, setMessages] = useState([]);
  const [loaded, setLoaded] = useState(false);
  const [input, setInput] = useState("");
  const [sending, setSending] = useState(false);
  const [error, setError] = useState(null);
  const scrollRef = useRef(null);
  const inputRef = useRef(null);

  useEffect(() => {
    if (!uid) return;
    let alive = true;
    db.collection("users").doc(uid).collection("financialCoach").doc("chat").get()
      .then(d => { if (alive) setMessages(d.exists && Array.isArray(d.data().messages) ? d.data().messages : []); })
      .catch(e => console.warn("[coach] transcript load failed", e))
      .finally(() => { if (alive) setLoaded(true); });
    return () => { alive = false; };
  }, [uid]);

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

  useEffect(() => { if (inputRef.current) inputRef.current.focus(); }, []);

  const send = useCallback(async (text) => {
    const message = String(text || "").trim();
    if (!message || sending) return;
    setError(null);
    setInput("");
    setMessages(m => [...m, { role: "user", content: message, at: Date.now() }]);
    setSending(true);
    try {
      const r = await callFn("financialCoach", {
        message,
        clientContext: { profile: USER_PROFILE, historicalComp: HISTORICAL_COMP, tab },
      });
      setMessages(m => [...m, { role: "assistant", content: r.reply, at: Date.now(), lookedAt: r.lookedAt || [] }]);
    } catch (e) {
      console.error("[coach] turn failed", e);
      setError(e?.message || "The coach didn't answer.");
      // Put the message back so it can be retried without retyping.
      setMessages(m => m.slice(0, -1));
      setInput(message);
    } finally {
      setSending(false);
    }
  }, [sending, tab]);

  const clear = useCallback(async () => {
    if (!confirm("Clear the whole conversation?")) return;
    try {
      await callFn("financialCoach", { clear: true });
      setMessages([]);
      setError(null);
    } catch (e) {
      setError(e?.message || "Could not clear the conversation.");
    }
  }, []);

  const onKeyDown = (e) => {
    if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); send(input); }
    if (e.key === "Escape") onClose();
  };

  return (
    <div role="dialog" aria-label="Financial coach" style={{
      position: "fixed", top: 0, right: 0, bottom: 0, width: "min(620px, 100vw)", zIndex: 500,
      background: "#0a0e16", borderLeft: "1px solid #1e2a3a", boxShadow: "-12px 0 40px rgba(0,0,0,0.5)",
      display: "flex", flexDirection: "column",
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 8, padding: "12px 16px", borderBottom: "1px solid #1e2a3a" }}>
        <div style={{ flex: 1 }}>
          <div style={{ fontWeight: 700, color: "#10b981" }}>Financial coach</div>
          <div style={{ fontSize: 11, color: "#64748b" }}>Reads all of your hub data: accounts, transactions, comp, tax, and your plans</div>
        </div>
        {messages.length > 0 && (
          <button className="btn-secondary" style={{ fontSize: 11, padding: "4px 10px" }} onClick={clear} disabled={sending}>Clear</button>
        )}
        <button className="btn-secondary" style={{ fontSize: 11, padding: "4px 10px" }} onClick={onClose} aria-label="Close coach">✕</button>
      </div>

      <div ref={scrollRef} style={{ flex: 1, overflowY: "auto", padding: 16, display: "flex", flexDirection: "column", gap: 12 }}>
        {!loaded && <div style={{ textAlign: "center", padding: 24 }}><span className="spinner" /></div>}
        {loaded && messages.length === 0 && !sending && (
          <div style={{ color: "#94a3b8", fontSize: 12 }}>
            <div style={{ marginBottom: 12 }}>Ask about anything in the hub. The coach can look through your full transaction history and every stored record, so it answers with your actual numbers.</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
              {COACH_SUGGESTIONS.map(s => (
                <button key={s} className="btn-secondary" style={{ textAlign: "left", fontSize: 12, padding: "8px 12px" }} onClick={() => send(s)}>{s}</button>
              ))}
            </div>
          </div>
        )}
        {messages.map((m, i) => (
          m.role === "user" ? (
            <div key={i} style={{ alignSelf: "flex-end", maxWidth: "85%", background: "rgba(16,185,129,0.12)", border: "1px solid rgba(16,185,129,0.3)", borderRadius: 10, padding: "8px 12px", whiteSpace: "pre-wrap", fontSize: 13 }}>
              {m.content}
            </div>
          ) : (
            <div key={i} style={{ alignSelf: "stretch", background: "#0d1117", border: "1px solid #1e2a3a", borderRadius: 10, padding: "10px 14px" }}>
              {Array.isArray(m.lookedAt) && m.lookedAt.length > 0 && (
                <div style={{ display: "flex", flexWrap: "wrap", gap: 4, marginBottom: 8 }}>
                  {m.lookedAt.map((l, j) => <span key={j} className="tag tag-blue" style={{ fontWeight: 500 }}>🔎 {l}</span>)}
                </div>
              )}
              <MarkdownView text={m.content} />
            </div>
          )
        ))}
        {sending && (
          <div style={{ display: "flex", alignItems: "center", gap: 8, color: "#64748b", fontSize: 12 }}>
            <span className="spinner" style={{ width: 14, height: 14 }} /> Looking through your data…
          </div>
        )}
        {error && <div style={{ color: "#ef4444", fontSize: 12 }}>✕ {error}</div>}
      </div>

      <div style={{ padding: 12, borderTop: "1px solid #1e2a3a", display: "flex", gap: 8, alignItems: "flex-end" }}>
        <textarea
          ref={inputRef}
          value={input}
          onChange={e => setInput(e.target.value)}
          onKeyDown={onKeyDown}
          rows={2}
          maxLength={4000}
          placeholder="Ask your financial coach…  (Enter to send, Shift+Enter for a new line)"
          style={{ resize: "none", flex: 1 }}
          disabled={sending}
        />
        <button className="btn-primary" onClick={() => send(input)} disabled={sending || !input.trim()}>Send</button>
      </div>
    </div>
  );
}

// The launcher: a fixed button on every tab that opens the panel.
function CoachLauncher({ uid, tab }) {
  const [open, setOpen] = useState(false);
  return (
    <>
      {!open && (
        <button className="btn-primary" onClick={() => setOpen(true)} aria-label="Open financial coach" style={{
          position: "fixed", right: 20, bottom: 20, zIndex: 400, borderRadius: 999, padding: "12px 18px",
          boxShadow: "0 8px 24px rgba(16,185,129,0.35)",
        }}>💬 Coach</button>
      )}
      {open && <CoachPanel uid={uid} tab={tab} onClose={() => setOpen(false)} />}
    </>
  );
}

window.FinanceViews = Object.assign(window.FinanceViews || {}, { CoachLauncher });
