"use client";

import Image from "next/image";
import React from "react";
import { AnimatePresence, motion } from "framer-motion";
import { Box, Paper, Skeleton, Stack, Typography, alpha, useTheme, Grid } from "@mui/material";
import WaterDropRounded from "@mui/icons-material/WaterDropRounded";
import SensorsRounded from "@mui/icons-material/SensorsRounded";
import TroubleshootRounded from "@mui/icons-material/TroubleshootRounded";
import MapRounded from "@mui/icons-material/MapRounded";

import { AgentTurn } from "./AgentTurn";
import type { PermissionReply } from "@/lib/chatStream";
import type {
  Message,
  SpeechState,
} from "./GlobalChatbox.types";

type AgentWorkspaceProps = {
  messages: Message[];
  isStreaming: boolean;
  isLoadingSession?: boolean;
  scrollContainerRef?: React.RefObject<HTMLDivElement | null>;
  bottomRef: React.RefObject<HTMLDivElement | null>;
  onScrollStateChange?: (isNearBottom: boolean) => void;
  speakingMessageId: string | null;
  speechState: SpeechState;
  onSpeak: (
    messageId: string,
    text: string,
    options?: { startOffset?: number },
  ) => void;
  onPauseSpeech: () => void;
  onResumeSpeech: () => void;
  onStopSpeech: () => void;
  isTtsSupported: boolean;
  onCreateBranch: (messageId: string) => void;
  onReplyPermission: (requestId: string, reply: PermissionReply) => void;
  onReplyQuestion: (requestId: string, answers: string[][]) => void;
  onRejectQuestion: (requestId: string) => void;
};

type TurnListProps = {
  messages: Message[];
  isAssistantStreaming: boolean;
  streamingMessageId: string | null;
  speakingMessageId: string | null;
  speechState: SpeechState;
  onSpeak: (
    messageId: string,
    text: string,
    options?: { startOffset?: number },
  ) => void;
  onPauseSpeech: () => void;
  onResumeSpeech: () => void;
  onStopSpeech: () => void;
  isTtsSupported: boolean;
  onCreateBranch: (messageId: string) => void;
  onReplyPermission: (requestId: string, reply: PermissionReply) => void;
  onReplyQuestion: (requestId: string, answers: string[][]) => void;
  onRejectQuestion: (requestId: string) => void;
};

const STREAMING_BOTTOM_RESERVE_PX = 180;
const STREAMING_NEAR_BOTTOM_THRESHOLD_PX = STREAMING_BOTTOM_RESERVE_PX + 120;

const sameMessages = (left: Message[], right: Message[]) =>
  left.length === right.length &&
  left.every((message, index) => message === right[index]);

const TurnItem = React.memo(AgentTurn);

const TurnListInner = ({
  messages,
  isAssistantStreaming,
  streamingMessageId,
  speakingMessageId,
  speechState,
  onSpeak,
  onPauseSpeech,
  onResumeSpeech,
  onStopSpeech,
  isTtsSupported,
  onCreateBranch,
  onReplyPermission,
  onReplyQuestion,
  onRejectQuestion,
}: TurnListProps) => {
  return (
    <>
      {messages.map((message) => (
        <TurnItem
          key={message.id}
          message={message}
          isStreaming={isAssistantStreaming && message.id === streamingMessageId}
          messageSpeechState={speakingMessageId === message.id ? speechState : "idle"}
          onSpeak={onSpeak}
          onPause={onPauseSpeech}
          onResume={onResumeSpeech}
          onStopSpeech={onStopSpeech}
          isTtsSupported={isTtsSupported}
          onCreateBranch={onCreateBranch}
          onReplyPermission={onReplyPermission}
          onReplyQuestion={onReplyQuestion}
          onRejectQuestion={onRejectQuestion}
        />
      ))}
    </>
  );
};

const TurnList = React.memo(
  TurnListInner,
  (prevProps, nextProps) =>
    sameMessages(prevProps.messages, nextProps.messages) &&
    prevProps.isAssistantStreaming === nextProps.isAssistantStreaming &&
    prevProps.streamingMessageId === nextProps.streamingMessageId &&
    prevProps.speakingMessageId === nextProps.speakingMessageId &&
    prevProps.speechState === nextProps.speechState &&
    prevProps.onSpeak === nextProps.onSpeak &&
    prevProps.onPauseSpeech === nextProps.onPauseSpeech &&
    prevProps.onResumeSpeech === nextProps.onResumeSpeech &&
    prevProps.onStopSpeech === nextProps.onStopSpeech &&
    prevProps.isTtsSupported === nextProps.isTtsSupported &&
    prevProps.onCreateBranch === nextProps.onCreateBranch &&
    prevProps.onReplyPermission === nextProps.onReplyPermission &&
    prevProps.onReplyQuestion === nextProps.onReplyQuestion &&
    prevProps.onRejectQuestion === nextProps.onRejectQuestion,
);

TurnList.displayName = "TurnList";

const EmptyState = () => {
  const theme = useTheme();
  const capabilities = [
    { icon: <WaterDropRounded sx={{ fontSize: 20, color: "#00acc1" }} />, label: "水力瓶颈识别" },
    { icon: <SensorsRounded sx={{ fontSize: 20, color: "#0288d1" }} />, label: "异常状态预警" },
    { icon: <TroubleshootRounded sx={{ fontSize: 20, color: "#43a047" }} />, label: "调度与改造建议" },
    { icon: <MapRounded sx={{ fontSize: 20, color: "#8e24aa" }} />, label: "GIS 地图联动" },
  ];

  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ type: "spring", stiffness: 200, damping: 20 }}
      style={{ margin: "auto", width: "100%", maxWidth: 440, padding: 16 }}
    >
      <Paper
        elevation={0}
        sx={{
          p: 4,
          borderRadius: 4,
          bgcolor: alpha("#ffffff", 0.4),
          border: `1px solid ${alpha("#fff", 0.8)}`,
          boxShadow: `0 16px 40px ${alpha("#000", 0.05)}`,
          textAlign: "center",
          backdropFilter: "blur(24px)",
          position: "relative",
          overflow: "hidden",
        }}
      >
        <Box sx={{
          position: "absolute",
          top: -100,
          right: -100,
          width: 200,
          height: 200,
          background: "radial-gradient(circle, rgba(0, 172, 193, 0.15) 0%, rgba(255,255,255,0) 70%)",
        }} />
        <motion.div
          animate={{
            y: [-6, 4, -6],
            scale: [1, 1.04, 1],
            rotate: [-3, 3, -3],
          }}
          transition={{ duration: 4.8, repeat: Infinity, ease: "easeInOut" }}
          style={{
            display: "inline-flex",
            alignItems: "center",
            justifyContent: "center",
            width: 88,
            height: 88,
            marginBottom: 12,
            borderRadius: "50%",
            background: "radial-gradient(circle, rgba(255,255,255,0.92) 0%, rgba(255,255,255,0.45) 58%, rgba(255,255,255,0) 100%)",
            boxShadow: "0 10px 28px rgba(0, 131, 143, 0.12)",
          }}
        >
          <Image
            src="/ai-agent.svg"
            alt="TJWater Agent"
            width={54}
            height={54}
            style={{
              objectFit: "contain",
              filter: "drop-shadow(0 4px 12px rgba(0, 131, 143, 0.2))",
            }}
          />
        </motion.div>
        <Typography variant="h6" color="text.primary" fontWeight={800} gutterBottom>
          我已就绪，请描述任务
        </Typography>
        <Typography variant="body2" color="text.secondary" sx={{ lineHeight: 1.6, mb: 3 }}>
          你可以使用自然语言下达指令，我会自主规划决策执行、并在地图上呈现分析结果。
        </Typography>

        <Grid container spacing={1.5}>
          {capabilities.map((item) => (
            <Grid item xs={6} key={item.label}>
              <motion.div whileHover={{ y: -2, scale: 1.02 }} transition={{ duration: 0.2 }}>
                <Stack
                  direction="row"
                  spacing={1}
                  alignItems="center"
                  justifyContent="center"
                  sx={{
                    px: 1.5,
                    py: 1.5,
                    borderRadius: 3,
                    bgcolor: alpha("#fff", 0.5),
                    border: `1px solid ${alpha("#fff", 0.6)}`,
                    boxShadow: `0 4px 12px ${alpha("#000", 0.03)}`,
                    color: "text.primary",
                    transition: "all 0.2s",
                    "&:hover": {
                      bgcolor: alpha("#fff", 0.8),
                      borderColor: alpha("#00acc1", 0.4),
                      boxShadow: `0 6px 16px ${alpha("#00acc1", 0.15)}`,
                    }
                  }}
                >
                  {item.icon}
                  <Typography variant="caption" fontWeight={700}>
                    {item.label}
                  </Typography>
                </Stack>
              </motion.div>
            </Grid>
          ))}
        </Grid>
      </Paper>
    </motion.div>
  );
};

const SessionLoadingSkeleton = () => (
  <Stack
    spacing={2.25}
    aria-label="正在加载历史记录"
    sx={{ width: "100%", maxWidth: 760, alignSelf: "stretch" }}
  >
    {Array.from({ length: 2 }, (_, turnIndex) => (
      <Stack key={turnIndex} spacing={1.25}>
        <Stack direction="row" justifyContent="flex-end">
          <Paper
            elevation={0}
            sx={{
              width: turnIndex === 0 ? "72%" : "64%",
              maxWidth: "86%",
              p: 1.75,
              borderRadius: 5,
              borderBottomRightRadius: 2,
              bgcolor: alpha("#00acc1", 0.16),
              border: `1px solid ${alpha("#00acc1", 0.12)}`,
              boxShadow: `0 8px 24px -12px ${alpha("#00acc1", 0.35)}`,
            }}
          >
            <Stack spacing={0.85}>
              <Skeleton variant="text" width="76%" height={18} />
              <Skeleton variant="text" width="48%" height={15} />
            </Stack>
          </Paper>
        </Stack>

        <Stack direction="row" spacing={1.5} alignItems="flex-start">
          <Skeleton
            variant="circular"
            width={34}
            height={34}
            sx={{ bgcolor: alpha("#00acc1", 0.12), flexShrink: 0, mt: 0.25 }}
          />
          <Paper
            elevation={0}
            sx={{
              flex: 1,
              minWidth: 0,
              p: 2,
              borderRadius: 5,
              bgcolor: alpha("#ffffff", 0.52),
              border: `1px solid ${alpha("#fff", 0.72)}`,
              boxShadow: `0 10px 30px -10px ${alpha("#000", 0.06)}`,
            }}
          >
            <Stack spacing={1}>
              <Skeleton variant="text" width="38%" height={16} />
              <Skeleton variant="text" width="94%" height={16} />
              <Skeleton variant="text" width={turnIndex === 0 ? "88%" : "82%"} height={16} />
              <Skeleton variant="text" width={turnIndex === 0 ? "78%" : "70%"} height={16} />
              <Skeleton variant="rounded" width="100%" height={turnIndex === 0 ? 104 : 76} sx={{ borderRadius: 2 }} />
            </Stack>
          </Paper>
        </Stack>
      </Stack>
    ))}
  </Stack>
);

export const AgentWorkspace = ({
  messages,
  isStreaming,
  isLoadingSession = false,
  scrollContainerRef,
  bottomRef,
  onScrollStateChange,
  speakingMessageId,
  speechState,
  onSpeak,
  onPauseSpeech,
  onResumeSpeech,
  onStopSpeech,
  isTtsSupported,
  onCreateBranch,
  onReplyPermission,
  onReplyQuestion,
  onRejectQuestion,
}: AgentWorkspaceProps) => {
  const streamingMessageId =
    isStreaming && messages.at(-1)?.role === "assistant"
      ? messages.at(-1)?.id ?? null
      : null;
  const handleScroll = React.useCallback(
    (event: React.UIEvent<HTMLDivElement>) => {
      if (!onScrollStateChange) return;
      const target = event.currentTarget;
      const distanceToBottom =
        target.scrollHeight - target.scrollTop - target.clientHeight;
      onScrollStateChange(
        distanceToBottom <
          (isStreaming ? STREAMING_NEAR_BOTTOM_THRESHOLD_PX : 96),
      );
    },
    [isStreaming, onScrollStateChange],
  );

  return (
    <Box
      ref={scrollContainerRef}
      onScroll={handleScroll}
      sx={{
        flex: 1,
        overflowY: "auto",
        px: 2.5,
        py: 2,
        display: "flex",
        flexDirection: "column",
        scrollbarGutter: "stable",
        zIndex: 5,
      }}
    >
      {isLoadingSession ? (
        <SessionLoadingSkeleton />
      ) : (
        <>
          <AnimatePresence initial={false}>
            {messages.length === 0 ? <EmptyState /> : null}
          </AnimatePresence>

          {messages.length > 0 ? (
            <Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
              <TurnList
                messages={messages}
                isAssistantStreaming={isStreaming}
                streamingMessageId={streamingMessageId}
                speakingMessageId={speakingMessageId}
                speechState={speechState}
                onSpeak={onSpeak}
                onPauseSpeech={onPauseSpeech}
                onResumeSpeech={onResumeSpeech}
                onStopSpeech={onStopSpeech}
                isTtsSupported={isTtsSupported}
                onCreateBranch={onCreateBranch}
                onReplyPermission={onReplyPermission}
                onReplyQuestion={onReplyQuestion}
                onRejectQuestion={onRejectQuestion}
              />
            </Box>
          ) : null}
        </>
      )}

      <div
        ref={bottomRef}
        style={{
          flexShrink: 0,
          height: isStreaming ? STREAMING_BOTTOM_RESERVE_PX : 1,
        }}
      />
    </Box>
  );
};
