/* London Free Guide — virtual guide assistant.
   A floating "Ask the guide" chat that answers from the real content (window.LFG_CONTENT)
   using window.claude.complete. On-brand voice. Exported to window. */
const { useState: useAgentState, useRef, useEffect: useAgentEffect } = React;

const COST_WORD = { free: "free", under10: "under £10", ticketed: "train fare only" };

/* Brolly's knowledge for a given question. Prefers the unified KB (window.LFG_KB
   — the 298 A-Z spots + deep pages + curated feed) and returns a cache-friendly
   split: a stable always-on spot index, the time-bound "now" list, and the
   full detail for just the handful of records that match the question.
   Falls back to a flat dump of the curated feed if the KB has not loaded. */
function buildKnowledge(question) {
  const KB = window.LFG_KB;
  if (KB && KB.spotIndex) {
    const hits = KB.retrieve(question, 8);
    return {
      index: KB.spotIndex(),
      now: KB.nowList(),
      detail: hits.map((r) => KB.detailBlock(r)).join("\n\n")
    };
  }
  const flat = (window.LFG_CONTENT || []).map((i) => {
    const tags = (i.tags || []).join(", ");
    const when = i.date ? ` (${i.date})` : "";
    return `- ${i.title} [${i.kind}, ${COST_WORD[i.cost] || i.cost}] — ${i.area}, near ${i.tube}. ${tags}.${when} ${i.summary}`;
  }).join("\n");
  return { index: flat, now: "", detail: "" };
}

/* default question chips, picked by the weather so they feel alive (3 each) */
const SUGGEST_DRY = [
  "What's free this weekend?",
  "Best free view in London?",
  "Free things to do with kids?"
];
const SUGGEST_WET = [
  "What's good to do in the rain?",
  "Best free museums right now?",
  "What's free this weekend?"
];

const GREETING = "Hiya, I'm Brolly. Ask me anything about free things to do in London.";

/* Brolly's mark — a clean line-icon umbrella in the brand stroke language
   (inherits currentColor so it's white on the red pill, accent-red on the
   panel head, and theme-safe in both light and dark with no inverting) */
function BrollyIcon({ open }) {
  return (
    <svg className="brolly-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      {open ? (
        <React.Fragment>
          <path d="M12 3.4V5" />
          <path d="M3.5 12a8.5 6.5 0 0 1 17 0Z" />
          <path d="M12 12v6a2.6 2.6 0 0 1-5.2 0" />
        </React.Fragment>
      ) : (
        <React.Fragment>
          <path d="M12 2.5c-1.9 3-2.9 6.2-2.9 10.5h5.8C14.9 8.7 13.9 5.5 12 2.5Z" />
          <path d="M12 13v4.6a2.3 2.3 0 0 1-4.6 0" />
        </React.Fragment>
      )}
    </svg>
  );
}

/* a small white line-icon weather glyph that MIRRORS Brolly's rain threshold
   (>=51 = rain = brolly up) so the glyph and her umbrella never disagree.
   Built in the same stroke language as BrollyIcon, white via currentColor. */
function wxLabel(code) { return code >= 51 ? "rain" : code >= 2 ? "cloudy" : "clear"; }
function WxGlyph({ code }) {
  const c = code == null ? 2 : code;
  const common = { className: "wx-svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true };
  if (c >= 51) {
    return (
      <svg {...common}>
        <path d="M7 15h9.3a3.5 3.5 0 0 0 .4-6.97 5.3 5.3 0 0 0-10.1 1.27A3.1 3.1 0 0 0 7 15Z" />
        <path d="M8.5 18l-.9 1.8 M12 18l-.9 1.8 M15.5 18l-.9 1.8" />
      </svg>
    );
  }
  if (c >= 2) {
    return (
      <svg {...common}>
        <path d="M7 18h10a4 4 0 0 0 .5-7.97 6 6 0 0 0-11.5 1.4A3.5 3.5 0 0 0 7 18Z" />
      </svg>
    );
  }
  return (
    <svg {...common}>
      <circle cx="12" cy="12" r="4" />
      <path d="M12 2.5v2 M12 19.5v2 M4.5 12h-2 M21.5 12h-2 M6 6l-1.4-1.4 M19.4 19.4 18 18 M18 6l1.4-1.4 M4.6 19.4 6 18" />
    </svg>
  );
}

/* the weather sits INSIDE the red pill, on a small line right above "Ask Brolly"
   (umbrella stays on the left). Two short stacked lines fit inside the umbrella
   icon's height, so the pill doesn't grow. Injected so it ships with agent.jsx
   on every page (no home.css bump). White on red — theme-safe. */
const BROLLY_WX_CSS = `
.agent-fab { font-size: .76rem; bottom: 26px; }
.agent-msg.assistant { white-space: pre-wrap; }
.agent-fab-stack { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 2px; line-height: 1.04; }
.agent-fab-label { font-weight: 700; }
.agent-fab-wx { display: inline-flex; align-items: center; gap: 4px; font-weight: 600; font-size: .86em; color: rgba(255,255,255,.92); letter-spacing: .01em; animation: wxfade .35s ease both; }
.agent-fab-wx .wx-svg { width: 13px; height: 13px; display: block; color: #fff; }
@keyframes wxfade { from { opacity: 0; transform: translateY(2px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .agent-fab-wx { animation: none; } }
`;
function injectBrollyWxCSS() {
  if (document.getElementById("lfg-brolly-wx-css")) return;
  const s = document.createElement("style");
  s.id = "lfg-brolly-wx-css";
  s.textContent = BROLLY_WX_CSS;
  document.head.appendChild(s);
}

function GuideAgent() {
  const [open, setOpen] = useAgentState(false);
  const [input, setInput] = useAgentState("");
  const [busy, setBusy] = useAgentState(false);
  const [msgs, setMsgs] = useAgentState([{ role: "assistant", text: GREETING }]);
  const [rainy, setRainy] = useAgentState(true);   // brolly opens in the rain
  const [wx, setWx] = useAgentState(null);         // today's London {code, t} for the chip
  const scrollRef = useRef(null);

  useAgentEffect(() => { injectBrollyWxCSS(); }, []);

  // Brolly's brolly opens when it's raining in London, folds away when it's clear.
  // We also keep today's temp + code for the little weather chip above the pill.
  useAgentEffect(() => {
    if (!window.LFGWeather) return;
    let live = true;
    window.LFGWeather.london().then((d) => {
      if (live && d && d.length) { setRainy(d[0].code >= 51); setWx(d[0]); }
    }).catch(() => {});
    return () => { live = false; };
  }, []);

  useAgentEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [msgs, busy, open]);

  /* let other parts of the site open Brolly (optionally with a seed question) —
     e.g. the First Time planner's "Hand it to Brolly" button */
  useAgentEffect(() => {
    function onOpen(e) {
      setOpen(true);
      const q = e && e.detail && e.detail.ask;
      if (q) setTimeout(() => ask(q), 350);
    }
    window.addEventListener("lfg-brolly-open", onOpen);
    return () => window.removeEventListener("lfg-brolly-open", onOpen);
  }, [msgs, busy]);

  async function ask(q) {
    const question = (q || input).trim();
    if (!question || busy) return;
    setInput("");
    const history = msgs.concat({ role: "user", text: question });
    setMsgs(history);
    setBusy(true);

    const convo = history.slice(-6).map((m) => (m.role === "user" ? "User" : "Guide") + ": " + m.text).join("\n");
    const know = buildKnowledge(question);
    const prompt =
`You are Brolly, the friendly London girl behind London Free Guide. You are a warm honest Londoner who hates overpaying and knows the city inside out.

VOICE: warm, cheeky and personal, like a London friend texting you back. Light and fun but tight.

FORMAT, this matters most:
- Keep it really short. Three picks at most, often fewer.
- When you name places, give one per line, each starting with a bullet •. Place name first, then a few words on why. For a general question just give a short line or two, no bullets.
- No opening pleasantries. Never start with Ooh, Brilliant question, Great question, Love that or anything like it. Go straight in.
- No long paragraphs or long winding sentences. Think quick text message, not an essay.
- Do not end by asking what they are into or offering to narrow it down. Give the picks and stop.
- Do not use Oxford commas, em dashes or hyphens. Never sound salesy or corporate.

Do not mention the weather or what it is like outside. The forecast is not always what they can actually see, so never open with the weather. Just answer what they asked.

EXAMPLE OF THE SHAPE AND LENGTH TO AIM FOR:
Three cracking free museums right now:
• Museum of London Docklands, Canary Wharf. Old sugar warehouse, atmospheric and dead quiet.
• Wellcome Collection, Euston. Gloriously weird medical curiosities.
• Horniman, Forest Hill. Stuffed walrus and a free aquarium, worth the little trip.

WHAT YOU DO:
- Help with anything London. Getting around, neighbourhoods, when to visit, rainy day ideas, the tube, markets, history. Be genuinely useful.
- When you name a specific spot, price, opening time or date, use only the knowledge below and never invent it. Just name the spot naturally so they can picture it.
- Lean to the free and cheap. If a free option fits, lead with it.
- You can drop an insider tip from the knowledge when it genuinely helps. It makes you feel like a local friend.
- Do not tell them to check the site or a section in every reply. Only point them somewhere once in a while when it truly adds something.
- If nothing on the site fits, give honest general advice anyway. Stay on London.

EVERYTHING LONDON FREE GUIDE LISTS (name, area, category):
${know.index}

ON THE SITE RIGHT NOW (time sensitive):
${know.now}

MOST RELEVANT TO THIS QUESTION (full detail, use these first):
${know.detail}

CONVERSATION SO FAR:
${convo}

Reply as Brolly:`;

    try {
      let reply;
      if (window.claude && window.claude.complete) {
        reply = await window.claude.complete({ messages: [{ role: "user", content: prompt }] });
      } else {
        reply = "I need a live connection to answer — in the published site I'll be right here to help. For now, try the search bar or the filters above.";
      }
      setMsgs(history.concat({ role: "assistant", text: (reply || "").trim() }));
    } catch (e) {
      setMsgs(history.concat({ role: "assistant", text: "Something went wrong reaching me just then. Have another go in a sec?" }));
    } finally {
      setBusy(false);
    }
  }

  return (
    <React.Fragment>
      <button
        className={"agent-fab" + (open ? " hide" : "")}
        onClick={() => setOpen(true)}
        aria-label={wx ? ("Ask Brolly. London " + wx.t + " degrees, " + wxLabel(wx.code) + ".") : "Ask Brolly"}
      >
        <span className="agent-fab-ico" aria-hidden="true"><BrollyIcon open={rainy} /></span>
        <span className="agent-fab-stack">
          {wx && (
            <span className="agent-fab-wx" aria-hidden="true">
              <WxGlyph code={wx.code} />
              <span className="fab-wx-temp">{wx.t}°</span>
            </span>
          )}
          <span className="agent-fab-label">Ask Brolly</span>
        </span>
      </button>

      <div className={"agent-panel" + (open ? " open" : "")} role="dialog" aria-label="Brolly, the London Free Guide assistant">
        <div className="agent-head">
          <div className="agent-id">
            <span className="agent-avatar" aria-hidden="true"><BrollyIcon open={rainy} /></span>
            <div>
              <div className="agent-name">Brolly</div>
              <div className="agent-status">{wx ? ("London " + wx.t + "° · " + (rainy ? "wet out, so my brolly's up" : "dry out, brolly's down")) : "your London girl · ask me anything"}</div>
            </div>
          </div>
          <button className="agent-close" onClick={() => setOpen(false)} aria-label="Close">×</button>
        </div>

        <div className="agent-body" ref={scrollRef}>
          {msgs.map((m, i) => (
            <div key={i} className={"agent-msg " + m.role}>{m.text}</div>
          ))}
          {busy && <div className="agent-msg assistant typing"><span></span><span></span><span></span></div>}

          {msgs.length <= 1 && !busy && (
            <div className="agent-suggest">
              {(rainy ? SUGGEST_WET : SUGGEST_DRY).map((s) => (
                <button key={s} className="agent-chip" onClick={() => ask(s)}>{s}</button>
              ))}
            </div>
          )}
        </div>

        <form className="agent-input" onSubmit={(e) => { e.preventDefault(); ask(); }}>
          <input
            value={input}
            onChange={(e) => setInput(e.target.value)}
            placeholder="ask Brolly anything about London…"
            aria-label="Message Brolly"
          />
          <button type="submit" className="agent-send" disabled={busy || !input.trim()} aria-label="Send">→</button>
        </form>
      </div>
    </React.Fragment>
  );
}

Object.assign(window, { GuideAgent });
