/* chat.jsx, the messaging surface. Texting your agent, in-app.
   Agent replies are canned. One message carries an inline proposal card
   that opens the same approval flow. Typing indicator + slide-in bubbles. */

const cannedReply = (text) => {
  const t = text.toLowerCase();
  if (/(make it|every|run when|change it|set it|instead|\$\d|raise|lower|cap it)/.test(t)) return { t: "Done. I've updated the rule and it'll run that way from now on. I'll flag the next run in your stream before it executes." };
  if (t.includes("proposal") || t.includes("send it")) return { t: "Done. Here it is, ready for you to approve whenever you like.", proposal: "p1" };
  if (t.includes("cash")) return { t: "Your cash is in good shape, with $18,420 in Checking and $64,000 in Savings earning 4.8%. About $15k of that has sat idle for 9 days though, so want me to move it into short-term Treasuries earning about 5.1%?" };
  if (t.includes("pause") && (t.includes("invest") || t.includes("dca"))) return { t: "Paused the weekly VTI buy, so nothing runs Friday. I'll keep watching and nudge you if cash starts piling up." };
  if (t.includes("today") || t.includes("did you")) return { t: "Today I bought $500 of VTI at the open, swept $12,000 from Checking to Savings at 11:08, and put a rebalance up for your approval, so you're up $4,802 on the day." };
  if (t.includes("risk")) return { t: "Evening it out means selling a bit of your two biggest holdings (NVDA, Bitcoin) and putting it into a broad fund. That leaves you less exposed to any single name, with a small gain along the way, and the catch is that you'd hold less of the names that ran up the most." };
  return { t: "Got it. I'll look at your accounts and come back with something concrete you can approve." };
};

const Chat = ({ nav, proposals, onApprove, inject, onInjected }) => {
  const [msgs, setMsgs] = useState(CHAT_SEED);
  const [draft, setDraft] = useState("");
  const [typing, setTyping] = useState(false);
  const scrollRef = useRef(null);

  const dateLabel = "Today · 9:24 AM";

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

  // a "send back to agent" from the approval flow lands here
  useEffect(() => {
    if (!inject) return;
    setMsgs(m => [...m, { from: "user", t: inject.note, time: "now" }]);
    setTyping(true);
    const id = setTimeout(() => {
      setTyping(false);
      setMsgs(m => [...m, { from: "agent", t: inject.reply, time: "now" }]);
    }, 1100);
    onInjected();
    return () => clearTimeout(id);
  }, [inject]);

  const send = (text) => {
    const body = (text != null ? text : draft).trim();
    if (!body) return;
    setDraft("");
    setMsgs(m => [...m, { from: "user", t: body, time: "now" }]);
    setTyping(true);
    setTimeout(() => {
      const r = cannedReply(body);
      setTyping(false);
      setMsgs(m => [...m, { from: "agent", time: "now", ...r }]);
    }, 1100);
  };

  const attachDoc = (doc) => {
    setMsgs(m => [...m, { from: "user", t: `Attached ${doc.name}`, doc, time: "now" }]);
    setTyping(true);
    setTimeout(() => {
      setTyping(false);
      setMsgs(m => [...m, { from: "agent", t: attachReplyFor(doc), time: "now" }]);
    }, 1100);
  };

  return (
    <div style={{ flex: 1, display: "flex", flexDirection: "column", minHeight: 0 }}>
      {/* header */}
      <div style={{ flex: "none", padding: "4px 16px 10px", borderBottom: "1px solid var(--rule)", display: "flex", alignItems: "center", gap: 10 }}>
        <button className="press" onClick={() => nav.tab("home")} aria-label="Back" style={{ background: "none", border: "none", padding: 6, margin: "0 -6px", display: "grid", placeItems: "center", color: "var(--ink)", cursor: "pointer", flex: "none" }}>
          <Icon name="back" size={22} stroke={1.7} />
        </button>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontFamily: "var(--f-display)", fontSize: 15, fontWeight: 600, letterSpacing: "-0.015em" }}>Yoshi</div>
        </div>
        <button className="press" onClick={() => nav.tab("home")} aria-label="Close" style={{ background: "none", border: "none", padding: 6, margin: "0 -6px", display: "grid", placeItems: "center", color: "var(--ink-3)", cursor: "pointer", flex: "none" }}>
          <Icon name="close" size={21} stroke={1.7} />
        </button>
      </div>

      {/* thread */}
      <div className="scroll" ref={scrollRef} style={{ padding: "14px 16px 8px", display: "flex", flexDirection: "column", gap: 10 }}>
        <div style={{ textAlign: "center", padding: "2px 0 8px" }}>
          <span style={{ fontFamily: "var(--f-display)", fontSize: 10, color: "var(--ink-3)", letterSpacing: "0.06em", textTransform: "uppercase" }}>{dateLabel}</span>
        </div>
        {msgs.map((m, i) => <Bubble key={i} m={m} proposals={proposals} onApprove={onApprove} />)}
        {typing && <Typing />}
      </div>

      {/* quick replies + composer */}
      <div style={{ flex: "none", borderTop: "1px solid var(--rule)" }}>
          <div style={{ display: "flex", gap: 7, overflowX: "auto", padding: "10px 16px 6px" }}>
            {QUICK_REPLIES.map(q => (
              <button key={q} className="press" onClick={() => send(q)} style={{ flex: "none", padding: "7px 12px", borderRadius: 999, background: "color-mix(in srgb, var(--ink) 8%, var(--bg-2))", border: "none", fontFamily: "var(--f-display)", fontSize: 12, fontWeight: 500, color: "var(--ink)", whiteSpace: "nowrap", cursor: "pointer" }}>{q}</button>
            ))}
          </div>
          <div style={{ padding: "4px 14px 16px" }}>
            <YoshiComposer value={draft} onChange={setDraft} onSend={() => send()} placeholder="Talk to Yoshi…" onAttach={attachDoc} />
          </div>
      </div>
    </div>
  );
};

const Bubble = ({ m, proposals, onApprove }) => {
  const isUser = m.from === "user";
  return (
    <div className="yo-enter" style={{ display: "flex", justifyContent: isUser ? "flex-end" : "flex-start" }}>
      <div style={{ maxWidth: "82%" }}>
        <div style={{
          padding: "10px 13px",
          borderRadius: isUser ? "14px 14px 4px 14px" : "14px 14px 14px 4px",
          background: isUser ? "var(--accent)" : "var(--bg-card)",
          color: isUser ? "var(--accent-ink)" : "var(--ink)",
          border: isUser ? "none" : "1px solid var(--rule)",
          fontFamily: "var(--f-display)", fontSize: 14, lineHeight: 1.45, letterSpacing: "-0.003em",
        }}>
          {m.doc &&
          <span style={{ display: "flex", alignItems: "center", gap: 8, padding: "7px 10px", marginBottom: 7, background: isUser ? "color-mix(in srgb, var(--accent-ink) 14%, transparent)" : "var(--bg-2)", border: "1px solid " + (isUser ? "color-mix(in srgb, var(--accent-ink) 28%, transparent)" : "var(--rule-2)"), borderRadius: 9 }}>
            <Icon name={m.doc.icon || "doc"} size={15} stroke={1.5} />
            <span style={{ fontFamily: "var(--f-display)", fontSize: 12, fontWeight: 600 }}>{m.doc.name}</span>
          </span>}
          {m.t}</div>
        {m.proposal && <InlineProposal id={m.proposal} proposals={proposals} onApprove={onApprove} />}
      </div>
    </div>
  );
};

const InlineProposal = ({ id, proposals, onApprove }) => {
  const live = proposals.find(p => p.id === id);
  const p = live || PROPOSALS.find(p => p.id === id);
  const done = !live;
  return (
    <div style={{ marginTop: 7, border: `1px solid ${done ? "var(--rule)" : "var(--accent)"}`, background: "var(--bg-card)", borderRadius: 12, position: "relative" }}>
      <div style={{ padding: "11px 13px 12px" }}>
        <Eyebrow color={done ? "var(--ink-3)" : "var(--accent)"}>{done ? "● Executed" : "Proposal"}</Eyebrow>
        <div style={{ fontFamily: "var(--f-display)", fontSize: 14.5, fontWeight: 600, letterSpacing: "-0.012em", marginTop: 5 }}>{p.title}</div>
        <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginTop: 7 }}>
          <Money value={p.net} size={12.5} sign color={p.net >= 0 ? "var(--accent-pos)" : "var(--ink)"} dim="var(--ink-3)" />
          <span style={{ fontFamily: "var(--f-mono)", fontSize: 10.5, color: "var(--ink-3)", marginLeft: "auto" }}>{p.settlesVerb || "settles"} {p.settles}</span>
        </div>
        {!done && <Btn full onClick={() => onApprove(id)} style={{ marginTop: 11, padding: "10px" }}>Review</Btn>}
      </div>
    </div>
  );
};

const Typing = () => (
  <div style={{ display: "flex", justifyContent: "flex-start" }}>
    <div style={{ padding: "12px 14px", background: "var(--bg-card)", border: "1px solid var(--rule)", borderRadius: "14px 14px 14px 4px", display: "flex", gap: 4 }}>
      {[0, 1, 2].map(i => (
        <span key={i} className="yo-pulse" style={{ width: 6, height: 6, borderRadius: 999, background: "var(--ink-3)", animationDelay: `${i * 200}ms` }} />
      ))}
    </div>
  </div>
);

window.Chat = Chat;
