// "Talk to Ignited" — conversational agent modal.
//
// UI only. All knowledge/behaviour lives in agent/knowledge.js (window.IgnitedAgent),
// which is the SAME file the Vercel /api/chat function uses — one source of truth.
//
// Transport (callAgent): tries the production endpoint POST /api/chat first; if it
// isn't there (e.g. this prototype, or before deploy) it falls back to the built-in
// in-browser model so the experience is identical to demo and to ship.

const AGENT_EMAIL = "contact@ignitedusa.com";
// Pre-framed subject so leads arrive ready for the team to pick up.
const AGENT_CONTACT_URL =
  "mailto:" + AGENT_EMAIL + "?subject=" + encodeURIComponent("Let's talk growth — from the Ignited site");

async function callAgent(messages) {
  // 1) Production path — the Vercel function holds the API key server-side.
  try {
    const r = await fetch("/api/chat", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ messages })
    });
    if (r.ok) {
      const d = await r.json();
      if (d && d.reply) return { reply: d.reply, handoff: !!d.handoff };
    }
  } catch (e) {

    /* endpoint not available (prototype / pre-deploy) — fall through */}

  // 2) Fallback path — same knowledge, runs against the in-browser model.
  const A = window.IgnitedAgent || {};
  const lastUser = (messages[messages.length - 1] || {}).content || "";
  const cannedKey = A.matchCanned && A.matchCanned(lastUser);
  if (cannedKey && A.CANNED && A.CANNED[cannedKey]) {
    return { reply: A.CANNED[cannedKey], handoff: true };
  }
  if (window.claude && window.claude.complete) {
    try {
      // Prime the model with the system prompt as a leading turn (works with the
      // documented messages[] API; the real /api/chat uses a native system field).
      const primed = [
      { role: "user", content: A.SYSTEM_PROMPT || "You are Ignited's AI strategist." },
      { role: "assistant", content: "Understood — I'm Ignited's strategist. What are you working on?" }].
      concat(messages);
      const reply = await window.claude.complete({ messages: primed });
      const text = (reply || "").trim();
      const handoff = /strategy call|connect you|reach (out to )?the team|book a|get in touch|talk to (the|our) team/i.test(text);
      return { reply: text || A.CANNED && A.CANNED.error || "", handoff };
    } catch (e) {
      return { reply: A.CANNED && A.CANNED.error || "I'm having trouble responding right now.", handoff: true };
    }
  }
  return { reply: A.CANNED && A.CANNED.error || "I'm having trouble responding right now.", handoff: true };
}

// Render the model's text as clean rich text: paragraphs by line, **bold** and
// *italic* parsed into real markup, and leading "- " / "* " bullets as a list —
// so stray markdown never shows as literal asterisks.
function formatInline(text, keyBase) {
  const nodes = [];
  const re = /(\*\*([^*]+)\*\*|\*([^*\n]+)\*|__([^_]+)__)/g;
  let last = 0, m, k = 0;
  while ((m = re.exec(text))) {
    if (m.index > last) nodes.push(text.slice(last, m.index));
    if (m[2] != null) nodes.push(<strong key={keyBase + "-b" + k}>{m[2]}</strong>);
    else if (m[3] != null) nodes.push(<em key={keyBase + "-i" + k}>{m[3]}</em>);
    else if (m[4] != null) nodes.push(<strong key={keyBase + "-u" + k}>{m[4]}</strong>);
    last = re.lastIndex; k++;
  }
  if (last < text.length) nodes.push(text.slice(last));
  return nodes;
}

function formatAgentText(content) {
  const lines = String(content).split("\n").filter((l, i, a) => !(l.trim() === "" && (i === 0 || i === a.length - 1)));
  const blocks = [];
  let bullets = null;
  lines.forEach((raw, j) => {
    const line = raw.replace(/\s+$/, "");
    const bullet = line.match(/^\s*[-*•]\s+(.*)$/);
    if (bullet) {
      if (!bullets) { bullets = []; blocks.push({ type: "ul", items: bullets, key: "ul" + j }); }
      bullets.push({ text: bullet[1], key: "li" + j });
    } else {
      bullets = null;
      if (line.trim() !== "") blocks.push({ type: "p", text: line, key: "p" + j });
    }
  });
  return blocks.map((b, i) =>
    b.type === "ul"
      ? <ul key={b.key} style={{ margin: i === 0 ? 0 : "8px 0 0", paddingLeft: 18 }}>
          {b.items.map((it) => <li key={it.key} style={{ margin: "2px 0" }}>{formatInline(it.text, it.key)}</li>)}
        </ul>
      : <p key={b.key} style={{ margin: i === 0 ? 0 : "8px 0 0" }}>{formatInline(b.text, b.key)}</p>
  );
}

const AgentModal = ({ open, seed, onClose }) => {
  const [messages, setMessages] = React.useState([]);
  const [input, setInput] = React.useState("");
  const [loading, setLoading] = React.useState(false);
  const [handoff, setHandoff] = React.useState(false);
  const scrollRef = React.useRef(null);
  const inputRef = React.useRef(null);
  const seedSent = React.useRef(null);
  const funneledRef = React.useRef(false);

  const send = React.useCallback(async (text) => {
    const content = (text != null ? text : input).trim();
    if (!content || loading) return;
    setInput("");
    const next = messages.concat({ role: "user", content });
    setMessages(next);
    setLoading(true);
    const userCount = next.filter((m) => m.role === "user").length;
    const { reply, handoff: h } = await callAgent(next);
    // Lead capture: once the user has shared real context (2nd exchange) or
    // shows intent, make sure there's a clear next step — but add it only once,
    // and never if the model already routed them to email itself.
    let finalReply = reply;
    const mentionsEmail = /contact@ignitedusa\.com/i.test(finalReply);
    if (!funneledRef.current && !mentionsEmail && (h || userCount >= 2)) {
      finalReply = finalReply.trim() + "\n\nWant Ignited's team to pressure-test this with you? Email contact@ignitedusa.com and we'll take it from here.";
      funneledRef.current = true;
    }
    if (mentionsEmail) funneledRef.current = true;
    setMessages((m) => m.concat({ role: "assistant", content: finalReply }));
    if (h || userCount >= 2) setHandoff(true);
    setLoading(false);
  }, [input, loading, messages]);

  // Auto-send the seed message (the challenge typed in the hero) once per unique seed.
  React.useEffect(() => {
    if (open && seed && seedSent.current !== seed) {
      seedSent.current = seed;
      send(seed);
    }
  }, [open, seed]); // eslint-disable-line

  // Esc to close, lock body scroll while open.
  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => {if (e.key === "Escape") onClose();};
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    setTimeout(() => inputRef.current && inputRef.current.focus(), 120);
    return () => {window.removeEventListener("keydown", onKey);document.body.style.overflow = "";};
  }, [open, onClose]);

  // Keep the transcript pinned to the latest message.
  React.useEffect(() => {
    const el = scrollRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [messages, loading]);

  if (!open) return null;

  return ReactDOM.createPortal(
    <div className="r-agent-overlay" onClick={onClose}>
      <style>{AGENT_CSS}</style>
      <div className="r-agent-panel" onClick={(e) => e.stopPropagation()} role="dialog" aria-label="Talk to Ignited">
        {/* Header */}
        <div className="r-agent-head">
          <div className="r-agent-id">
            <span className="r-agent-dot" />
            <div>
              <div className="r-agent-title">Talk to Ignited</div>
              <div className="r-agent-sub mono">AI STRATEGIST</div>
            </div>
          </div>
          <button className="r-agent-x" onClick={onClose} aria-label="Close">✕</button>
        </div>

        {/* Transcript */}
        <div className="r-agent-scroll" ref={scrollRef}>
          {messages.length === 0 && !loading &&
          <div className="r-agent-empty">
              <div className="r-agent-empty-h display">What's your biggest marketing challenge?</div>
              <p className="r-agent-empty-p">Tell me what you're up against — budget pressure, sameness, measurement, attention — and I'll give you Ignited's point of view.</p>
            </div>
          }
          {messages.map((m, i) =>
          <div key={i} className={"r-agent-row " + (m.role === "user" ? "is-user" : "is-bot")}>
              <div className="r-agent-bubble">
                {formatAgentText(m.content)}
              </div>
            </div>
          )}
          {loading &&
          <div className="r-agent-row is-bot">
              <div className="r-agent-bubble r-agent-typing"><span /><span /><span /></div>
            </div>
          }

          {handoff &&
          <div className="r-agent-cta-inline">
              <a href={AGENT_CONTACT_URL} className="r-agent-cta">
                Book a strategy call
                <ArrowUpRight size={14} />
              </a>
            </div>
          }
        </div>

        {/* Composer */}
        <form
          className="r-agent-composer"
          onSubmit={(e) => {e.preventDefault();send();}}>
          
          <input
            ref={inputRef}
            value={input}
            onChange={(e) => setInput(e.target.value)}
            placeholder="Type your challenge…"
            className="r-agent-input" />
          
          <button type="submit" className="r-agent-send" aria-label="Send" disabled={loading || !input.trim()}>
            <ArrowUpRight size={16} />
          </button>
        </form>
        <div className="r-agent-foot mono">
          Powered by Ignited · responses are AI-generated.{" "}
          <a href={AGENT_CONTACT_URL}>Email us →</a>
        </div>
      </div>
    </div>,
    document.body
  );
};

const AGENT_CSS = `
.r-agent-overlay{position:fixed;inset:0;z-index:200;background:rgba(10,10,15,0.55);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  display:flex;justify-content:flex-end;align-items:stretch;animation:rAgentFade .2s ease;}
@keyframes rAgentFade{from{opacity:0}to{opacity:1}}
.r-agent-panel{width:440px;max-width:100%;height:100%;background:var(--paper,#F4F1EA);
  display:flex;flex-direction:column;box-shadow:-30px 0 80px -20px rgba(10,10,15,0.5);
  animation:rAgentSlide .3s cubic-bezier(.22,1,.36,1) both;}
@keyframes rAgentSlide{from{transform:translateX(18px);opacity:.4}to{transform:translateX(0);opacity:1}}
.r-agent-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:18px 20px;background:var(--ink,#0A0A0F);color:#fff;flex-shrink:0;}
.r-agent-id{display:flex;align-items:center;gap:12px;}
.r-agent-dot{width:9px;height:9px;border-radius:99px;background:var(--blue,#1AA5F5);
  box-shadow:0 0 0 4px rgba(26,165,245,0.25);flex-shrink:0;}
.r-agent-title{font-size:16px;font-weight:600;letter-spacing:-0.01em;}
.r-agent-sub{font-size:10px;color:rgba(255,255,255,0.55);margin-top:2px;}
.r-agent-x{background:transparent;border:none;color:#fff;font-size:18px;cursor:pointer;
  width:36px;height:36px;border-radius:99px;display:grid;place-items:center;}
.r-agent-x:hover{background:rgba(255,255,255,0.12);}
.r-agent-scroll{flex:1;overflow-y:auto;padding:24px 20px;display:flex;flex-direction:column;gap:16px;}
.r-agent-empty{margin:auto 0;text-align:left;padding:8px 0;}
.r-agent-empty-h{font-size:26px;line-height:1.05;letter-spacing:-0.02em;color:var(--ink,#0A0A0F);
  font-weight:600;text-wrap:balance;}
.r-agent-empty-p{font-size:15px;line-height:1.5;color:var(--muted,#6b6b6b);margin:14px 0 0;max-width:340px;}
.r-agent-row{display:flex;}
.r-agent-row.is-user{justify-content:flex-end;}
.r-agent-bubble{max-width:85%;padding:13px 16px;border-radius:16px;font-size:15px;
  line-height:1.5;letter-spacing:-0.005em;}
.is-bot .r-agent-bubble{background:#fff;color:var(--ink,#0A0A0F);border:1px solid var(--rule,rgba(10,10,15,0.1));
  border-bottom-left-radius:5px;}
.is-user .r-agent-bubble{background:var(--ink,#0A0A0F);color:#fff;border-bottom-right-radius:5px;}
.r-agent-typing{display:flex;gap:5px;align-items:center;}
.r-agent-typing span{width:7px;height:7px;border-radius:99px;background:var(--muted,#999);
  animation:rAgentBlink 1.2s infinite both;}
.r-agent-typing span:nth-child(2){animation-delay:.2s}
.r-agent-typing span:nth-child(3){animation-delay:.4s}
@keyframes rAgentBlink{0%,80%,100%{opacity:.25}40%{opacity:1}}
.r-agent-cta-inline{display:flex;justify-content:flex-start;padding-top:4px;}
.r-agent-cta{display:inline-flex;align-items:center;gap:8px;background:var(--blue,#1AA5F5);
  color:#fff;text-decoration:none;font-size:14px;font-weight:600;padding:12px 20px;border-radius:99px;
  letter-spacing:-0.01em;transition:transform .15s ease;}
.r-agent-cta:hover{transform:translateY(-1px);}
.r-agent-composer{display:flex;align-items:center;gap:10px;padding:14px 16px;
  background:var(--paper,#F4F1EA);border-top:1px solid var(--rule,rgba(10,10,15,0.1));flex-shrink:0;}
.r-agent-input{flex:1;background:#fff;border:1px solid var(--rule-strong,rgba(10,10,15,0.18));
  border-radius:99px;padding:13px 18px;font-size:15px;font-family:var(--body);color:var(--ink,#0A0A0F);
  outline:none;min-width:0;}
.r-agent-input:focus{border-color:var(--blue,#1AA5F5);box-shadow:0 0 0 4px rgba(26,165,245,0.15);}
.r-agent-send{width:46px;height:46px;border-radius:99px;background:var(--blue,#1AA5F5);border:none;
  color:#fff;display:grid;place-items:center;flex-shrink:0;cursor:pointer;transition:opacity .15s ease;}
.r-agent-send:disabled{opacity:.4;cursor:default;}
.r-agent-foot{font-size:10px;color:var(--muted,#888);text-align:center;padding:0 16px 14px;
  background:var(--paper,#F4F1EA);}
.r-agent-foot a{color:var(--muted,#888);text-decoration:underline;}
@media (max-width:560px){
  .r-agent-overlay{justify-content:stretch;}
  .r-agent-panel{width:100%;height:100%;height:100dvh;}
}
@media (prefers-reduced-motion: reduce){
  .r-agent-overlay,.r-agent-panel{animation:none;}
}
`;

window.AgentModal = AgentModal;
window.callAgent = callAgent;