"use client";

import React, { useMemo, useRef, useState, useEffect, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";

// MUI
import {
  Avatar,
  Box,
  Drawer,
  IconButton,
  ListItemIcon,
  ListItemText,
  Menu,
  MenuItem,
  Paper,
  Stack,
  TextField,
  Typography,
  useTheme,
  alpha,
} from "@mui/material";

// Icons
import CloseRounded from "@mui/icons-material/CloseRounded";
import SendRounded from "@mui/icons-material/SendRounded";
import StopRounded from "@mui/icons-material/StopRounded";
import AutoAwesome from "@mui/icons-material/AutoAwesome"; // Sparkle icon for AI
import AddCommentRounded from "@mui/icons-material/AddCommentRounded";
import MicRounded from "@mui/icons-material/MicRounded";
import KeyboardArrowDownRounded from "@mui/icons-material/KeyboardArrowDownRounded";
import KeyboardArrowUpRounded from "@mui/icons-material/KeyboardArrowUpRounded";

// Logic
import { streamCopilotChat } from "@/lib/chatStream";
import type { StreamEvent } from "@/lib/chatStream";
import {
  useChatToolStore,
  type ChatToolAction,
} from "@/store/chatToolStore";
import type { Message, PersistedChatState, Props } from "./GlobalChatbox.types";
import {
  CHAT_STORAGE_KEY,
  PRESET_PROMPTS,
  createId,
  getInitialChatState,
  normalizeThoughtTagToken,
} from "./GlobalChatbox.utils";
import { Blob, ChatMessageItem, TypingIndicator } from "./GlobalChatbox.parts";
import { useSpeechRecognition, useSpeechSynthesis } from "./GlobalChatbox.voice";

export const GlobalChatbox: React.FC<Props> = ({ open, onClose }) => {
  const initialChatStateRef = useRef<PersistedChatState | null>(null);
  if (initialChatStateRef.current === null) {
    initialChatStateRef.current = getInitialChatState();
  }

  const [messages, setMessages] = useState<Message[]>(initialChatStateRef.current.messages);
  const [input, setInput] = useState("");
  const [isStreaming, setIsStreaming] = useState(false);
  const [width, setWidth] = useState(480);
  const [isResizing, setIsResizing] = useState(false);
  const [conversationId, setConversationId] = useState<string | undefined>(
    initialChatStateRef.current.conversationId
  );
  const [headerMenuAnchorEl, setHeaderMenuAnchorEl] = useState<HTMLElement | null>(null);
  const [isPresetPanelOpen, setIsPresetPanelOpen] = useState(false);

  // SSE tool_call → inline chart data (keyed by assistantMessageId)
  const [sseCharts, setSseCharts] = useState<
    Record<string, Array<{ tool: string; params: Record<string, unknown> }>>
  >({});

  const dispatchToolAction = useChatToolStore((s) => s.dispatch);
  const abortRef = useRef<AbortController | null>(null);
  const bottomRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement | null>(null);
  const theme = useTheme();

  // --- Voice Features ---
  const {
    speechState,
    speakingMessageId,
    speak: handleSpeak,
    pause: handlePauseSpeech,
    resume: handleResumeSpeech,
    stop: handleStopSpeech,
    isSupported: isTtsSupported,
  } = useSpeechSynthesis();

  const handleSpeechResult = useCallback((text: string) => {
    setInput((prev) => prev + text);
  }, []);

  const {
    isListening,
    start: startListening,
    stop: stopListening,
    isSupported: isSttSupported,
  } = useSpeechRecognition(handleSpeechResult);

  const canSend = useMemo(() => input.trim().length > 0 && !isStreaming, [input, isStreaming]);
  const isHeaderMenuOpen = Boolean(headerMenuAnchorEl);

  // Auto-scroll
  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [messages, isStreaming]);

  useEffect(() => {
    if (!open) return;
    const timer = window.setTimeout(() => {
      inputRef.current?.focus();
      bottomRef.current?.scrollIntoView({ behavior: "auto" });
    }, 0);
    return () => window.clearTimeout(timer);
  }, [open]);

  useEffect(() => {
    const state: PersistedChatState = { messages, conversationId };
    try {
      window.localStorage.setItem(CHAT_STORAGE_KEY, JSON.stringify(state));
    } catch (error) {
      console.error("[GlobalChatbox] Failed to persist chat state:", error);
    }
  }, [messages, conversationId]);

  const sendPrompt = useCallback(
    async (rawPrompt: string) => {
      const prompt = rawPrompt.trim();
      if (!prompt || isStreaming) return;
      stopListening();

      const userId = createId();
      const assistantId = createId();
      setInput("");
      setIsStreaming(true);

      setMessages((prev) => [
        ...prev,
        { id: userId, role: "user", content: prompt },
        { id: assistantId, role: "assistant", content: "" },
      ]);

      const controller = new AbortController();
      abortRef.current = controller;

      // Track SSE tool_call hashes to deduplicate against text-parsed tool_calls
      const sseToolHashes = new Set<string>();

      const handleSseToolCall = (event: StreamEvent & { type: "tool_call" }) => {
        const { tool, params } = event;
        const hash = `${tool}:${JSON.stringify(params)}`;
        sseToolHashes.add(hash);
        const startTime =
          (params.start_time as string | undefined) ??
          (params.startTime as string | undefined) ??
          (params.from as string | undefined) ??
          (params.start as string | undefined);
        const endTime =
          (params.end_time as string | undefined) ??
          (params.endTime as string | undefined) ??
          (params.to as string | undefined) ??
          (params.end as string | undefined);
        const resolveScadaFeatureInfos = (): [string, string][] => {
          const rawFeatureInfos = params.feature_infos;
          if (Array.isArray(rawFeatureInfos)) {
            const normalizedFeatureInfos = rawFeatureInfos
              .map((item) => (Array.isArray(item) ? item : null))
              .filter((item): item is [unknown, unknown] => Boolean(item))
              .map(
                (item) =>
                  [String(item[0] ?? ""), String(item[1] ?? "scada")] as [
                    string,
                    string,
                  ],
              )
              .filter(([id]) => id.trim().length > 0);
            if (normalizedFeatureInfos.length > 0) {
              return normalizedFeatureInfos;
            }
          }
          const rawDeviceIds =
            params.device_ids ??
            params.deviceId ??
            params.device_id ??
            params.id ??
            params.ids;
          const deviceIds = Array.isArray(rawDeviceIds)
            ? rawDeviceIds.map((id) => String(id))
            : typeof rawDeviceIds === "string"
              ? rawDeviceIds
                  .split(",")
                  .map((id) => id.trim())
                  .filter(Boolean)
              : [];
          return deviceIds.map((id) => [id, "scada"]);
        };

        // show_chart → store as inline chart for rendering
        if (tool === "show_chart") {
          setSseCharts((prev) => ({
            ...prev,
            [assistantId]: [
              ...(prev[assistantId] ?? []),
              { tool, params },
            ],
          }));
          return;
        }

        // Other frontend tools → dispatch to chatToolStore immediately
        const normalizeIds = (): string[] => {
          const rawIds = params.ids;
          if (Array.isArray(rawIds)) {
            return rawIds
              .map((id) => String(id).trim())
              .filter(Boolean);
          }
          if (typeof rawIds === "string") {
            return rawIds
              .split(",")
              .map((id) => id.trim())
              .filter(Boolean);
          }
          return [];
        };
        const buildLocateFeaturesAction = (
          layer: string,
          geometryKind: "point" | "line",
        ): ChatToolAction => ({
          type: "locate_features" as const,
          ids: normalizeIds(),
          layer,
          geometryKind,
        });
        const buildLocateByFeatureType = (): ChatToolAction | null => {
          const rawType = params.feature_type;
          const featureType =
            typeof rawType === "string" ? rawType.trim().toLowerCase() : "";
          const featureTypeMap: Record<
            string,
            { layer: string; geometryKind: "point" | "line" }
          > = {
            junction: { layer: "geo_junctions_mat", geometryKind: "point" },
            junctions: { layer: "geo_junctions_mat", geometryKind: "point" },
            pipe: { layer: "geo_pipes_mat", geometryKind: "line" },
            pipes: { layer: "geo_pipes_mat", geometryKind: "line" },
            valve: { layer: "geo_valves", geometryKind: "point" },
            valves: { layer: "geo_valves", geometryKind: "point" },
            reservoir: { layer: "geo_reservoirs", geometryKind: "point" },
            reservoirs: { layer: "geo_reservoirs", geometryKind: "point" },
            pump: { layer: "geo_pumps", geometryKind: "point" },
            pumps: { layer: "geo_pumps", geometryKind: "point" },
            tank: { layer: "geo_tanks", geometryKind: "point" },
            tanks: { layer: "geo_tanks", geometryKind: "point" },
          };
          const config = featureTypeMap[featureType];
          if (!config) return null;
          return buildLocateFeaturesAction(config.layer, config.geometryKind);
        };
        const actionMap: Record<string, () => ChatToolAction | null> = {
          locate_features: buildLocateByFeatureType,
          locate_pipes: () => buildLocateFeaturesAction("geo_pipes_mat", "line"),
          locate_junctions: () =>
            buildLocateFeaturesAction("geo_junctions_mat", "point"),
          locate_valves: () => buildLocateFeaturesAction("geo_valves", "point"),
          locate_reservoirs: () =>
            buildLocateFeaturesAction("geo_reservoirs", "point"),
          locate_pumps: () => buildLocateFeaturesAction("geo_pumps", "point"),
          locate_tanks: () => buildLocateFeaturesAction("geo_tanks", "point"),
          view_history: () => ({
            type: "view_history" as const,
            featureInfos: (params.feature_infos as [string, string][]) ?? [],
            dataType: (params.data_type as "realtime" | "scheme" | "none") ?? "realtime",
            startTime,
            endTime,
          }),
          view_scada: () => ({
            type: "view_scada" as const,
            featureInfos: resolveScadaFeatureInfos(),
            startTime,
            endTime,
          }),
        };
        const buildAction = actionMap[tool];
        if (buildAction) {
          const action = buildAction();
          if (action) dispatchToolAction(action);
        }
      };

      try {
        await streamCopilotChat({
          message: prompt,
          conversationId,
          signal: controller.signal,
          onEvent: (event) => {
            if (event.type === "token") {
              if (!conversationId && event.conversationId) setConversationId(event.conversationId);
              const normalizedToken = normalizeThoughtTagToken(event.content);
              setMessages((prev) =>
                prev.map((m) =>
                  m.id === assistantId
                    ? { ...m, content: m.content + normalizedToken, isError: false }
                    : m
                )
              );
            } else if (event.type === "done") {
              if (!conversationId && event.conversationId) setConversationId(event.conversationId);
              setMessages((prev) =>
                prev.map((m) =>
                  m.id === assistantId && m.content.trim().length === 0
                    ? {
                        ...m,
                        content: "⚠️ **错误：** Copilot 未返回内容，请稍后重试。",
                        isError: true,
                      }
                    : m
                )
              );
              setIsStreaming(false);
            } else if (event.type === "error") {
              setMessages((prev) =>
                prev.map((m) =>
                  m.id === assistantId
                    ? {
                        ...m,
                        content: m.content || `⚠️ **错误：** ${event.message}`,
                        isError: true,
                      }
                    : m
                )
              );
              setIsStreaming(false);
            } else if (event.type === "tool_call") {
              handleSseToolCall(event);
            }
          },
        });
      } catch (error) {
        if (abortRef.current?.signal.aborted) {
          setMessages((prev) =>
            prev.filter((m) => !(m.id === assistantId && m.role === "assistant" && m.content.trim().length === 0))
          );
          return;
        }
        setMessages((prev) =>
          prev.map((m) =>
            m.id === assistantId
              ? { ...m, content: `⚠️ **错误：** ${String(error)}`, isError: true }
              : m
          )
        );
        setIsStreaming(false);
      } finally {
        abortRef.current = null;
        setIsStreaming(false);
      }
    },
    [conversationId, isStreaming, stopListening, dispatchToolAction],
  );

  const handleSend = async () => {
    const prompt = input.trim();
    if (!prompt || isStreaming) return;
    await sendPrompt(prompt);
  };

  const handleAbort = () => {
    abortRef.current?.abort();
    setIsStreaming(false);
  };

  const handlePresetPromptSelect = useCallback((prompt: string) => {
    setInput(prompt);
    setIsPresetPanelOpen(false);
    window.setTimeout(() => {
      inputRef.current?.focus();
    }, 0);
  }, []);

  const handleHeaderMenuOpen = useCallback(
    (event: React.MouseEvent<HTMLElement>) => {
      setHeaderMenuAnchorEl(event.currentTarget);
    },
    [],
  );

  const handleHeaderMenuClose = useCallback(() => {
    setHeaderMenuAnchorEl(null);
  }, []);

  const handleNewConversation = useCallback(() => {
    abortRef.current?.abort();
    handleStopSpeech();
    stopListening();
    setMessages([]);
    setConversationId(undefined);
    setInput("");
    setIsStreaming(false);
    handleHeaderMenuClose();

    window.setTimeout(() => {
      inputRef.current?.focus();
    }, 0);
  }, [handleHeaderMenuClose, handleStopSpeech, stopListening]);

  const handleMouseDown = useCallback((e: React.MouseEvent) => {
    e.preventDefault();
    setIsResizing(true);
  }, []);

  useEffect(() => {
    const handleMouseMove = (e: MouseEvent) => {
      if (!isResizing) return;
      const newWidth = window.innerWidth - e.clientX;
      if (newWidth > 320 && newWidth < 1200) {
        setWidth(newWidth);
      }
    };

    const handleMouseUp = () => {
      setIsResizing(false);
    };

    if (isResizing) {
      window.addEventListener("mousemove", handleMouseMove);
      window.addEventListener("mouseup", handleMouseUp);
    }

    return () => {
      window.removeEventListener("mousemove", handleMouseMove);
      window.removeEventListener("mouseup", handleMouseUp);
    };
  }, [isResizing]);

  const renderedMessages = useMemo(
    () =>
      messages.map((message) => (
        <ChatMessageItem
          key={message.id}
          message={message}
          theme={theme}
          messageSpeechState={speakingMessageId === message.id ? speechState : "idle"}
          onSpeak={handleSpeak}
          onPause={handlePauseSpeech}
          onResume={handleResumeSpeech}
          onStopSpeech={handleStopSpeech}
          isTtsSupported={isTtsSupported}
          sseChartParams={sseCharts[message.id]}
        />
      )),
    [messages, theme, speechState, speakingMessageId, handleSpeak, handlePauseSpeech, handleResumeSpeech, handleStopSpeech, isTtsSupported, sseCharts],
  );


  return (
    <Drawer
      anchor="right"
      variant="persistent"
      open={open}
      onClose={onClose}
      hideBackdrop
      sx={{ zIndex: (muiTheme) => muiTheme.zIndex.modal + 100 }}
      PaperProps={{
        sx: {
          width: { xs: "100%", sm: width },
          background: "transparent",
          boxShadow: "none",
          overflow: "visible", // Changed from "hidden" to show resizer handle if needed, though handle is inside.
          zIndex: (muiTheme) => muiTheme.zIndex.modal + 100,
          transition: isResizing ? "none" : "width 0.2s cubic-bezier(0, 0, 0.2, 1)", // Disable transition during resize
        },
      }}
    >
      <Box
        sx={{
          height: "100%",
          display: "flex",
          flexDirection: "column",
          bgcolor: alpha("#fff", 0.75), // Light glass base
          backdropFilter: "blur(30px)",
          position: "relative",
        }}
      >
        {/* Resize Handle */}
        <Box
          onMouseDown={handleMouseDown}
          sx={{
            position: "absolute",
            left: 0,
            top: 0,
            bottom: 0,
            width: "6px",
            cursor: "col-resize",
            zIndex: 200,
            "&:hover": {
              bgcolor: alpha(theme.palette.primary.main, 0.2),
            },
            "&::after": {
              content: '""',
              position: "absolute",
              left: "50%",
              top: "50%",
              transform: "translate(-50%, -50%)",
              width: "2px",
              height: "40px",
              bgcolor: alpha(theme.palette.divider, 0.4),
              borderRadius: "1px",
            }
          }}
        />

        {/* Ambient Blobs */}
        <Blob color={alpha(theme.palette.primary.main, 0.3)} size={300} top="-10%" left="-20%" delay={0} />
        <Blob color={alpha(theme.palette.secondary.main, 0.3)} size={250} top="40%" left="60%" delay={2} />
        <Blob color={alpha(theme.palette.success.light, 0.2)} size={200} top="80%" left="-10%" delay={4} />

        {/* Header - Transparent & Floating */}
        <Box
          sx={{
            p: 3,
            zIndex: 10,
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
          }}
        >
          <Stack direction="row" alignItems="center" spacing={2}>
            <motion.div
                whileHover={{ rotate: 10, scale: 1.1 }}
                whileTap={{ scale: 0.95 }}
            >
                <IconButton
                  onClick={handleHeaderMenuOpen}
                  aria-label="打开聊天菜单"
                  aria-controls={isHeaderMenuOpen ? "global-chatbox-header-menu" : undefined}
                  aria-expanded={isHeaderMenuOpen ? "true" : undefined}
                  aria-haspopup="menu"
                  sx={{
                    p: 0,
                    borderRadius: "50%",
                  }}
                >
                  <Box sx={{ position: "relative" }}>
                    <Avatar
                      sx={{
                        background: `linear-gradient(135deg, ${theme.palette.primary.light}, ${theme.palette.primary.main})`,
                        boxShadow: `0 8px 20px ${alpha(theme.palette.primary.main, 0.4)}`,
                        width: 48,
                        height: 48,
                      }}
                    >
                      <AutoAwesome fontSize="medium" sx={{ color: "#fff" }} />
                    </Avatar>
                    <Box
                      sx={{
                        position: "absolute",
                        bottom: 2,
                        right: 2,
                        width: 12,
                        height: 12,
                        bgcolor: "success.main",
                        borderRadius: "50%",
                        border: "2px solid #fff",
                        boxShadow: "0 0 0 2px rgba(255,255,255,0.5)"
                      }}
                    />
                  </Box>
                </IconButton>
            </motion.div>
            
            <Box>
              <Typography variant="h6" fontWeight={800} sx={{ background: `linear-gradient(90deg, ${theme.palette.primary.dark}, ${theme.palette.secondary.dark})`, backgroundClip: "text", color: "transparent", letterSpacing: -0.5 }}>
                Copilot
              </Typography>
              <Typography variant="caption" color="text.secondary" fontWeight={500}>
                 你的 AI 助手
              </Typography>
            </Box>
          </Stack>

          <Menu
            id="global-chatbox-header-menu"
            anchorEl={headerMenuAnchorEl}
            open={isHeaderMenuOpen}
            onClose={handleHeaderMenuClose}
            anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
            transformOrigin={{ vertical: "top", horizontal: "left" }}
            slotProps={{
              paper: {
                elevation: 8,
                sx: {
                  mt: 1,
                  minWidth: 180,
                  borderRadius: 3,
                  border: `1px solid ${alpha(theme.palette.divider, 0.12)}`,
                  backdropFilter: "blur(12px)",
                  bgcolor: alpha("#fff", 0.92),
                  boxShadow: `0 16px 40px -16px ${alpha(theme.palette.common.black, 0.28)}`,
                },
              },
            }}
          >
            <MenuItem onClick={handleNewConversation}>
              <ListItemIcon>
                <AddCommentRounded fontSize="small" />
              </ListItemIcon>
              <ListItemText
                primary="新建对话"
                secondary="清空当前会话"
                primaryTypographyProps={{ sx: { fontSize: "0.95rem", fontWeight: 600 } }}
                secondaryTypographyProps={{ sx: { fontSize: "0.8rem" } }}
              />
            </MenuItem>
          </Menu>
          
          <motion.div whileHover={{ scale: 1.1, rotate: 90 }} whileTap={{ scale: 0.9 }}>
            <IconButton onClick={onClose} size="small" sx={{ color: "text.primary", bgcolor: alpha("#fff", 0.5), "&:hover": { bgcolor: "#fff" } }}>
                <CloseRounded />
            </IconButton>
          </motion.div>
        </Box>

        {/* Messages - Bouncy List */}
        <Box
          sx={{
            flex: 1,
            overflowY: "auto",
            px: 2.5,
            py: 2,
            display: "flex",
            flexDirection: "column",
            gap: 2.5,
            zIndex: 5,
          }}
        >
            <AnimatePresence initial={false}>
            {messages.length === 0 && (
                <motion.div
                    initial={{ opacity: 0, y: 20 }}
                    animate={{ opacity: 1, y: 0 }}
                    transition={{ type: "spring", stiffness: 200, damping: 20 }}
                    style={{ margin: "auto", width: "100%" }}
                >
                    <Paper
                        elevation={0}
                        sx={{
                            p: 4,
                            borderRadius: 6,
                            bgcolor: alpha("#fff", 0.6),
                            border: `1px solid ${alpha(theme.palette.divider, 0.1)}`,
                            maxWidth: 320,
                            mx: "auto",
                            textAlign: "center",
                            backdropFilter: "blur(10px)",
                        }}
                    >
                        <motion.div 
                            animate={{ y: [-5, 5, -5] }} 
                            transition={{ duration: 4, repeat: Infinity, ease: "easeInOut" }}
                        >
                            <AutoAwesome sx={{ fontSize: 56, color: "primary.main", mb: 2, filter: "drop-shadow(0 4px 8px rgba(0,0,0,0.1))" }} />
                        </motion.div>
                        <Typography variant="h6" color="text.primary" fontWeight={700} gutterBottom>
                            你好呀！👋
                        </Typography>
                        <Typography variant="body2" color="text.secondary" sx={{ lineHeight: 1.6 }}>
                            我已准备好为你提供帮助，尽管问我吧！
                        </Typography>
                    </Paper>
                </motion.div>
            )}

            {renderedMessages}
            </AnimatePresence>
            
            {isStreaming && (
                 <motion.div
                    initial={{ opacity: 0, y: 10, scale: 0.9 }}
                    animate={{ opacity: 1, y: 0, scale: 1 }}
                    transition={{ type: "spring", stiffness: 300 }}
                    style={{ alignSelf: "flex-start", display: "flex", gap: 12, marginTop: 4, marginLeft: 40 }}
                 >
                    <Paper 
                        elevation={0}
                        sx={{ 
                            p: 1.5, 
                            borderRadius: 4, 
                            bgcolor: alpha("#fff", 0.8),
                            boxShadow: `0 4px 12px ${alpha("#000", 0.05)}`
                        }}
                    >
                        <TypingIndicator />
                    </Paper>
                 </motion.div>
            )}

            <div ref={bottomRef} style={{ height: 1 }} />
        </Box>

        {/* Input Area - Floating Capsule */}
        <Box sx={{ p: 3, zIndex: 10 }}>
          <Box sx={{ mb: 1.25, display: "flex", justifyContent: "flex-end" }}>
            <Box sx={{ position: "relative", width: "100%", maxWidth: 520, display: "flex", justifyContent: "flex-end" }}>
              <AnimatePresence initial={false}>
                {isPresetPanelOpen && (
                  <motion.div
                    initial={{ opacity: 0, y: 8, scale: 0.98 }}
                    animate={{ opacity: 1, y: 0, scale: 1 }}
                    exit={{ opacity: 0, y: 8, scale: 0.98 }}
                    transition={{ type: "spring", stiffness: 320, damping: 26 }}
                    style={{ position: "absolute", right: 0, bottom: "calc(100% + 10px)", width: "100%", zIndex: 3 }}
                  >
                    <Paper
                      elevation={12}
                      sx={{
                        p: 1.2,
                        borderRadius: 3,
                        bgcolor: alpha("#fff", 0.92),
                        backdropFilter: "blur(12px)",
                        border: `1px solid ${alpha(theme.palette.divider, 0.12)}`,
                        boxShadow: `0 20px 48px -20px ${alpha(theme.palette.common.black, 0.3)}`,
                      }}
                    >
                      <Stack spacing={0.8}>
                        {PRESET_PROMPTS.map((prompt, index) => (
                          <Box
                            key={`preset-${index}`}
                            component="button"
                            type="button"
                            onClick={() => handlePresetPromptSelect(prompt)}
                            sx={{
                              textAlign: "left",
                              width: "100%",
                              px: 1.1,
                              py: 0.9,
                              borderRadius: 2,
                              border: `1px solid ${alpha(theme.palette.divider, 0.24)}`,
                              bgcolor: alpha("#fff", 0.72),
                              color: "text.secondary",
                              fontSize: "0.84rem",
                              lineHeight: 1.45,
                              cursor: "pointer",
                              transition: "all 0.18s ease",
                              "&:hover": {
                                borderColor: alpha(theme.palette.primary.main, 0.45),
                                color: "text.primary",
                                transform: "translateY(-1px)",
                                boxShadow: `0 8px 24px -16px ${alpha(theme.palette.primary.main, 0.6)}`,
                              },
                            }}
                          >
                            {prompt}
                          </Box>
                        ))}
                      </Stack>
                    </Paper>
                  </motion.div>
                )}
              </AnimatePresence>

              <motion.div whileHover={{ y: -1 }} whileTap={{ scale: 0.98 }}>
              <Paper
                elevation={10}
                sx={{
                  borderRadius: 99,
                  border: `1px solid ${alpha(theme.palette.divider, 0.1)}`,
                  bgcolor: alpha("#fff", 0.9),
                  backdropFilter: "blur(10px)",
                  boxShadow: `0 14px 40px -14px ${alpha(theme.palette.primary.main, 0.35)}`,
                  overflow: "hidden",
                }}
              >
                <Stack direction="row" alignItems="center" spacing={1} sx={{ pl: 1.2, pr: 0.5, py: 0.5 }}>
                  <Avatar
                    sx={{
                      width: 28,
                      height: 28,
                      background: `linear-gradient(135deg, ${theme.palette.primary.light}, ${theme.palette.secondary.main})`,
                    }}
                  >
                    <AutoAwesome sx={{ fontSize: 16, color: "#fff" }} />
                  </Avatar>
                  <Typography variant="caption" sx={{ color: "text.secondary", fontWeight: 700, letterSpacing: 0.2 }}>
                    常用功能
                  </Typography>
                  <IconButton
                    size="small"
                    onClick={() => setIsPresetPanelOpen((prev) => !prev)}
                    aria-label={isPresetPanelOpen ? "收起常用功能" : "展开常用功能"}
                    sx={{ color: "text.secondary" }}
                  >
                    {isPresetPanelOpen ? <KeyboardArrowDownRounded /> : <KeyboardArrowUpRounded />}
                  </IconButton>
                </Stack>
              </Paper>
              </motion.div>
            </Box>
          </Box>

          <motion.div
            initial={{ y: 20, opacity: 0 }}
            animate={{ y: 0, opacity: 1 }}
            transition={{ delay: 0.2 }}
          >
            <Stack 
                direction="row"
                alignItems="center"
                component={Paper}
                elevation={12}
                sx={{
                p: "6px 8px",
                borderRadius: 50, // Full capsule
                bgcolor: alpha("#fff", 0.9),
                backdropFilter: "blur(10px)",
                border: `1px solid ${alpha("#fff", 0.6)}`,
                boxShadow: `0 12px 40px -8px ${alpha(theme.palette.primary.main, 0.15)}`,
                transition: "all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1)",
                "&:hover": {
                    transform: "translateY(-2px)",
                    boxShadow: `0 16px 48px -8px ${alpha(theme.palette.primary.main, 0.25)}`,
                }
                }}
            >
                <TextField
                inputRef={inputRef}
                value={input}
                onChange={(e) => setInput(e.target.value)}
                onKeyDown={(e) => {
                    if (e.key === "Enter" && !e.shiftKey) {
                    e.preventDefault();
                    void handleSend();
                    }
                }}
                placeholder="输入消息给 Copilot..."
                fullWidth
                multiline
                maxRows={3}
                variant="standard"
                InputProps={{
                    disableUnderline: true,
                    sx: { px: 2.5, py: 1.5, fontSize: "1rem" },
                }}
                />
                
                {isSttSupported && (
                  <Box sx={{ display: "flex", alignItems: "center", mr: 1 }}>
                    {isListening ? (
                      <motion.div
                        animate={{ scale: [1, 1.15, 1] }}
                        transition={{ duration: 1.5, repeat: Infinity, ease: "easeInOut" }}
                      >
                        <IconButton
                          onClick={stopListening}
                          aria-label="停止语音输入"
                          sx={{
                            color: "error.main",
                            bgcolor: alpha(theme.palette.error.main, 0.1),
                            width: 44,
                            height: 44,
                            "&:hover": { bgcolor: alpha(theme.palette.error.main, 0.2) },
                          }}
                        >
                          <MicRounded />
                        </IconButton>
                      </motion.div>
                    ) : (
                      <IconButton
                        onClick={startListening}
                        disabled={isStreaming}
                        aria-label="语音输入"
                        sx={{
                          color: "text.secondary",
                          width: 44,
                          height: 44,
                          "&:hover": { color: "primary.main" },
                        }}
                      >
                        <MicRounded />
                      </IconButton>
                    )}
                  </Box>
                )}

                <Box sx={{ pr: 0.5 }}>
                    <AnimatePresence mode="wait">
                        {isStreaming ? (
                        <motion.div
                            key="stop"
                            initial={{ scale: 0, rotate: -180 }}
                            animate={{ scale: 1, rotate: 0 }}
                            exit={{ scale: 0, rotate: 180 }}
                            transition={{ type: "spring", stiffness: 400, damping: 25 }}
                        >
                            <IconButton 
                                onClick={handleAbort}
                                sx={{ 
                                    bgcolor: alpha(theme.palette.error.main, 0.1), 
                                    color: "error.main",
                                    width: 44, height: 44,
                                    "&:hover": { bgcolor: alpha(theme.palette.error.main, 0.2) }
                                }}
                            >
                                <StopRounded />
                            </IconButton>
                        </motion.div>
                        ) : (
                        <motion.div
                            key="send"
                            initial={{ scale: 0 }}
                            animate={{ scale: 1 }}
                            exit={{ scale: 0 }}
                            transition={{ type: "spring", stiffness: 400, damping: 25 }}
                        >
                            <IconButton
                                disabled={!canSend}
                                onClick={() => void handleSend()}
                                sx={{
                                    bgcolor: canSend ? "primary.main" : "action.disabledBackground",
                                    color: "#fff",
                                    width: 44, height: 44,
                                    transition: "background-color 0.2s",
                                    "&:hover": { 
                                        bgcolor: "primary.dark",
                                        boxShadow: `0 4px 12px ${alpha(theme.palette.primary.main, 0.5)}`
                                    }
                                }}
                            >
                                <SendRounded sx={{ ml: 0.5 }} />
                            </IconButton>
                        </motion.div>
                        )}
                    </AnimatePresence>
                </Box>
            </Stack>
          </motion.div>
        </Box>
      </Box>
    </Drawer>
  );
};
