"use client";

import dynamic from "next/dynamic";
import { useState, useEffect, useRef, useCallback } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { useAuth } from "@/context/AuthContext";
import { createStompClient } from "@/lib/chatSocket";

const API_BASE = "";

//Checks if a filename looks like an image based on its extension
function isImageFilename(name) {
  return /\.(jpe?g|png|gif|webp|bmp|svg)$/i.test(name || "");
}

//Shows an image inline or a download link for other file types
function AttachmentPreview({ url, name, token }) {
  const [blobUrl, setBlobUrl] = useState(null);
  const isImage = isImageFilename(name);

  useEffect(() => {
    if (!url || !token) return;
    let objectUrl;
    fetch(url, { headers: { Authorization: `Bearer ${token}` } })
      .then((r) => (r.ok ? r.blob() : null))
      .then((blob) => {
        if (blob) {
          objectUrl = URL.createObjectURL(blob);
          setBlobUrl(objectUrl);
        }
      })
      .catch(() => {});
    return () => { if (objectUrl) URL.revokeObjectURL(objectUrl); };
  }, [url, token]);

  if (isImage) {
    return (
      <div style={{ marginTop: "0.5rem" }}>
        {blobUrl ? (
          <img
            src={blobUrl}
            alt={name || "attachment"}
            style={{ maxWidth: "220px", maxHeight: "220px", borderRadius: "8px", cursor: "pointer", display: "block" }}
            onClick={() => window.open(blobUrl, "_blank")}
          />
        ) : (
          <span style={{ fontSize: "0.8rem", opacity: 0.7 }}>📎 Loading image…</span>
        )}
      </div>
    );
  }

  return (
    <div style={{ marginTop: "0.4rem" }}>
      <a
        href="#"
        style={{ color: "inherit", fontSize: "0.85rem", opacity: 0.85 }}
        onClick={(e) => {
          e.preventDefault();
          if (!blobUrl) return;
          const a = document.createElement("a");
          a.href = blobUrl;
          a.download = name || "attachment";
          a.click();
        }}
      >
        📎 {name || "Attachment"}
      </a>
    </div>
  );
}

//Returns true when the screen width is below 640px
function useIsMobile() {
  const [isMobile, setIsMobile] = useState(false);
  useEffect(() => {
    const check = () => setIsMobile(window.innerWidth < 640);
    check();
    window.addEventListener("resize", check);
    return () => window.removeEventListener("resize", check);
  }, []);
  return isMobile;
}

//AI chat page with a conversation sidebar, supports switching to a human agent and sending file attachments
function AiChatPage() {
  const { user, token, loading: authLoading } = useAuth();
  const router = useRouter();
  const searchParams = useSearchParams();
  const conversationIdParam = searchParams.get("id");
  const isMobile = useIsMobile();

  const [conversation, setConversation] = useState(null);
  const [messages, setMessages] = useState([]);
  const [input, setInput] = useState("");
  const [sending, setSending] = useState(false);
  const [loadingConv, setLoadingConv] = useState(true);
  const [error, setError] = useState(null);
  const [conversations, setConversations] = useState([]);
  const [convsLoading, setConvsLoading] = useState(false);
  const [closedExpanded, setClosedExpanded] = useState(false);
  const [selectedFile, setSelectedFile] = useState(null);
  const [botTyping, setBotTyping] = useState(false);
  const [switchingConv, setSwitchingConv] = useState(false);

  const messagesEndRef = useRef(null);
  const messagesAreaRef = useRef(null);
  const inputRef = useRef(null);
  const stompRef = useRef(null);
  const lastMessageIdRef = useRef(null);
  const fileInputRef = useRef(null);
  const lastScrolledIdRef = useRef(null);
  const initialLoadDoneRef = useRef(false);
  const botTypingTimeoutRef = useRef(null);

  useEffect(() => {
    if (!authLoading && !user) {
      router.push("/login?next=" + encodeURIComponent("/ai-chat" + (conversationIdParam ? `?id=${conversationIdParam}` : "")));
    }
  }, [authLoading, user, router, conversationIdParam]);

  useEffect(() => {
    if (messages.length === 0) return;
    const lastMsg = messages[messages.length - 1];
    if (lastMsg.id === lastScrolledIdRef.current) return;
    if (!initialLoadDoneRef.current) return;
    lastScrolledIdRef.current = lastMsg.id;
    const area = messagesAreaRef.current;
    if (!area) return;
    const nearBottom = area.scrollHeight - area.scrollTop - area.clientHeight < 80;
    if (nearBottom) {
      area.scrollTop = area.scrollHeight;
    }
  }, [messages]);

  useEffect(() => {
    if (!botTyping) return;
    const area = messagesAreaRef.current;
    if (!area) return;
    const nearBottom = area.scrollHeight - area.scrollTop - area.clientHeight < 80;
    if (nearBottom) area.scrollTop = area.scrollHeight;
  }, [botTyping]);

  //Loads all messages for a conversation and scrolls to the bottom
  const fetchMessages = useCallback(async (convId) => {
    if (!token || !convId) return;
    initialLoadDoneRef.current = false;
    try {
      const res = await fetch(`${API_BASE}/api/v1/chat/conversations/${convId}/messages`, {
        headers: { Authorization: `Bearer ${token}` },
      });
      if (!res.ok) return;
      const data = await res.json();
      if (Array.isArray(data)) {
        setMessages(data);
        if (data.length > 0) {
          lastMessageIdRef.current = data[data.length - 1].id;
          lastScrolledIdRef.current = data[data.length - 1].id;
        }
        setTimeout(() => {
          const area = messagesAreaRef.current;
          if (area) area.scrollTop = area.scrollHeight;
          initialLoadDoneRef.current = true;
        }, 50);
      }
    } catch {
    }
  }, [token]);

  //Fetches a single conversation's details and stores it
  const fetchConversation = useCallback(async (convId) => {
    if (!token || !convId) return null;
    try {
      const res = await fetch(`${API_BASE}/api/v1/chat/conversations/${convId}`, {
        headers: { Authorization: `Bearer ${token}` },
      });
      if (!res.ok) return null;
      const data = await res.json();
      setConversation(data);
      return data;
    } catch {
      return null;
    }
  }, [token]);

  const fetchConversations = useCallback(async () => {
    if (!token) return;
    setConvsLoading(true);
    try {
      const res = await fetch(`${API_BASE}/api/v1/chat/conversations`, {
        headers: { Authorization: `Bearer ${token}` },
      });
      if (!res.ok) return;
      const data = await res.json();
      setConversations(Array.isArray(data) ? data : (data.content ?? []));
    } catch {
      // silent
    } finally {
      setConvsLoading(false);
    }
  }, [token]);

  //Connects the WebSocket and subscribes to new messages and conversation updates
  const connectStomp = useCallback((convId) => {
    if (stompRef.current) {
      stompRef.current.deactivate();
      stompRef.current = null;
    }
    const client = createStompClient(token);
    client.onConnect = () => {
      client.subscribe(`/topic/chat/conversations/${convId}`, (frame) => {
        try {
          const msg = JSON.parse(frame.body);
          setMessages((prev) => prev.some((m) => m.id === msg.id) ? prev : [...prev, msg]);
          lastMessageIdRef.current = msg.id;
          if (botTypingTimeoutRef.current) clearTimeout(botTypingTimeoutRef.current);
          setBotTyping(false);
        } catch { /* silent */ }
      });
      const convTopic = user?.role === "CUSTOMER"
        ? `/user/queue/chat/conversations`
        : `/topic/chat/conversations`;
      client.subscribe(convTopic, (frame) => {
        try {
          const conv = JSON.parse(frame.body);
          if (conv.id === convId) setConversation(conv);
          setConversations((prev) => prev.map((c) => c.id === conv.id ? conv : c));
        } catch { /* silent */ }
      });
    };
    stompRef.current = client;
    client.activate();
  }, [token, user?.role]);

  useEffect(() => {
    if (!token || authLoading) return;

    let stale = false;

    async function init() {
      setLoadingConv(true);
      setError(null);

      let convId = conversationIdParam ? Number(conversationIdParam) : null;

      if (!convId) {
        try {
          const res = await fetch(`${API_BASE}/api/v1/chat/conversations`, {
            headers: { Authorization: `Bearer ${token}` },
          });
          if (stale) return;
          if (res.ok) {
            const list = await res.json();
            const openAi = Array.isArray(list)
              ? list.find((c) => c.status === "OPEN" && c.mode === "AUTOMATED")
              : null;
            if (openAi) convId = openAi.id;
          }
        } catch {
          if (stale) return;
          setError("Failed to load conversations.");
        }
      }

      if (!convId) {
        try {
          const res = await fetch(`${API_BASE}/api/v1/chat/conversations`, {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              Authorization: `Bearer ${token}`,
            },
            body: JSON.stringify({}),
          });
          if (stale) return;
          if (res.ok) {
            const conv = await res.json();
            convId = conv.id;
          }
        } catch {
          if (stale) return;
        }
      }

      if (!convId) {
        await fetchConversations();
        if (stale) return;
        setLoadingConv(false);
        return;
      }

      await Promise.all([
        fetchConversation(convId),
        fetchMessages(convId),
        fetchConversations(),
      ]);
      if (stale) return;
      setLoadingConv(false);
      connectStomp(convId);
      router.replace(`/ai-chat?id=${convId}`, { scroll: false });
    }

    init();

    return () => {
      stale = true;
      if (stompRef.current) { stompRef.current.deactivate(); stompRef.current = null; }
    };
  }, [token, authLoading, conversationIdParam, fetchConversation, fetchMessages, connectStomp, fetchConversations, router]);

  //Decides whether to send a text message or an attachment
  async function handleSend(e) {
    e?.preventDefault();
    const text = input.trim();
    if ((!text && !selectedFile) || sending || !conversation) return;
    if (selectedFile) {
      await handleSendAttachment(text);
    } else {
      await handleSendText(text);
    }
  }

  //Sends a plain text message and shows a bot typing indicator
  async function handleSendText(text) {
    setInput("");
    setSending(true);
    setError(null);

    try {
      const res = await fetch(`${API_BASE}/api/v1/chat/conversations/${conversation.id}/messages`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({ content: text }),
      });

      if (res.status === 401) {
        router.push("/login?next=" + encodeURIComponent("/ai-chat"));
        return;
      }

      if (!res.ok) {
        const data = await res.json().catch(() => null);
        setError(data?.message || "Failed to send message.");
        setInput(text);
        return;
      }

      const msg = await res.json();
      setMessages((prev) => prev.some((m) => m.id === msg.id) ? prev : [...prev, msg]);
      lastMessageIdRef.current = msg.id;
      if (!isEscalated) {
        setBotTyping(true);
        if (botTypingTimeoutRef.current) clearTimeout(botTypingTimeoutRef.current);
        botTypingTimeoutRef.current = setTimeout(() => setBotTyping(false), 30000);
      }
    } catch {
      setError("Network error. Please try again.");
      setInput(text);
    } finally {
      setSending(false);
      inputRef.current?.focus();
    }
  }

  //Uploads a file as an attachment, with an optional caption
  async function handleSendAttachment(optionalText) {
    setSending(true);
    setError(null);
    const file = selectedFile;
    setSelectedFile(null);
    setInput("");

    try {
      const formData = new FormData();
      formData.append("file", file);
      if (optionalText) formData.append("content", optionalText);

      const res = await fetch(
        `${API_BASE}/api/v1/chat/conversations/${conversation.id}/attachments`,
        {
          method: "POST",
          headers: { Authorization: `Bearer ${token}` },
          body: formData,
        }
      );

      if (res.status === 401) {
        router.push("/login?next=" + encodeURIComponent("/ai-chat"));
        return;
      }

      if (!res.ok) {
        const data = await res.json().catch(() => null);
        setError(data?.message || "Failed to send attachment.");
        setSelectedFile(file);
        setInput(optionalText);
        return;
      }

      const msg = await res.json();
      setMessages((prev) => prev.some((m) => m.id === msg.id) ? prev : [...prev, msg]);
      lastMessageIdRef.current = msg.id;
    } catch {
      setError("Network error. Please try again.");
      setSelectedFile(file);
      setInput(optionalText);
    } finally {
      setSending(false);
      inputRef.current?.focus();
    }
  }

  function handleFileChange(e) {
    const file = e.target.files?.[0];
    if (file) setSelectedFile(file);
    e.target.value = "";
  }

  function handleKeyDown(e) {
    if (e.key === "Enter" && !e.shiftKey) {
      e.preventDefault();
      handleSend();
    }
  }

  //Creates a new AI conversation and navigates to it
  async function handleNewConversation() {
    if (stompRef.current) { stompRef.current.deactivate(); stompRef.current = null; }
    setError(null);
    setLoadingConv(true);
    try {
      const res = await fetch(`${API_BASE}/api/v1/chat/conversations`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({}),
      });
      if (!res.ok) {
        const data = await res.json().catch(() => null);
        setError(data?.message || "Failed to start a conversation.");
        setLoadingConv(false);
        return;
      }
      const conv = await res.json();
      setConversation(conv);
      await Promise.all([fetchMessages(conv.id), fetchConversations()]);
      setLoadingConv(false);
      connectStomp(conv.id);
      router.replace(`/ai-chat?id=${conv.id}`, { scroll: false });
    } catch {
      setError("Network error. Please try again.");
      setLoadingConv(false);
    }
  }

  async function switchConversation(convId) {
    if (stompRef.current) { stompRef.current.deactivate(); stompRef.current = null; }
    setMessages([]);
    setError(null);
    setBotTyping(false);
    await Promise.all([fetchConversation(convId), fetchMessages(convId)]);
    connectStomp(convId);
    router.replace(`/ai-chat?id=${convId}`, { scroll: false });
  }

  //Requests a human agent for the current conversation
  async function handleSwitchToHuman() {
    if (!conversation) return;
    try {
      await fetch(`${API_BASE}/api/v1/chat/conversations/${conversation.id}/request-human`, {
        method: "POST",
        headers: { Authorization: `Bearer ${token}` },
      });
      setConversation((prev) => prev ? { ...prev, mode: "HUMAN" } : prev);
    } catch {
      setError("Could not connect to live support. Please try again.");
    }
  }

  //Closes the current conversation so no more messages can be sent
  async function handleCloseConversation() {
    if (!conversation || conversation.status === "CLOSED") return;
    try {
      const res = await fetch(`${API_BASE}/api/v1/chat/conversations/${conversation.id}`, {
        method: "PUT",
        headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
        body: JSON.stringify({ status: "CLOSED" }),
      });
      if (!res.ok) return;
      const updated = await res.json();
      setConversation(updated);
      await fetchConversations();
    } catch {
    }
  }

  if (authLoading || loadingConv) {
    return (
      <main style={s.page}>
        <p style={s.loading}>Loading...</p>
      </main>
    );
  }

  if (!user) return null;

  const isEscalated = conversation?.mode === "HUMAN";
  const isClosed = conversation?.status === "CLOSED";
  const hasStaff = !!conversation?.staffId;
  const hasStaffMessage = messages.some((m) => m.senderId !== user?.id);

  return (
    <main style={s.page}>
      <section style={s.hero}>
        <h1 style={s.heroTitle}>AI Pet Assistant</h1>
        <p style={s.heroSubtitle}>Ask me anything about pet care, adoption advice, or your pets!</p>
        <div style={s.titleDecoration} />
      </section>

      <section style={s.chatSection}>
        <div style={{ display: "flex", flexDirection: isMobile ? "column" : "row", gap: "1rem", alignItems: "flex-start" }}>
          <div style={{ ...s.sidebar, width: isMobile ? "100%" : 230, maxHeight: isMobile ? 260 : "calc(100vh - 220px)" }}>
            <div style={s.sidebarHeader}>
              <span style={s.sidebarTitle}>All Conversations</span>
            </div>
            {convsLoading && <p style={s.sidebarEmpty}>Loading...</p>}
            {!convsLoading && conversations.length === 0 && (
              <p style={s.sidebarEmpty}>No conversations yet.</p>
            )}
            <div style={{ overflowY: "auto", flex: 1 }}>
              {conversations.filter(c => c.status !== "CLOSED").map((conv) => (
                <button
                  key={conv.id}
                  style={{ ...s.convItem, ...(conv.id === conversation?.id ? s.convItemActive : {}) }}
                  onClick={() => switchConversation(conv.id)}
                >
                  <div style={s.convItemTop}>
                    <span style={s.convItemSubject}>{conv.subject || `Conversation #${conv.id}`}</span>
                    <span style={{ ...s.convStatusBadge, ...s.convStatusOpen }}>{conv.status}</span>
                  </div>
                  <div style={s.convItemBottom}>
                    <span style={{ ...s.convItemMode, display: "flex", alignItems: "center", gap: "0.25rem" }}>
                      <img src={conv.mode === "HUMAN" ? "/bootstrap/person-fill.svg" : "/bootstrap/robot.svg"} alt="" style={{ width: 12, height: 12 }} />
                      {conv.mode === "HUMAN" ? "Live" : "AI"}
                    </span>
                    <span style={s.convItemDate}>{conv.createdAt ? new Date(conv.createdAt).toLocaleDateString() : ""}</span>
                  </div>
                </button>
              ))}
            </div>
            {conversations.some(c => c.status === "CLOSED") && (
              <>
                <button style={s.closedSectionToggle} onClick={() => setClosedExpanded(p => !p)}>
                  <span>Closed ({conversations.filter(c => c.status === "CLOSED").length})</span>
                  <span>{closedExpanded ? "▲" : "▼"}</span>
                </button>
                {closedExpanded && conversations.filter(c => c.status === "CLOSED").map((conv) => (
                  <button
                    key={conv.id}
                    style={{ ...s.convItem, ...s.convItemClosed, ...(conv.id === conversation?.id ? s.convItemActive : {}) }}
                    onClick={() => switchConversation(conv.id)}
                  >
                    <div style={s.convItemTop}>
                      <span style={s.convItemSubject}>{conv.subject || `Conversation #${conv.id}`}</span>
                      <span style={{ ...s.convStatusBadge, ...s.convStatusClosed }}>CLOSED</span>
                    </div>
                    <div style={s.convItemBottom}>
                      <span style={{ ...s.convItemMode, display: "flex", alignItems: "center", gap: "0.25rem" }}>
                      <img src={conv.mode === "HUMAN" ? "/bootstrap/person-fill.svg" : "/bootstrap/robot.svg"} alt="" style={{ width: 12, height: 12 }} />
                      {conv.mode === "HUMAN" ? "Live" : "AI"}
                    </span>
                      <span style={s.convItemDate}>{conv.createdAt ? new Date(conv.createdAt).toLocaleDateString() : ""}</span>
                    </div>
                  </button>
                ))}
              </>
            )}
            <button style={s.newConvSidebarBtn} onClick={handleNewConversation}>
              + New Conversation
            </button>
          </div>

          <div style={{ flex: 1, minWidth: 0, width: isMobile ? "100%" : undefined }}>
            {!conversation ? (
              <div style={s.noConvCard}>
                <div style={s.noConvIcon}><img src="/bootstrap/person-circle.svg" alt="assistant" style={{ width: "3rem", height: "3rem", opacity: 0.6 }} /></div>
                <h2 style={s.noConvTitle}>No active conversation</h2>
                <p style={s.noConvText}>Start a new conversation with the AI assistant.</p>
                {error && <div style={s.errorInline}>{error}</div>}
                <button style={s.startBtn} onClick={handleNewConversation}>
                  Start a Conversation
                </button>
                <button style={s.backBtn} onClick={() => router.push("/chat")}>
                  Live Support
                </button>
              </div>
            ) : (
              <div style={s.chatCard}>
                <div style={{ ...s.chatHeader, flexDirection: isMobile ? "column" : "row", alignItems: isMobile ? "flex-start" : "center", gap: isMobile ? "0.6rem" : 0 }}>
                  <div style={s.chatHeaderLeft}>
                    <div style={isEscalated ? s.agentAvatar : s.aiAvatar}>{isEscalated ? "👤" : <img src="/bootstrap/person-circle.svg" alt="assistant" style={{ width: "100%", height: "100%", filter: "brightness(0) invert(1)" }} />}</div>
                    <div>
                      <div style={s.chatHeaderTitle}>
                        {isEscalated ? (hasStaff ? "Support Agent" : "Leon's Pet Store Support") : "Leon's Pet Assistant"}
                      </div>
                      <div style={{ ...s.chatHeaderStatus, color: isClosed ? "#999" : isEscalated && hasStaff ? "#4CAF50" : isEscalated ? "#ff8c00" : undefined }}>
                        <span style={{ ...s.statusDot, background: isClosed ? "#999" : isEscalated && hasStaff ? "#4CAF50" : isEscalated ? "#ff8c00" : undefined }} />
                        {isClosed ? "Conversation closed" : isEscalated && hasStaff ? "Support agent connected" : isEscalated ? "Waiting for a support agent..." : "Online"}
                      </div>
                    </div>
                  </div>
                  <div style={{ display: "flex", gap: "0.5rem", width: isMobile ? "100%" : undefined }}>
                    {!isEscalated && !isClosed && (
                      <button style={isMobile ? { ...s.humanBtn, flex: 1 } : s.humanBtn} onClick={handleSwitchToHuman} title="Connect with a human support agent">
                        Chat with a Real Person
                      </button>
                    )}
                    {!isClosed && (
                      <button style={isMobile ? { ...s.closeConvBtn, flex: 1 } : s.closeConvBtn} onClick={handleCloseConversation} title="Close this conversation">
                        Close Chat
                      </button>
                    )}
                  </div>
                </div>

                {isEscalated && !hasStaff && !hasStaffMessage && !isClosed && (
                  <div style={s.waitingBanner}>
                    <span style={s.waitingSpinner} />
                    A support agent will be with you shortly. You can send messages while you wait.
                  </div>
                )}

                <div style={s.messagesArea} ref={messagesAreaRef}>
                  {messages.length === 0 && (
                    <div style={s.emptyState}>
                      <div style={s.emptyIcon}>{isEscalated ? "💬" : <img src="/bootstrap/person-circle.svg" alt="assistant" style={{ width: "3rem", height: "3rem", opacity: 0.6 }} />}</div>
                      <p style={s.emptyText}>
                        {isEscalated ? "Your conversation has started. A support agent will join soon." : `Hello${user.fullName ? `, ${user.fullName.split(" ")[0]}` : ""}! I'm your pet care assistant. Ask me about pet recommendations, care tips, supplies, or anything pet-related!`}
                      </p>
                    </div>
                  )}

                  {messages.map((msg) => {
                    const isOwn = msg.senderId === user.id;
                    return (
                      <div
                        key={msg.id}
                        style={{
                          ...s.messageRow,
                          ...(isOwn ? s.messageRowUser : s.messageRowAgent),
                        }}
                      >
                        {!isOwn && <div style={isEscalated ? s.agentAvatarSmall : s.aiAvatarSmall}>{isEscalated ? "👤" : <img src="/bootstrap/person-circle.svg" alt="assistant" style={{ width: "100%", height: "100%", filter: "brightness(0) invert(1)" }} />}</div>}
                        <div
                          style={{
                            ...s.messageBubble,
                            ...(isOwn ? s.bubbleUser : s.bubbleAgent),
                          }}
                        >
                          {msg.content && msg.content.split("\n").map((line, i, arr) => (
                            <span key={i}>
                              {line}
                              {i < arr.length - 1 && <br />}
                            </span>
                          ))}
                          {msg.attachmentUrl && (
                            <AttachmentPreview url={msg.attachmentUrl} name={msg.attachmentName} token={token} />
                          )}
                          <div style={{ ...s.timestamp, ...(isOwn ? s.timestampUser : {}) }}>
                            {msg.timestamp ? new Date(msg.timestamp).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : ""}
                          </div>
                        </div>
                        {isOwn && (
                          <div style={s.userAvatarSmall}>
                            {user.fullName ? user.fullName.charAt(0).toUpperCase() : "U"}
                          </div>
                        )}
                      </div>
                    );
                  })}

                  {botTyping && !isEscalated && (
                    <div style={{ ...s.messageRow, ...s.messageRowAgent }}>
                      <div style={s.aiAvatarSmall}><img src="/bootstrap/person-circle.svg" alt="assistant" style={{ width: "100%", height: "100%", filter: "brightness(0) invert(1)" }} /></div>
                      <div style={{ ...s.messageBubble, ...s.bubbleAgent, display: "flex", alignItems: "center", gap: "4px", padding: "0.6rem 0.9rem" }}>
                        <span className="fc-dot" />
                        <span className="fc-dot" style={{ animationDelay: "0.2s" }} />
                        <span className="fc-dot" style={{ animationDelay: "0.4s" }} />
                      </div>
                    </div>
                  )}

                  {switchingConv && (
                    <div style={{ textAlign: "center", padding: "1rem", color: "#aaa", fontSize: "0.85rem" }}>
                      Loading messages…
                    </div>
                  )}

                  <div ref={messagesEndRef} />
                </div>

                {error && (
                  <div style={s.errorBar}>
                    {error}
                    <button style={s.errorClose} onClick={() => setError(null)}>✕</button>
                  </div>
                )}

                {isClosed ? (
                  <div style={s.closedBanner}>
                    This conversation has been closed.
                    <button style={s.newConvBtn} onClick={handleNewConversation}>
                      Start New Conversation
                    </button>
                  </div>
                ) : (
                  <form style={s.inputArea} onSubmit={handleSend}>
                    <input
                      type="file"
                      ref={fileInputRef}
                      style={{ display: "none" }}
                      onChange={handleFileChange}
                    />
                    {selectedFile && (
                      <div style={s.filePreview}>
                        <span style={s.filePreviewName}>📎 {selectedFile.name}</span>
                        <button
                          type="button"
                          style={s.filePreviewRemove}
                          onClick={() => setSelectedFile(null)}
                        >
                          ✕
                        </button>
                      </div>
                    )}
                    <div style={s.inputRow}>
                      <button
                        type="button"
                        style={s.attachBtn}
                        onClick={() => fileInputRef.current?.click()}
                        disabled={sending}
                        title="Attach a file"
                      >
                        📎
                      </button>
                      <textarea
                        ref={inputRef}
                        style={s.textarea}
                        value={input}
                        onChange={(e) => setInput(e.target.value)}
                        onKeyDown={handleKeyDown}
                        placeholder={selectedFile ? "Add a caption (optional)..." : "Ask me about pet care, adoption, supplies..."}
                        rows={1}
                        disabled={sending}
                        maxLength={2000}
                      />
                      <button
                        type="submit"
                        style={{
                          ...s.sendBtn,
                          ...((!input.trim() && !selectedFile) || sending ? s.sendBtnDisabled : {}),
                        }}
                        disabled={(!input.trim() && !selectedFile) || sending}
                      >
                        {sending ? "..." : "Send"}
                      </button>
                    </div>
                  </form>
                )}
              </div>
            )}
          </div>
        </div>
      </section>
    </main>
  );
}

const s = {
  page: {
    minHeight: "100vh",
    background: "#fafaf8",
    fontFamily: "inherit",
  },
  loading: {
    textAlign: "center",
    padding: "4rem",
    color: "#888",
    fontSize: "1rem",
  },
  hero: {
    background: "linear-gradient(135deg, #333 0%, #555 100%)",
    padding: "2.5rem 1.5rem 2rem",
    textAlign: "center",
    color: "white",
  },
  heroTitle: {
    fontSize: "clamp(1.6rem, 4vw, 2.4rem)",
    fontWeight: 800,
    margin: 0,
    letterSpacing: "-0.5px",
  },
  heroSubtitle: {
    fontSize: "clamp(0.9rem, 2vw, 1.1rem)",
    marginTop: "0.5rem",
    opacity: 0.85,
  },
  titleDecoration: {
    width: 60,
    height: 4,
    background: "rgba(255,255,255,0.4)",
    borderRadius: 2,
    margin: "1rem auto 0",
  },
  chatSection: {
    maxWidth: 1060,
    margin: "0 auto",
    padding: "1.5rem 1rem 2rem",
  },
  sidebar: {
    flexShrink: 0,
    background: "white",
    borderRadius: 16,
    boxShadow: "0 4px 24px rgba(0,0,0,0.08)",
    display: "flex",
    flexDirection: "column",
    overflow: "hidden",
    minHeight: 200,
  },
  sidebarHeader: {
    display: "flex",
    alignItems: "center",
    padding: "0.85rem 1rem",
    borderBottom: "1px solid #f0f0f0",
    flexShrink: 0,
  },
  sidebarTitle: { fontWeight: 700, fontSize: "0.88rem", color: "#333" },
  sidebarEmpty: {
    color: "#aaa",
    fontSize: "0.82rem",
    padding: "1rem",
    textAlign: "center",
    margin: 0,
  },
  convItem: {
    display: "flex",
    flexDirection: "column",
    gap: "0.2rem",
    padding: "0.65rem 1rem",
    background: "white",
    border: "none",
    borderBottomWidth: 1,
    borderBottomStyle: "solid",
    borderBottomColor: "#f0f0f0",
    textAlign: "left",
    cursor: "pointer",
    width: "100%",
  },
  convItemActive: { background: "#f8f8f8" },
  convItemTop: {
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    gap: "0.4rem",
  },
  convItemBottom: {
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
  },
  convItemSubject: {
    fontSize: "0.82rem",
    fontWeight: 600,
    color: "#222",
    overflow: "hidden",
    textOverflow: "ellipsis",
    whiteSpace: "nowrap",
    flex: 1,
  },
  convItemMode: { fontSize: "0.7rem", color: "#999" },
  convItemDate: { fontSize: "0.68rem", color: "#bbb" },
  convStatusBadge: {
    fontSize: "0.62rem",
    fontWeight: 700,
    borderRadius: 20,
    padding: "0.1rem 0.45rem",
    flexShrink: 0,
    textTransform: "uppercase",
    letterSpacing: "0.04em",
  },
  convStatusOpen: { background: "#e6f9ee", color: "#1a7a3c" },
  convStatusClosed: { background: "#f0f0f0", color: "#888" },
  convItemClosed: { opacity: 0.7 },
  closedSectionToggle: {
    width: "100%",
    background: "#f5f5f5",
    border: "none",
    borderTop: "1px solid #e8e8e8",
    padding: "0.5rem 1rem",
    fontSize: "0.78rem",
    fontWeight: 600,
    color: "#666",
    cursor: "pointer",
    display: "flex",
    justifyContent: "space-between",
    alignItems: "center",
  },
  newConvSidebarBtn: {
    margin: "0.65rem 1rem",
    background: "#333",
    color: "white",
    border: "none",
    borderRadius: 8,
    padding: "0.5rem 0.75rem",
    fontSize: "0.8rem",
    fontWeight: 600,
    cursor: "pointer",
    flexShrink: 0,
  },
  chatCard: {
    background: "white",
    borderRadius: 16,
    boxShadow: "0 4px 24px rgba(0,0,0,0.08)",
    overflow: "hidden",
    display: "flex",
    flexDirection: "column",
    height: "calc(100vh - 220px)",
    minHeight: 400,
  },
  chatHeader: {
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    padding: "1rem 1.25rem",
    borderBottom: "1px solid #f0f0f0",
    background: "#fff",
    flexShrink: 0,
  },
  chatHeaderLeft: {
    display: "flex",
    alignItems: "center",
    gap: "0.75rem",
  },
  aiAvatar: {
    width: 44,
    height: 44,
    borderRadius: "50%",
    background: "linear-gradient(135deg, #444, #666)",
    border: "3px solid #666",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    fontSize: "1.3rem",
    flexShrink: 0,
  },
  chatHeaderTitle: {
    fontWeight: 700,
    fontSize: "1rem",
    color: "#1a1a1a",
  },
  chatHeaderStatus: {
    display: "flex",
    alignItems: "center",
    gap: "0.35rem",
    fontSize: "0.8rem",
    color: "#4CAF50",
    marginTop: 2,
  },
  statusDot: {
    display: "inline-block",
    width: 8,
    height: 8,
    borderRadius: "50%",
    background: "#4CAF50",
  },
  humanBtn: {
    background: "white",
    border: "2px solid #ff8c00",
    color: "#ff8c00",
    borderRadius: 8,
    padding: "0.3rem 0.65rem",
    fontSize: "0.72rem",
    fontWeight: 600,
    cursor: "pointer",
    whiteSpace: "nowrap",
  },
  liveBtn: {
    background: "white",
    border: "2px solid #555",
    color: "#555",
    borderRadius: 8,
    padding: "0.45rem 0.9rem",
    fontSize: "0.82rem",
    fontWeight: 600,
    cursor: "pointer",
    whiteSpace: "nowrap",
  },
  agentAvatar: {
    width: 44,
    height: 44,
    borderRadius: "50%",
    background: "linear-gradient(135deg, #444, #666)",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    fontSize: "1.3rem",
    flexShrink: 0,
  },
  agentAvatarSmall: {
    width: 30,
    height: 30,
    borderRadius: "50%",
    background: "#e0e0e0",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    fontSize: "0.9rem",
    flexShrink: 0,
  },
  closeConvBtn: {
    background: "white",
    border: "2px solid #c0392b",
    color: "#c0392b",
    borderRadius: 8,
    padding: "0.3rem 0.65rem",
    fontSize: "0.72rem",
    fontWeight: 600,
    cursor: "pointer",
    whiteSpace: "nowrap",
  },
  waitingBanner: {
    background: "#fff8f0",
    borderBottom: "1px solid #ffe0b2",
    padding: "0.6rem 1.25rem",
    fontSize: "0.85rem",
    color: "#7c4a00",
    display: "flex",
    alignItems: "center",
    gap: "0.5rem",
    flexShrink: 0,
  },
  waitingSpinner: {
    display: "inline-block",
    width: 12,
    height: 12,
    borderRadius: "50%",
    border: "2px solid #ff8c00",
    borderTopColor: "transparent",
    animation: "spin 0.8s linear infinite",
    flexShrink: 0,
  },
  noConvCard: {
    background: "white",
    borderRadius: 16,
    boxShadow: "0 4px 24px rgba(0,0,0,0.08)",
    padding: "3rem 2rem",
    textAlign: "center",
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    gap: "1rem",
  },
  noConvIcon: { fontSize: "3rem" },
  noConvTitle: { fontSize: "1.4rem", fontWeight: 700, color: "#1a1a1a", margin: 0 },
  noConvText: { color: "#666", fontSize: "0.95rem", maxWidth: 360 },
  errorInline: {
    background: "#fff0f0",
    color: "#c0392b",
    border: "1px solid #ffd0d0",
    borderRadius: 8,
    padding: "0.6rem 1rem",
    fontSize: "0.875rem",
    width: "100%",
    maxWidth: 360,
  },
  startBtn: {
    background: "#333",
    color: "white",
    border: "none",
    borderRadius: 10,
    padding: "0.7rem 2rem",
    fontSize: "0.95rem",
    fontWeight: 600,
    cursor: "pointer",
  },
  backBtn: {
    background: "none",
    border: "1.5px solid #ff8c00",
    color: "#ff8c00",
    borderRadius: 10,
    padding: "0.6rem 1.5rem",
    fontSize: "0.9rem",
    fontWeight: 600,
    cursor: "pointer",
  },
  messagesArea: {
    flex: 1,
    overflowY: "auto",
    padding: "1.25rem",
    display: "flex",
    flexDirection: "column",
    gap: "0.75rem",
  },
  emptyState: {
    flex: 1,
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    justifyContent: "center",
    textAlign: "center",
    padding: "2rem",
    margin: "auto",
  },
  emptyIcon: { fontSize: "3rem", marginBottom: "1rem" },
  emptyText: {
    color: "#666",
    fontSize: "0.95rem",
    maxWidth: 400,
    lineHeight: 1.6,
  },
  messageRow: {
    display: "flex",
    alignItems: "flex-end",
    gap: "0.5rem",
  },
  messageRowUser: { flexDirection: "row-reverse" },
  messageRowAgent: { flexDirection: "row" },
  aiAvatarSmall: {
    width: 30,
    height: 30,
    borderRadius: "50%",
    background: "linear-gradient(135deg, #444, #666)",
    border: "3px solid #666",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    fontSize: "0.85rem",
    flexShrink: 0,
  },
  userAvatarSmall: {
    width: 30,
    height: 30,
    borderRadius: "50%",
    background: "#ff8c00",
    color: "white",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    fontSize: "0.8rem",
    fontWeight: 700,
    flexShrink: 0,
  },
  messageBubble: {
    maxWidth: "72%",
    padding: "0.65rem 0.9rem",
    borderRadius: 14,
    fontSize: "0.92rem",
    lineHeight: 1.55,
    wordBreak: "break-word",
  },
  bubbleUser: {
    background: "#ff8c00",
    color: "white",
    borderBottomRightRadius: 4,
  },
  bubbleAgent: {
    background: "#f4f4f4",
    color: "#1a1a1a",
    borderBottomLeftRadius: 4,
  },
  timestamp: {
    fontSize: "0.7rem",
    color: "#aaa",
    marginTop: "0.3rem",
    textAlign: "left",
  },
  timestampUser: { textAlign: "right", color: "rgba(255,255,255,0.7)" },
  attachment: { marginTop: "0.4rem" },
  attachmentLink: {
    color: "inherit",
    fontSize: "0.85rem",
    opacity: 0.85,
  },
  errorBar: {
    background: "#fff0f0",
    borderTop: "1px solid #ffd0d0",
    color: "#c0392b",
    padding: "0.65rem 1.25rem",
    fontSize: "0.875rem",
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    flexShrink: 0,
  },
  errorClose: {
    background: "none",
    border: "none",
    color: "#c0392b",
    cursor: "pointer",
    fontSize: "0.9rem",
    padding: "0 0.25rem",
  },
  closedBanner: {
    background: "#f5f5f5",
    borderTop: "1px solid #e0e0e0",
    color: "#666",
    padding: "0.85rem 1.25rem",
    fontSize: "0.875rem",
    display: "flex",
    alignItems: "center",
    justifyContent: "space-between",
    flexShrink: 0,
  },
  newConvBtn: {
    background: "#333",
    color: "white",
    border: "none",
    borderRadius: 8,
    padding: "0.4rem 1rem",
    fontSize: "0.82rem",
    fontWeight: 600,
    cursor: "pointer",
  },
  inputArea: {
    display: "flex",
    flexDirection: "column",
    gap: "0.4rem",
    padding: "0.85rem 1.25rem",
    borderTop: "1px solid #f0f0f0",
    background: "#fff",
    flexShrink: 0,
  },
  inputRow: {
    display: "flex",
    gap: "0.6rem",
    alignItems: "flex-end",
  },
  attachBtn: {
    background: "none",
    border: "1.5px solid #e0e0e0",
    borderRadius: 8,
    padding: "0.5rem 0.6rem",
    fontSize: "1rem",
    cursor: "pointer",
    flexShrink: 0,
    color: "#666",
    lineHeight: 1,
  },
  filePreview: {
    display: "flex",
    alignItems: "center",
    gap: "0.5rem",
    background: "#f8f8f8",
    border: "1px solid #e8e8e8",
    borderRadius: 8,
    padding: "0.35rem 0.75rem",
  },
  filePreviewName: {
    fontSize: "0.82rem",
    color: "#555",
    flex: 1,
    overflow: "hidden",
    textOverflow: "ellipsis",
    whiteSpace: "nowrap",
  },
  filePreviewRemove: {
    background: "none",
    border: "none",
    cursor: "pointer",
    color: "#999",
    fontSize: "0.8rem",
    padding: "0 0.15rem",
    flexShrink: 0,
  },
  textarea: {
    flex: 1,
    border: "1.5px solid #e0e0e0",
    borderRadius: 10,
    padding: "0.6rem 0.85rem",
    fontSize: "0.92rem",
    resize: "none",
    outline: "none",
    fontFamily: "inherit",
    lineHeight: 1.5,
    maxHeight: 120,
    overflowY: "auto",
  },
  sendBtn: {
    background: "#333",
    color: "white",
    border: "none",
    borderRadius: 10,
    padding: "0.6rem 1.2rem",
    fontSize: "0.92rem",
    fontWeight: 600,
    cursor: "pointer",
    flexShrink: 0,
  },
  sendBtnDisabled: {
    background: "#aaa",
    cursor: "not-allowed",
  },
};

export default dynamic(() => Promise.resolve(AiChatPage), { ssr: false });
