"use client";

import React from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { motion } from "framer-motion";
import {
  Avatar,
  Box,
  Chip,
  IconButton,
  LinearProgress,
  Paper,
  Stack,
  Typography,
  alpha,
} from "@mui/material";
import type { Theme } from "@mui/material/styles";
import AutoAwesome from "@mui/icons-material/AutoAwesome";
import CheckCircleRounded from "@mui/icons-material/CheckCircleRounded";
import ErrorOutlineRounded from "@mui/icons-material/ErrorOutlineRounded";
import HourglassEmptyRounded from "@mui/icons-material/HourglassEmptyRounded";
import VolumeUpRounded from "@mui/icons-material/VolumeUpRounded";
import PauseRounded from "@mui/icons-material/PauseRounded";
import PlayArrowRounded from "@mui/icons-material/PlayArrowRounded";
import StopRounded from "@mui/icons-material/StopRounded";
import {
  parseAssistantMessageSections,
  parseContentWithToolCalls,
  type ContentSegment,
} from "./chatMessageSections";
import { ChatInlineChart } from "./ChatInlineChart";
import { ChatToolCallBlock } from "./ChatToolCallBlock";
import markdownStyles from "./GlobalChatboxMarkdown.module.css";
import type { ChatProgress, Message, SpeechState } from "./GlobalChatbox.types";
import { stripMarkdown } from "./GlobalChatbox.utils";

export const TypingIndicator = () => {
  return (
    <Stack direction="row" spacing={0.5} alignItems="center" sx={{ p: 1 }}>
      {[0, 1, 2].map((i) => (
        <motion.div
          key={i}
          initial={{ y: 0 }}
          animate={{ y: [-4, 4, -4] }}
          transition={{
            duration: 0.6,
            repeat: Infinity,
            delay: i * 0.15,
            ease: "easeInOut",
          }}
        >
          <Box
            sx={{
              width: 8,
              height: 8,
              borderRadius: "50%",
              background: "linear-gradient(135deg, #FF6B6B 0%, #FF8E53 100%)",
            }}
          />
        </motion.div>
      ))}
    </Stack>
  );
};

export const Blob = ({
  color,
  size,
  top,
  left,
  delay,
}: {
  color: string;
  size: number;
  top: string;
  left: string;
  delay: number;
}) => (
  <motion.div
    initial={{ scale: 0.8, opacity: 0.3, x: 0, y: 0 }}
    animate={{
      scale: [0.8, 1.2, 0.8],
      opacity: [0.3, 0.5, 0.3],
      x: [0, 30, 0],
      y: [0, -30, 0],
    }}
    transition={{
      duration: 8,
      repeat: Infinity,
      ease: "easeInOut",
      delay,
    }}
    style={{
      position: "absolute",
      top,
      left,
      width: size,
      height: size,
      borderRadius: "50%",
      background: color,
      filter: "blur(60px)",
      zIndex: 0,
      pointerEvents: "none",
    }}
  />
);

type ChatMessageItemProps = {
  message: Message;
  theme: Theme;
  messageSpeechState: SpeechState;
  onSpeak: (messageId: string, text: string) => void;
  onPause: () => void;
  onResume: () => void;
  onStopSpeech: () => void;
  isTtsSupported: boolean;
  sseChartParams?: Array<{ tool: string; params: Record<string, unknown> }>;
};

export const ChatMessageItem = React.memo(
  ({
    message,
    theme,
    messageSpeechState,
    onSpeak,
    onPause,
    onResume,
    onStopSpeech,
    isTtsSupported,
    sseChartParams,
  }: ChatMessageItemProps) => {
    const isUser = message.role === "user";
    const isErrorMessage = Boolean(message.isError);
    const parsedAssistantSections =
      !isUser && !isErrorMessage
        ? parseAssistantMessageSections(message.content)
        : null;
    const answerContent = parsedAssistantSections?.answer ?? message.content;

    const contentSegments: ContentSegment[] =
      !isUser && !isErrorMessage
        ? parseContentWithToolCalls(answerContent).segments
        : [{ type: "text", content: answerContent }];

    return (
      <motion.div
        initial={{ opacity: 0, scale: 0.8, x: isUser ? 50 : -50 }}
        animate={{ opacity: 1, scale: 1, x: 0 }}
        exit={{ opacity: 0, scale: 0.8 }}
        transition={{ type: "spring", stiffness: 350, damping: 25 }}
        style={{
          alignSelf: isUser ? "flex-end" : "flex-start",
          maxWidth: "85%",
          display: "flex",
          flexDirection: isUser ? "row-reverse" : "row",
          gap: 12,
          alignItems: "flex-end",
        }}
      >
        {!isUser && (
          <Avatar
            sx={{
              width: 28,
              height: 28,
              bgcolor: isErrorMessage
                ? alpha(theme.palette.error.main, 0.12)
                : alpha(theme.palette.secondary.main, 0.1),
              mb: 0.5,
            }}
          >
            {isErrorMessage ? (
              <ErrorOutlineRounded sx={{ fontSize: 16, color: "error.main" }} />
            ) : (
              <AutoAwesome sx={{ fontSize: 16, color: "secondary.main" }} />
            )}
          </Avatar>
        )}

        <Box>
          <Paper
            elevation={isUser ? 8 : isErrorMessage ? 1 : 2}
            sx={{
              p: 2.5,
              borderRadius: 4,
              borderBottomRightRadius: isUser ? 4 : 24,
              borderBottomLeftRadius: !isUser ? 4 : 24,
              bgcolor: isUser
                ? "primary.main"
                : isErrorMessage
                  ? alpha(theme.palette.error.light, 0.18)
                  : "#fff",
              color: isUser ? "#fff" : isErrorMessage ? "error.dark" : "text.primary",
              background: isUser
                ? `linear-gradient(135deg, ${theme.palette.primary.main}, ${theme.palette.primary.dark})`
                : isErrorMessage
                  ? `linear-gradient(135deg, ${alpha(theme.palette.error.light, 0.28)}, ${alpha(theme.palette.error.main, 0.12)})`
                  : undefined,
              border: isErrorMessage
                ? `1px solid ${alpha(theme.palette.error.main, 0.35)}`
                : "none",
              boxShadow: isUser
                ? `0 8px 24px -4px ${alpha(theme.palette.primary.main, 0.5)}`
                : isErrorMessage
                  ? `0 4px 16px -4px ${alpha(theme.palette.error.main, 0.2)}`
                  : `0 4px 16px -4px ${alpha("#000", 0.05)}`,
              "--chat-md-text": isUser
                ? alpha("#fff", 0.96)
                : isErrorMessage
                  ? theme.palette.error.dark
                  : "#1f2937",
              "--chat-md-heading": isUser
                ? "#fff"
                : isErrorMessage
                  ? theme.palette.error.dark
                  : "#111827",
              "--chat-md-link": isUser
                ? "#E3F2FD"
                : isErrorMessage
                  ? theme.palette.error.main
                  : "#7C3AED",
              "--chat-md-link-hover": isUser
                ? "#fff"
                : isErrorMessage
                  ? theme.palette.error.dark
                  : "#6D28D9",
              "--chat-md-inline-code-bg": isUser
                ? "rgba(255,255,255,0.2)"
                : isErrorMessage
                  ? alpha(theme.palette.error.main, 0.08)
                  : "#EEF2FF",
              "--chat-md-inline-code-border": isUser
                ? alpha("#fff", 0.16)
                : isErrorMessage
                  ? alpha(theme.palette.error.main, 0.25)
                  : "#CBD5E1",
              "--chat-md-inline-code-text": isUser
                ? "#fff"
                : isErrorMessage
                  ? theme.palette.error.dark
                  : "#334155",
              "--chat-md-pre-bg": isUser
                ? "rgba(11, 18, 32, 0.56)"
                : isErrorMessage
                  ? alpha(theme.palette.error.main, 0.08)
                  : "#111827",
              "--chat-md-pre-border": isUser
                ? alpha("#fff", 0.12)
                : isErrorMessage
                  ? alpha(theme.palette.error.main, 0.3)
                  : "#64748B",
              "--chat-md-pre-text": isUser
                ? "#F8FAFC"
                : isErrorMessage
                  ? theme.palette.error.dark
                  : "#E5E7EB",
              "--chat-md-quote-border": isErrorMessage
                ? alpha(theme.palette.error.main, 0.5)
                : isUser
                  ? alpha("#fff", 0.5)
                  : "#7C3AED",
              "--chat-md-quote-bg": isUser
                ? alpha("#fff", 0.08)
                : isErrorMessage
                  ? alpha(theme.palette.error.main, 0.06)
                  : "#F5F3FF",
              "--chat-md-quote-text": isUser
                ? alpha("#fff", 0.9)
                : isErrorMessage
                  ? theme.palette.error.dark
                  : "#475569",
            }}
          >
            {!isUser && !isErrorMessage && message.progress?.length ? (
              <ChatProgressPanel progress={message.progress} />
            ) : null}
            {contentSegments.map((segment, segIdx) => {
              if (segment.type === "text") {
                const text = segment.content.trim();
                if (!text && contentSegments.length > 1) return null;
                return (
                  <div key={segIdx} className={markdownStyles.markdown}>
                    <ReactMarkdown remarkPlugins={[remarkGfm]}>
                      {text || "..."}
                    </ReactMarkdown>
                  </div>
                );
              }
              if (segment.type === "tool_call") {
                if (segment.toolCall.tool === "chart") {
                  return (
                    <ChatInlineChart
                      key={segment.toolCall.id}
                      {...(segment.toolCall.params as Record<string, unknown>)}
                    />
                  );
                }
                if (segment.toolCall.tool === "show_chart") {
                  const p = segment.toolCall.params;
                  return (
                    <ChatInlineChart
                      key={segment.toolCall.id}
                      title={(p.title as string) ?? undefined}
                      chart_type={
                        (p.chart_type as "line" | "bar" | "pie") ?? "line"
                      }
                      x_data={(p.x_data as string[]) ?? []}
                      series={
                        (p.series as import("./ChatInlineChart").ChatChartSeries[]) ??
                        []
                      }
                      x_axis_name={(p.x_axis_name as string) ?? undefined}
                      y_axis_name={(p.y_axis_name as string) ?? undefined}
                    />
                  );
                }
                return (
                  <ChatToolCallBlock
                    key={segment.toolCall.id}
                    toolCall={segment.toolCall}
                  />
                );
              }
              if (segment.type === "tool_call_pending") {
                return (
                  <motion.div
                    key="tool-pending"
                    initial={{ opacity: 0 }}
                    animate={{ opacity: [0.4, 1, 0.4] }}
                    transition={{
                      duration: 1.5,
                      repeat: Infinity,
                      ease: "easeInOut",
                    }}
                    style={{
                      marginTop: 8,
                      display: "flex",
                      alignItems: "center",
                      gap: 8,
                    }}
                  >
                    <AutoAwesome sx={{ fontSize: 14, color: "primary.main" }} />
                    <Typography variant="caption" color="text.secondary">
                      正在准备工具调用...
                    </Typography>
                  </motion.div>
                );
              }
              return null;
            })}
            {sseChartParams?.map((chart, idx) => (
              <ChatInlineChart
                key={`sse-chart-${idx}`}
                title={(chart.params.title as string) ?? undefined}
                chart_type={
                  (chart.params.chart_type as "line" | "bar" | "pie") ?? "line"
                }
                x_data={(chart.params.x_data as string[]) ?? []}
                series={
                  (chart.params.series as import("./ChatInlineChart").ChatChartSeries[]) ??
                  []
                }
                x_axis_name={(chart.params.x_axis_name as string) ?? undefined}
                y_axis_name={(chart.params.y_axis_name as string) ?? undefined}
              />
            ))}
          </Paper>
          {!isUser && !isErrorMessage && isTtsSupported && (
            <Stack direction="row" spacing={0.5} sx={{ mt: 0.5, ml: 0.5 }}>
              {messageSpeechState === "idle" && (
                <IconButton
                  size="small"
                  onClick={() => onSpeak(message.id, stripMarkdown(answerContent))}
                  aria-label="朗读消息"
                  sx={{
                    color: "text.secondary",
                    opacity: 0.6,
                    "&:hover": { opacity: 1 },
                    p: 0.5,
                  }}
                >
                  <VolumeUpRounded sx={{ fontSize: 16 }} />
                </IconButton>
              )}
              {messageSpeechState === "playing" && (
                <>
                  <IconButton
                    size="small"
                    onClick={onPause}
                    aria-label="暂停朗读"
                    sx={{ color: "primary.main", p: 0.5 }}
                  >
                    <PauseRounded sx={{ fontSize: 16 }} />
                  </IconButton>
                  <IconButton
                    size="small"
                    onClick={onStopSpeech}
                    aria-label="停止朗读"
                    sx={{ color: "error.main", p: 0.5 }}
                  >
                    <StopRounded sx={{ fontSize: 16 }} />
                  </IconButton>
                </>
              )}
              {messageSpeechState === "paused" && (
                <>
                  <IconButton
                    size="small"
                    onClick={onResume}
                    aria-label="继续朗读"
                    sx={{ color: "primary.main", p: 0.5 }}
                  >
                    <PlayArrowRounded sx={{ fontSize: 16 }} />
                  </IconButton>
                  <IconButton
                    size="small"
                    onClick={onStopSpeech}
                    aria-label="停止朗读"
                    sx={{ color: "error.main", p: 0.5 }}
                  >
                    <StopRounded sx={{ fontSize: 16 }} />
                  </IconButton>
                </>
              )}
            </Stack>
          )}
        </Box>
      </motion.div>
    );
  },
);

ChatMessageItem.displayName = "ChatMessageItem";

const ChatProgressPanel = ({ progress }: { progress: ChatProgress[] }) => {
  const isComplete = progress.some(
    (item) => item.phase === "complete" && item.status === "completed",
  );
  const latestRunning = isComplete
    ? undefined
    : [...progress].reverse().find((item) => item.status === "running");
  return (
    <Box
      sx={{
        mb: 1.5,
        p: 1.25,
        borderRadius: 2.5,
        bgcolor: "rgba(99, 102, 241, 0.06)",
        border: "1px solid rgba(99, 102, 241, 0.14)",
      }}
    >
      <Stack spacing={1}>
        <Stack direction="row" spacing={1} alignItems="center">
          <AutoAwesome sx={{ fontSize: 16, color: "primary.main" }} />
          <Typography variant="caption" fontWeight={800} color="text.primary">
            Agent 过程
          </Typography>
          {latestRunning ? (
            <Chip
              size="small"
              label={latestRunning.title}
              sx={{ height: 20, fontSize: "0.68rem", bgcolor: "rgba(124, 58, 237, 0.08)" }}
            />
          ) : null}
        </Stack>
        {latestRunning ? <LinearProgress sx={{ height: 4, borderRadius: 99 }} /> : null}
        <Stack spacing={0.7}>
          {progress.slice(-5).map((item) => (
            <Stack key={item.id} direction="row" spacing={0.8} alignItems="flex-start">
              {item.status === "completed" ? (
                <CheckCircleRounded sx={{ fontSize: 15, color: "success.main", mt: 0.2 }} />
              ) : item.status === "error" ? (
                <ErrorOutlineRounded sx={{ fontSize: 15, color: "error.main", mt: 0.2 }} />
              ) : (
                <HourglassEmptyRounded sx={{ fontSize: 15, color: "primary.main", mt: 0.2 }} />
              )}
              <Box sx={{ minWidth: 0 }}>
                <Typography variant="caption" color="text.primary" fontWeight={700}>
                  {item.title}
                </Typography>
                {item.detail ? (
                  <Typography
                    variant="caption"
                    component="pre"
                    color="text.secondary"
                    sx={{
                      display: "block",
                      mt: 0.25,
                      m: 0,
                      whiteSpace: "pre-wrap",
                      fontFamily: "inherit",
                      fontSize: "0.7rem",
                    }}
                  >
                    {item.detail}
                  </Typography>
                ) : null}
              </Box>
            </Stack>
          ))}
        </Stack>
      </Stack>
    </Box>
  );
};
