// chat-guide.jsx — persistent right-side AI guide
const { useState: useStateCG, useEffect: useEffectCG, useRef: useRefCG } = React;

// Single message bubble
const ChatBubble = ({ from, children, prose }) => {
  const isAI = from === "ai";
  return (
    <div style={{
      display: "flex", flexDirection: "column",
      alignItems: isAI ? "flex-start" : "flex-end",
      gap: 4,
    }}>
      {isAI && (
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 2 }}>
          <StarIcon size={16} />
          <span style={{ fontSize: 12, fontWeight: 500, color: "var(--helm-dark-green)", opacity: .7 }}>Helm</span>
        </div>
      )}
      <div style={{
        maxWidth: "92%",
        padding: isAI ? "0" : "12px 18px",
        borderRadius: isAI ? 0 : 20,
        background: isAI ? "transparent" : "var(--helm-ecru)",
        color: "var(--helm-dark-green)",
        fontFamily: prose ? "var(--font-serif)" : "var(--font-sans)",
        fontWeight: 400,
        fontSize: prose ? 19 : 15,
        lineHeight: prose ? "28px" : "22px",
        whiteSpace: "pre-wrap",
      }}>{children}</div>
    </div>
  );
};

// Quick-reply pill
const QuickReply = ({ children, onClick, primary, soft }) => (
  <button onClick={onClick} style={{
    padding: "14px 22px", borderRadius: 999,
    background: primary ? "var(--helm-chartreuse-2)" : soft ? "var(--helm-soft-chartreuse)" : "transparent",
    color: primary || soft ? "var(--helm-white)" : "var(--helm-dark-green)",
    border: primary || soft ? "none" : "1px solid var(--helm-dark-green)",
    fontFamily: "var(--font-sans)", fontWeight: 600, fontSize: 15,
    textAlign: "left", cursor: "pointer", width: "100%",
    transition: "transform .12s ease",
  }}
    onMouseDown={e => e.currentTarget.style.transform = "translateY(1px)"}
    onMouseUp={e => e.currentTarget.style.transform = "none"}
    onMouseLeave={e => e.currentTarget.style.transform = "none"}>
    {children}
  </button>
);

// Typing dots
const TypingDots = () => (
  <div style={{ display: "flex", gap: 5, padding: "8px 0" }}>
    {[0,1,2].map(i => (
      <span key={i} style={{
        width: 7, height: 7, borderRadius: "50%",
        background: "var(--helm-dark-green)", opacity: .4,
        animation: `helmPulse 1.2s ${i * 0.15}s infinite ease-in-out`,
      }} />
    ))}
  </div>
);

// ── ChatGuide: panel | rail | pill ─────────────────────────────────
const ChatGuide = ({
  style = "panel",     // panel | rail | pill
  title,
  messages,            // [{from:'ai'|'user', text, prose?}]
  quickReplies = [],   // [{label, onClick, primary?, soft?}]
  inputEnabled = true,
  onUserSend,          // async (text) => string  (mocked or real LLM)
  busy = false,
  density = "spacious",
}) => {
  const [draft, setDraft] = useStateCG("");
  const [localMessages, setLocalMessages] = useStateCG([]);
  const [thinking, setThinking] = useStateCG(false);
  const scrollRef = useRefCG(null);

  // Reset local messages when external messages change drastically (screen change)
  const allMessages = [...messages, ...localMessages];

  useEffectCG(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [allMessages.length, thinking, busy]);

  // Reset local messages on screen change
  const lastTitle = useRefCG(title);
  useEffectCG(() => {
    if (lastTitle.current !== title) {
      setLocalMessages([]);
      lastTitle.current = title;
    }
  }, [title]);

  const handleSend = async () => {
    const t = draft.trim();
    if (!t || thinking) return;
    setDraft("");
    setLocalMessages(m => [...m, { from: "user", text: t }]);
    setThinking(true);
    try {
      const reply = onUserSend ? await onUserSend(t, allMessages) :
        "I hear you — I'll keep that in mind as we work through your plan.";
      setLocalMessages(m => [...m, { from: "ai", text: reply, prose: true }]);
    } catch (e) {
      setLocalMessages(m => [...m, { from: "ai", text: "I'm having trouble connecting right now. Let's keep going — you can ask me again in a moment.", prose: true }]);
    } finally {
      setThinking(false);
    }
  };

  // Pill collapsed mode
  const [pillOpen, setPillOpen] = useStateCG(true);
  if (style === "pill" && !pillOpen) {
    const last = [...messages].reverse().find(m => m.from === "ai");
    return (
      <div style={{ position: "fixed", right: 32, bottom: 32, zIndex: 50 }}>
        <button onClick={() => setPillOpen(true)} style={{
          display: "flex", alignItems: "center", gap: 14,
          width: 420, height: 64, padding: "0 24px",
          borderRadius: 32, background: "var(--helm-white)",
          border: "1px solid var(--helm-dark-green)",
          boxShadow: "4px 4px 0 0 var(--helm-dark-green)",
          cursor: "pointer", fontFamily: "var(--font-sans)",
        }}>
          <StarIcon size={22} />
          <span style={{ flex: 1, textAlign: "left", fontWeight: 500, fontSize: 14, color: "var(--helm-dark-green)",
            overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
            {last ? last.text.split("\n")[0] : "Helm is here to help"}
          </span>
          <svg width="18" height="18" viewBox="0 0 20 20" fill="var(--helm-dark-green)">
            <path d="M0 20v-8.7h2.4v6.3h6.3V20zm17.6-11.3V2.4h-6.3V0H20v8.7z"/>
          </svg>
        </button>
      </div>
    );
  }

  // Rail vs panel sizing
  const isRail = style === "rail";
  const width = isRail ? 380 : 460;
  const padding = density === "compact" ? "20px 22px" : "28px 28px";

  return (
    <aside style={{
      position: "fixed", right: isRail ? 0 : 24, top: isRail ? 66 : 90,
      bottom: isRail ? 0 : 24,
      width, zIndex: 50,
      background: "var(--helm-white)",
      border: isRail ? "none" : "1px solid var(--helm-dark-green)",
      borderLeft: isRail ? "1px solid var(--helm-dark-green)" : "1px solid var(--helm-dark-green)",
      borderRadius: isRail ? 0 : 24,
      boxShadow: isRail ? "none" : "4px 4px 0 0 var(--helm-dark-green)",
      display: "flex", flexDirection: "column",
      fontFamily: "var(--font-sans)", color: "var(--helm-dark-green)",
      overflow: "hidden",
    }}>
      {/* Header */}
      <header style={{
        display: "flex", alignItems: "center", justifyContent: "space-between",
        padding: "18px 24px", borderBottom: "1px solid var(--helm-dark-ecru)",
        flexShrink: 0,
      }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <div style={{
            width: 32, height: 32, borderRadius: "50%",
            background: "var(--helm-dark-green)",
            display: "flex", alignItems: "center", justifyContent: "center",
          }}>
            <StarIcon size={18} color="var(--helm-white)" />
          </div>
          <div>
            <div style={{ fontSize: 14, fontWeight: 600, lineHeight: 1.2 }}>Helm</div>
            <div style={{ fontSize: 12, opacity: .6, lineHeight: 1.2 }}>
              {title || "Your guide"}
            </div>
          </div>
        </div>
        {style === "pill" && (
          <button onClick={() => setPillOpen(false)} style={{
            background: "none", border: "none", cursor: "pointer", padding: 4,
            color: "var(--helm-dark-green)",
          }} aria-label="Minimize">
            <svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor">
              <path d="M3 11h14v2H3z"/>
            </svg>
          </button>
        )}
      </header>

      {/* Scroll body */}
      <div ref={scrollRef} style={{
        flex: 1, overflowY: "auto", padding,
        display: "flex", flexDirection: "column", gap: 22,
      }}>
        {allMessages.map((m, i) => (
          <ChatBubble key={i} from={m.from} prose={m.prose}>{m.text}</ChatBubble>
        ))}
        {(busy || thinking) && (
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <StarIcon size={16} className="helm-spin" />
            <TypingDots />
          </div>
        )}
      </div>

      {/* Quick replies */}
      {quickReplies.length > 0 && (
        <div style={{
          padding: density === "compact" ? "10px 22px 14px" : "14px 28px 18px",
          display: "flex", flexDirection: "column", gap: 10,
          flexShrink: 0,
        }}>
          {quickReplies.map((q, i) => (
            <QuickReply key={i} primary={i === 0 && !q.soft && !q.secondary}
              soft={q.soft || (i > 0 && !q.secondary)}
              onClick={q.onClick}>{q.label}</QuickReply>
          ))}
        </div>
      )}

      {/* Free text input */}
      {inputEnabled && (
        <div style={{
          padding: "14px 18px 18px", borderTop: "1px solid var(--helm-dark-ecru)",
          display: "flex", gap: 10, alignItems: "center", flexShrink: 0,
          background: "var(--helm-white)",
        }}>
          <input
            value={draft}
            onChange={e => setDraft(e.target.value)}
            onKeyDown={e => e.key === "Enter" && handleSend()}
            placeholder="Ask Helm anything…"
            disabled={thinking}
            style={{
              flex: 1, padding: "12px 18px", borderRadius: 999,
              border: "1px solid var(--helm-dark-ecru)",
              background: "var(--helm-ecru)",
              fontFamily: "var(--font-sans)", fontSize: 14,
              color: "var(--helm-dark-green)", outline: "none",
            }}
          />
          <button onClick={handleSend} disabled={!draft.trim() || thinking} style={{
            width: 40, height: 40, borderRadius: "50%",
            background: draft.trim() ? "var(--helm-dark-green)" : "var(--helm-dark-ecru)",
            color: "var(--helm-white)", border: "none",
            cursor: draft.trim() && !thinking ? "pointer" : "not-allowed",
            display: "flex", alignItems: "center", justifyContent: "center",
            flexShrink: 0,
          }} aria-label="Send">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
              <path d="M2 21l21-9L2 3v7l15 2-15 2z"/>
            </svg>
          </button>
        </div>
      )}
    </aside>
  );
};

window.ChatGuide = ChatGuide;
window.ChatBubble = ChatBubble;
window.QuickReply = QuickReply;
