// GPS boxd assistant — floating sidekick. Ask questions ("what shipped today", "what do
// we buy in the next 2 weeks"); answers come from the server's predefined math. Optional
// Google connect unlocks Drive Q&A + emailing a report (always with an explicit Send click).
const { useState: useStateAI, useEffect: useEffectAI, useRef: useRefAI } = React;

// Lightweight SVG bar/line chart (no library).
function ChartView({ chart }) {
  const pts = (chart && chart.points) || [];
  if (!pts.length) return null;
  const W = 360, H = 180, pad = 30;
  const iw = W - pad * 2, ih = H - pad * 2;
  const max = Math.max(1, ...pts.map((p) => p.value));
  const x = (i) => pad + (pts.length === 1 ? iw / 2 : (i / (pts.length - 1)) * iw);
  const bx = (i) => pad + (i + 0.15) * (iw / pts.length);
  const bw = (iw / pts.length) * 0.7;
  const y = (v) => pad + ih - (v / max) * ih;
  const red = window.GPS_RED || "#C41230";
  return (
    <div className="mt-2 bg-zinc-900 border border-zinc-800 rounded-xl p-2 max-w-full overflow-x-auto">
      {chart.title && <div className="text-[12px] text-zinc-300 mb-1 px-1">{chart.title}</div>}
      <svg width={W} height={H} className="block">
        <line x1={pad} y1={pad + ih} x2={pad + iw} y2={pad + ih} stroke="#3f3f46" />
        {chart.type === "line"
          ? <polyline fill="none" stroke={red} strokeWidth="2" points={pts.map((p, i) => `${x(i)},${y(p.value)}`).join(" ")} />
          : pts.map((p, i) => <rect key={i} x={bx(i)} y={y(p.value)} width={bw} height={pad + ih - y(p.value)} fill={red} rx="2" />)}
        {chart.type === "line" && pts.map((p, i) => <circle key={i} cx={x(i)} cy={y(p.value)} r="2.5" fill="#fff" />)}
        {pts.map((p, i) => <text key={"v" + i} x={chart.type === "line" ? x(i) : bx(i) + bw / 2} y={y(p.value) - 4} fill="#a1a1aa" fontSize="9" textAnchor="middle">{p.value}</text>)}
        {pts.map((p, i) => <text key={"l" + i} x={chart.type === "line" ? x(i) : bx(i) + bw / 2} y={H - 9} fill="#71717a" fontSize="9" textAnchor="middle">{String(p.label).slice(0, 8)}</text>)}
      </svg>
    </div>
  );
}

// Marky's icon: use assets/marky.png if you've dropped one in, else the built-in SVG.
function MarkyIcon({ className }) {
  return (
    <img src="assets/marky.png" alt="Marky" className={"object-cover " + (className || "")}
      onError={(e) => { if (!e.target.dataset.fb) { e.target.dataset.fb = "1"; e.target.src = "assets/marky.svg"; } }} />
  );
}

function AssistantWidget({ user }) {
  const [open, setOpen] = useStateAI(false);
  const [msgs, setMsgs] = useStateAI([]); // {role:'user'|'model', text, draft?}
  const [input, setInput] = useStateAI("");
  const [busy, setBusy] = useStateAI(false);
  const [google, setGoogle] = useStateAI({ assistant: false, configured: false, connected: false, email: null });
  const scrollRef = useRefAI(null);

  const loadGoogle = () => fetch("/api/google/status").then(r => r.ok ? r.json() : null).then(d => d && setGoogle(d)).catch(() => {});
  useEffectAI(() => { loadGoogle(); }, []);
  // Handle the return from Google's OAuth redirect.
  useEffectAI(() => {
    const q = new URLSearchParams(window.location.search);
    if (q.get("google") === "connected") { window.gpsToast && window.gpsToast({ message: "Google connected", tone: "ok" }); loadGoogle(); setOpen(true); }
    else if (q.get("google") === "error") { window.gpsToast && window.gpsToast({ message: "Google connect failed: " + (q.get("reason") || ""), tone: "warn" }); }
    if (q.has("google")) { q.delete("google"); q.delete("reason"); window.history.replaceState({}, "", window.location.pathname + (q.toString() ? "?" + q : "")); }
  }, []);
  useEffectAI(() => { if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight; }, [msgs, busy]);

  async function connectGoogle() {
    try {
      const r = await fetch("/api/google/auth-url");
      const d = await r.json();
      if (d.url) window.location = d.url; else window.gpsToast && window.gpsToast({ message: d.error || "Google not configured", tone: "warn" });
    } catch { window.gpsToast && window.gpsToast({ message: "Couldn't start Google connect", tone: "warn" }); }
  }
  async function disconnectGoogle() { await fetch("/api/google/disconnect", { method: "POST" }).catch(() => {}); loadGoogle(); }

  async function ask(q) {
    const question = (q != null ? q : input).trim();
    if (!question || busy) return;
    setInput("");
    const history = msgs.map(m => ({ role: m.role, text: m.text }));
    setMsgs(m => [...m, { role: "user", text: question }]);
    setBusy(true);
    try {
      const r = await fetch("/api/assistant", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ question, history }) });
      const d = await r.json().catch(() => ({}));
      if (!r.ok) setMsgs(m => [...m, { role: "model", text: d.error === "assistant not configured" ? "The assistant isn't set up yet (missing API key)." : (d.error || "Something went wrong.") }]);
      else setMsgs(m => [...m, { role: "model", text: d.answer || "(no answer)", draft: d.draft || null, proposals: d.proposals || [], chart: d.chart || null }]);
    } catch { setMsgs(m => [...m, { role: "model", text: "Couldn't reach the assistant." }]); }
    finally { setBusy(false); }
  }

  async function applyProposal(pr, msgIdx, propIdx) {
    try {
      const r = await fetch("/api/assistant/apply", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(pr) });
      const d = await r.json().catch(() => ({}));
      if (!r.ok) { window.gpsToast && window.gpsToast({ message: d.error || "Apply failed", tone: "warn" }); return false; }
      window.gpsToast && window.gpsToast({ message: "Applied · " + (d.applied || "done"), tone: "ok" });
      setMsgs(m => m.map((x, i) => i === msgIdx ? { ...x, proposals: x.proposals.map((p, j) => j === propIdx ? { ...p, applied: true } : p) } : x));
      if (window.gpsRefreshData) window.gpsRefreshData();
      return true;
    } catch { window.gpsToast && window.gpsToast({ message: "Apply failed", tone: "warn" }); return false; }
  }
  async function applyAll(list, msgIdx) {
    for (let j = 0; j < list.length; j++) if (!list[j].applied) await applyProposal(list[j], msgIdx, j);
  }
  async function sendDraft(draft, idx) {
    try {
      const r = await fetch("/api/assistant/send-email", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ to_user_id: draft.to_user_id, report_type: draft.report_type }) });
      const d = await r.json().catch(() => ({}));
      if (!r.ok) { window.gpsToast && window.gpsToast({ message: d.error || "Send failed", tone: "warn" }); return; }
      window.gpsToast && window.gpsToast({ message: `Emailed ${draft.to_name || draft.to_email}`, tone: "ok" });
      setMsgs(m => m.map((x, i) => i === idx ? { ...x, draft: { ...x.draft, sent: true } } : x));
    } catch { window.gpsToast && window.gpsToast({ message: "Send failed", tone: "warn" }); }
  }

  const suggestions = ["What's low on stock?", "What do we need to buy in the next 2 weeks?", "How many did we ship today?", "Any jobs in progress?"];

  // Don't show a dead button before the Gemini key is configured on the server.
  if (!google.assistant) return null;

  return (
    <>
      {!open && (
        <button onClick={() => setOpen(true)} title="Ask Marky"
          className="fixed bottom-5 right-5 z-40 h-14 w-14 rounded-full shadow-lg overflow-hidden flex items-center justify-center">
          <MarkyIcon className="h-14 w-14" />
        </button>
      )}
      {open && (
        <div className="fixed bottom-5 right-5 z-40 w-[min(420px,calc(100vw-24px))] h-[min(620px,calc(100vh-40px))] bg-zinc-950 border border-zinc-800 rounded-2xl shadow-2xl flex flex-col overflow-hidden text-zinc-100">
          <div className="flex items-center justify-between px-4 py-3 border-b border-zinc-800 bg-zinc-900/60">
            <div className="flex items-center gap-2">
              <MarkyIcon className="h-7 w-7 rounded-full" />
              <span className="font-display text-[18px] tracking-wider">Marky</span>
            </div>
            <button onClick={() => setOpen(false)} className="h-8 w-8 rounded-lg text-zinc-400 hover:bg-zinc-800">✕</button>
          </div>

          <div className="px-4 py-2 border-b border-zinc-800/70 flex items-center justify-between text-[12px]">
            {google.connected
              ? <span className="text-emerald-400 flex items-center gap-1.5"><span className="h-2 w-2 rounded-full bg-emerald-500 inline-block" />Google · {google.email}</span>
              : <span className="text-zinc-500">Drive & email need Google</span>}
            {google.connected
              ? <button onClick={disconnectGoogle} className="text-zinc-500 hover:text-zinc-300 underline underline-offset-2">Disconnect</button>
              : <button onClick={connectGoogle} disabled={!google.configured} className="text-zinc-200 bg-zinc-800 hover:bg-zinc-700 rounded-md px-2.5 py-1 disabled:opacity-40">Connect Google</button>}
          </div>

          <div ref={scrollRef} className="flex-1 overflow-y-auto px-4 py-4 space-y-3">
            {msgs.length === 0 && (
              <div className="space-y-2">
                <div className="text-zinc-500 text-[13px]">Ask about stock, shipments, builds, or what to buy.</div>
                {suggestions.map(s => (
                  <button key={s} onClick={() => ask(s)} className="block w-full text-left text-[13px] text-zinc-300 bg-zinc-900 border border-zinc-800 rounded-lg px-3 py-2 hover:bg-zinc-800">{s}</button>
                ))}
              </div>
            )}
            {msgs.map((m, i) => (
              <div key={i} className={m.role === "user" ? "text-right" : "text-left"}>
                <div className={`inline-block max-w-[85%] text-[14px] rounded-2xl px-3 py-2 whitespace-pre-wrap ${m.role === "user" ? "bg-[#C41230] text-white" : "bg-zinc-900 border border-zinc-800 text-zinc-100"}`}>{m.text}</div>
                {m.chart && <ChartView chart={m.chart} />}
                {m.proposals && m.proposals.length > 0 && (
                  <div className="mt-2 max-w-[85%] space-y-2">
                    {m.proposals.length > 1 && !m.proposals.every(p => p.applied) && (
                      <button onClick={() => applyAll(m.proposals, i)}
                        className="h-8 px-3 rounded-lg bg-amber-600 hover:bg-amber-500 text-white text-[12px] font-semibold">
                        Apply all ({m.proposals.filter(p => !p.applied).length})
                      </button>
                    )}
                    {m.proposals.map((pr, j) => (
                      <div key={j} className="text-left bg-zinc-900 border border-amber-500/40 rounded-xl p-3">
                        <div className="text-[12px] text-amber-300 mb-1">Proposed change</div>
                        <div className="text-[13px] text-zinc-200">{pr.summary || `${pr.field}: ${pr.from} → ${pr.to}`}</div>
                        {pr.applied
                          ? <div className="text-emerald-400 text-[12px] mt-2">✓ Applied</div>
                          : <button onClick={() => applyProposal(pr, i, j)} className="mt-2 h-8 px-3 rounded-lg bg-amber-600 hover:bg-amber-500 text-white text-[12px] font-semibold">Apply</button>}
                      </div>
                    ))}
                  </div>
                )}
                {m.draft && (
                  <div className="mt-2 text-left bg-zinc-900 border border-amber-500/30 rounded-xl p-3 max-w-[85%]">
                    <div className="text-[12px] text-amber-300 mb-1">Draft email → {m.draft.to_name || m.draft.to_email}</div>
                    <div className="text-[12px] text-zinc-400 font-medium">{m.draft.subject}</div>
                    <pre className="text-[11px] text-zinc-500 mt-1 whitespace-pre-wrap font-sans max-h-24 overflow-y-auto">{m.draft.body}</pre>
                    {m.draft.sent
                      ? <div className="text-emerald-400 text-[12px] mt-2">✓ Sent</div>
                      : <button onClick={() => sendDraft(m.draft, i)} className="mt-2 h-8 px-3 rounded-lg bg-emerald-600 hover:bg-emerald-500 text-white text-[12px] font-semibold">Send email</button>}
                  </div>
                )}
              </div>
            ))}
            {busy && <div className="text-zinc-500 text-[13px]">Thinking…</div>}
          </div>

          <div className="p-3 border-t border-zinc-800 flex gap-2">
            <input value={input} onChange={e => setInput(e.target.value)} onKeyDown={e => { if (e.key === "Enter") ask(); }}
              placeholder="Ask a question…" disabled={busy}
              className="flex-1 bg-zinc-800 border border-zinc-700 focus:border-zinc-500 rounded-xl px-3 py-2.5 text-[15px] text-zinc-100 placeholder-zinc-400 caret-white outline-none" />
            <button onClick={() => ask()} disabled={busy || !input.trim()}
              className="h-10 px-4 rounded-xl text-white font-semibold text-[14px] disabled:opacity-40" style={{ background: window.GPS_RED }}>Ask</button>
          </div>
        </div>
      )}
    </>
  );
}

window.AssistantWidget = AssistantWidget;
