// ---------- Chatbot widget ----------
// Floating chat bubble + expandable panel.
// Available site-wide (mounted once in App).
// Uses window.claude.complete — no API key, runs against viewer's quota.

function Chatbot() {
  const { useState, useRef, useEffect } = React;

  const [open, setOpen] = useState(false);
  const [unread, setUnread] = useState(false);
  const [input, setInput] = useState("");
  const [loading, setLoading] = useState(false);
  const [messages, setMessages] = useState([
    {
      role: "assistant",
      content:
        "Hi — I'm GCM's site assistant. I can walk you through how our managed camera systems work, what they cost to deploy, theft prevention specifics, time lapse delivery, or any technical detail of the platform. What are you trying to solve on your jobsite?",
    },
  ]);

  const scrollRef = useRef(null);
  const inputRef = useRef(null);

  // System prompt — consultative + technical, brand-aware, knows when to hand off.
  const systemPrompt = `You are the site assistant for Gilman Construction Media (GCM), an AI-powered construction security camera and jobsite time lapse company based in San Diego, CA, serving general contractors, developers, and project owners across the United States.

ABOUT GCM:
- Provides fully managed construction security camera systems with AI-driven jobsite monitoring, theft prevention, and progress documentation.
- Core offerings: AI-powered jobsite security cameras, construction time lapse cameras, unified platform combining cameras + drones + wearables, real-time monitoring.
- Clients include Hensel Phelps, PCL, Swinerton, Whiting-Turner, Kaiser Permanente, CBRE, DPR, Balfour Beatty, Trammell Crow, Starbucks, PWI, and many others.
- Contact: 833.700.4426 / info@gilmanconstructionmedia.com / Contact page on this site.

TONE:
- Consultative and technical, but warm — talk like a knowledgeable project engineer, not a sales bot or a scripted chatbot.
- Be specific. Use construction vocabulary correctly (GC, sub, super, owner, phase, mobilization, punch list, AHJ, etc.) when it fits.
- Avoid hype words ("revolutionary", "cutting-edge", "synergy", "leverage"). Avoid marketing fluff.
- Short paragraphs. Use bullets when comparing options or listing specs. Plain text only — no markdown headers, no bold.
- It's fine to say "I don't know the specific spec for that — let me get you to someone who does" instead of guessing.

WHAT YOU CAN HELP WITH:
- Explaining how the camera + AI monitoring works at a high level
- Talking through use cases (theft deterrence, progress docs, safety incidents, OAC meetings, marketing time lapse)
- Discussing typical deployment (power, connectivity, mounting on light towers / fence / building)
- Comparing approaches (cellular vs. site WiFi, managed vs. self-monitored, etc.)
- Pointing visitors to the right page on the site (Platform, Case Studies, About, Leadership, Contact)

WHAT TO ROUTE OUT:
- Specific pricing or quotes: never quote a number. Say pricing depends on site size, camera count, project duration, monitoring level — and route them to the Contact page form, 833.700.4426, or info@gilmanconstructionmedia.com.
- Contracts, SLAs, legal questions, NDAs: route to the team via Contact.
- Anything requiring access to their account, invoices, or live footage: route to support at info@gilmanconstructionmedia.com.

KEEP IT SHORT: Most replies should be 2–4 sentences. Only go longer when the user asks a genuinely technical multi-part question.`;

  // auto-scroll on new message
  useEffect(() => {
    const el = scrollRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [messages, loading, open]);

  // focus input on open
  useEffect(() => {
    if (open) {
      setUnread(false);
      setTimeout(() => inputRef.current && inputRef.current.focus(), 50);
    }
  }, [open]);

  // Esc to close
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") setOpen(false); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open]);

  const send = async () => {
    const text = input.trim();
    if (!text || loading) return;
    const next = [...messages, { role: "user", content: text }];
    setMessages(next);
    setInput("");
    setLoading(true);

    try {
      const reply = await window.claude.complete({
        messages: [
          { role: "user", content: systemPrompt },
          { role: "assistant", content: "Understood. I'll talk like a knowledgeable GCM rep — consultative, technical, no marketing fluff, route pricing and account questions to the team." },
          ...next.map((m) => ({ role: m.role, content: m.content })),
        ],
      });
      setMessages([...next, { role: "assistant", content: (reply || "").trim() || "Sorry — I didn't catch that. Could you rephrase?" }]);
      if (!open) setUnread(true);
    } catch (err) {
      console.error("chatbot error", err);
      setMessages([
        ...next,
        {
          role: "assistant",
          content:
            "Sorry — I hit an error reaching the assistant. For anything urgent, give us a call at 833.700.4426 or email info@gilmanconstructionmedia.com.",
        },
      ]);
    } finally {
      setLoading(false);
    }
  };

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

  // ---- styles ----
  const cbBubbleStyle = {
    position: "fixed",
    right: 24,
    bottom: 24,
    width: 60,
    height: 60,
    borderRadius: "50%",
    background: "var(--red, #c42026)",
    color: "#fff",
    border: "none",
    boxShadow: "0 10px 28px rgba(12,35,64,0.28)",
    cursor: "pointer",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    zIndex: 9998,
    transition: "transform .15s ease, box-shadow .15s ease, background .15s ease",
    padding: 0,
  };

  const cbPanelStyle = {
    position: "fixed",
    right: 24,
    bottom: 96,
    width: 380,
    maxWidth: "calc(100vw - 32px)",
    height: 560,
    maxHeight: "calc(100vh - 120px)",
    background: "#fff",
    borderRadius: 14,
    boxShadow: "0 24px 60px rgba(12,35,64,0.30), 0 4px 14px rgba(12,35,64,0.12)",
    display: open ? "flex" : "none",
    flexDirection: "column",
    overflow: "hidden",
    zIndex: 9999,
    fontFamily: '"Open Sans", -apple-system, BlinkMacSystemFont, sans-serif',
    border: "1px solid rgba(12,35,64,0.08)",
  };

  const cbHeaderStyle = {
    background: "var(--navy, #0c2340)",
    color: "#fff",
    padding: "16px 18px",
    display: "flex",
    alignItems: "center",
    gap: 12,
    position: "relative",
  };

  const cbAvatarStyle = {
    width: 36,
    height: 36,
    borderRadius: "50%",
    background: "var(--red, #c42026)",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    flexShrink: 0,
    fontFamily: "Lato, sans-serif",
    fontWeight: 900,
    fontSize: 14,
    letterSpacing: "0.04em",
  };

  const cbListStyle = {
    flex: "1 1 auto",
    overflowY: "auto",
    padding: "18px 16px 8px",
    background: "var(--paper, #f7f5f2)",
    display: "flex",
    flexDirection: "column",
    gap: 10,
  };

  const cbInputBarStyle = {
    borderTop: "1px solid var(--rule, #e5e7ee)",
    padding: 10,
    display: "flex",
    gap: 8,
    alignItems: "flex-end",
    background: "#fff",
  };

  const cbTextareaStyle = {
    flex: 1,
    border: "1px solid var(--rule, #e5e7ee)",
    borderRadius: 10,
    padding: "10px 12px",
    fontFamily: "inherit",
    fontSize: 14,
    lineHeight: 1.4,
    resize: "none",
    outline: "none",
    color: "var(--ink, #14161c)",
    background: "#fff",
    maxHeight: 100,
  };

  const cbSendStyle = {
    background: "var(--red, #c42026)",
    color: "#fff",
    border: "none",
    borderRadius: 10,
    width: 40,
    height: 40,
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    cursor: input.trim() && !loading ? "pointer" : "default",
    opacity: input.trim() && !loading ? 1 : 0.5,
    transition: "background .15s ease, opacity .15s ease",
    flexShrink: 0,
    padding: 0,
  };

  return (
    <React.Fragment>
      {/* Panel */}
      <div role="dialog" aria-label="Chat with GCM" style={cbPanelStyle}>
        <div style={cbHeaderStyle}>
          <div style={cbAvatarStyle}>GCM</div>
          <div style={{flex: 1, minWidth: 0}}>
            <div style={{fontFamily: "Lato, sans-serif", fontWeight: 800, fontSize: 15, lineHeight: 1.1}}>
              Gilman Construction Media
            </div>
            <div style={{fontSize: 12, color: "rgba(255,255,255,0.7)", marginTop: 2, display: "flex", alignItems: "center", gap: 6}}>
              <span style={{display: "inline-block", width: 7, height: 7, borderRadius: "50%", background: "#3ddc91"}}></span>
              <span>Assistant — typically replies instantly</span>
            </div>
          </div>
          <button
            type="button"
            aria-label="Close chat"
            onClick={() => setOpen(false)}
            style={{
              background: "transparent",
              border: "none",
              color: "rgba(255,255,255,0.85)",
              cursor: "pointer",
              padding: 6,
              borderRadius: 6,
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
            }}
          >
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.25" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M18 6L6 18M6 6l12 12" />
            </svg>
          </button>
        </div>

        <div ref={scrollRef} style={cbListStyle}>
          {messages.map((m, i) => (
            <div
              key={i}
              style={{
                alignSelf: m.role === "user" ? "flex-end" : "flex-start",
                maxWidth: "85%",
                background: m.role === "user" ? "var(--navy, #0c2340)" : "#fff",
                color: m.role === "user" ? "#fff" : "var(--ink, #14161c)",
                border: m.role === "user" ? "none" : "1px solid var(--rule, #e5e7ee)",
                padding: "10px 14px",
                borderRadius: 14,
                borderBottomRightRadius: m.role === "user" ? 4 : 14,
                borderBottomLeftRadius: m.role === "user" ? 14 : 4,
                fontSize: 14,
                lineHeight: 1.5,
                whiteSpace: "pre-wrap",
                wordWrap: "break-word",
                boxShadow: m.role === "user" ? "none" : "0 1px 2px rgba(12,35,64,0.04)",
              }}
            >
              {m.content}
            </div>
          ))}
          {loading && (
            <div
              style={{
                alignSelf: "flex-start",
                background: "#fff",
                border: "1px solid var(--rule, #e5e7ee)",
                padding: "12px 16px",
                borderRadius: 14,
                borderBottomLeftRadius: 4,
                display: "flex",
                gap: 5,
              }}
              aria-label="Assistant is typing"
            >
              <span className="cb-dot" style={dotStyle(0)}></span>
              <span className="cb-dot" style={dotStyle(0.15)}></span>
              <span className="cb-dot" style={dotStyle(0.3)}></span>
            </div>
          )}
        </div>

        <div style={cbInputBarStyle}>
          <textarea
            ref={inputRef}
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyDown={onKeyDown}
            placeholder="Ask about cameras, time lapse, deployment…"
            rows={1}
            style={cbTextareaStyle}
            disabled={loading}
          />
          <button
            type="button"
            aria-label="Send message"
            onClick={send}
            disabled={!input.trim() || loading}
            style={cbSendStyle}
          >
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.25" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M22 2L11 13" />
              <path d="M22 2l-7 20-4-9-9-4 20-7z" />
            </svg>
          </button>
        </div>

        <div style={{fontSize: 11, color: "var(--muted, #4b556a)", padding: "6px 14px 10px", background: "#fff", borderTop: "1px solid var(--rule, #e5e7ee)", textAlign: "center"}}>
          For urgent issues, call <a href="tel:8337004426" style={{color: "var(--navy)", fontWeight: 700, textDecoration: "none"}}>833.700.4426</a>
        </div>
      </div>

      {/* Floating bubble */}
      <button
        type="button"
        aria-label={open ? "Close chat" : "Open chat"}
        aria-expanded={open}
        onClick={() => setOpen((v) => !v)}
        className="cb-bubble"
        style={cbBubbleStyle}
      >
        {open ? (
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
            <path d="M18 6L6 18M6 6l12 12" />
          </svg>
        ) : (
          <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
            <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
          </svg>
        )}
        {unread && !open && (
          <span
            aria-hidden="true"
            style={{
              position: "absolute",
              top: 6,
              right: 6,
              width: 12,
              height: 12,
              borderRadius: "50%",
              background: "#3ddc91",
              border: "2px solid #fff",
            }}
          ></span>
        )}
      </button>
    </React.Fragment>
  );
}

function dotStyle(delay) {
  return {
    width: 7,
    height: 7,
    borderRadius: "50%",
    background: "var(--muted, #4b556a)",
    display: "inline-block",
    animation: "cb-bounce 1s infinite ease-in-out",
    animationDelay: `${delay}s`,
  };
}

Object.assign(window, { Chatbot });
