// src/components/StockChart/TimelineChartModal.tsx - 分时图弹窗组件
import React, { useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import {
  Modal,
  ModalOverlay,
  ModalContent,
  ModalHeader,
  ModalCloseButton,
  ModalBody,
  VStack,
  HStack,
  Text,
  Box,
  Flex,
  CircularProgress,
  Alert,
  AlertIcon,
} from '@chakra-ui/react';
import * as echarts from 'echarts';
import dayjs from 'dayjs';
import { klineDataCache, getCacheKey, fetchKlineData } from '@utils/stock/klineDataCache';
import { selectIsMobile } from '@store/slices/deviceSlice';
import { StockInfo } from './types';

/**
 * TimelineChartModal 组件 Props
 */
export interface TimelineChartModalProps {
  /** 模态框是否打开 */
  isOpen: boolean;
  /** 关闭回调 */
  onClose: () => void;
  /** 股票信息 */
  stock: StockInfo | null;
  /** 事件时间 */
  eventTime?: string | null;
  /** 模态框大小 */
  size?: string;
}

/**
 * 分时图数据点
 */
interface TimelineDataPoint {
  time: string;
  price: number;
  avg_price: number;
  volume: number;
  change_percent: number;
}

const TimelineChartModal: React.FC<TimelineChartModalProps> = ({
  isOpen,
  onClose,
  stock,
  eventTime,
  size = '5xl',
}) => {
  const chartRef = useRef<HTMLDivElement>(null);
  const chartInstance = useRef<echarts.ECharts | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [data, setData] = useState<TimelineDataPoint[]>([]);

  // H5 响应式适配
  const isMobile = useSelector(selectIsMobile);

  // 加载分时图数据（优先使用缓存）
  const loadData = async () => {
    if (!stock?.stock_code) return;

    setLoading(true);
    setError(null);

    try {
      // 标准化事件时间
      const stableEventTime = eventTime ? dayjs(eventTime).format('YYYY-MM-DD HH:mm') : '';

      // 先检查缓存
      const cacheKey = getCacheKey(stock.stock_code, stableEventTime, 'timeline');
      const cachedData = klineDataCache.get(cacheKey);

      if (cachedData && cachedData.length > 0) {
        console.log('[TimelineChartModal] 使用缓存数据, 数据条数:', cachedData.length);
        setData(cachedData);
        setLoading(false);
        return;
      }

      // 缓存没有则请求（会自动存入缓存）
      console.log('[TimelineChartModal] 缓存未命中，发起请求');
      const result = await fetchKlineData(stock.stock_code, stableEventTime, 'timeline');

      if (!result || result.length === 0) {
        throw new Error('暂无分时数据');
      }

      console.log('[TimelineChartModal] 数据条数:', result.length);
      setData(result);
    } catch (err) {
      const errorMsg = err instanceof Error ? err.message : '数据加载失败';
      setError(errorMsg);
    } finally {
      setLoading(false);
    }
  };

  // 初始化图表
  useEffect(() => {
    if (!isOpen) return;

    // 延迟初始化，确保 Modal 动画完成后 DOM 已经渲染
    const timer = setTimeout(() => {
      if (!chartRef.current) {
        console.error('[TimelineChartModal] DOM元素未找到，无法初始化图表');
        return;
      }

      console.log('[TimelineChartModal] 初始化图表...');

      // 创建图表实例（不使用主题，直接在option中配置背景色）
      chartInstance.current = echarts.init(chartRef.current);

      console.log('[TimelineChartModal] 图表实例创建成功');

      // 监听窗口大小变化
      const handleResize = () => {
        chartInstance.current?.resize();
      };
      window.addEventListener('resize', handleResize);

      return () => {
        window.removeEventListener('resize', handleResize);
      };
    }, 100); // 延迟100ms等待Modal完全打开

    return () => {
      clearTimeout(timer);
      if (chartInstance.current) {
        chartInstance.current.dispose();
        chartInstance.current = null;
      }
    };
  }, [isOpen]);

  // 更新图表数据
  useEffect(() => {
    if (data.length === 0) {
      console.log('[TimelineChartModal] 无数据，跳过图表更新');
      return;
    }

    // 如果图表还没初始化，等待200ms后重试（给图表初始化留出时间）
    const updateChart = () => {
      if (!chartInstance.current) {
        console.warn('[TimelineChartModal] 图表实例不存在');
        return false;
      }

      console.log('[TimelineChartModal] 开始更新图表，数据点:', data.length);

    const times = data.map((d) => d.time);
    const prices = data.map((d) => d.price);
    const avgPrices = data.map((d) => d.avg_price);
    const volumes = data.map((d) => d.volume);

    // 计算涨跌颜色
    const basePrice = data[0]?.price || 0;
    const volumeColors = data.map((d) =>
      d.price >= basePrice ? '#ef5350' : '#26a69a'
    );

    // 提取事件发生时间（HH:MM格式）
    let eventTimeStr: string | null = null;
    if (eventTime) {
      try {
        const eventDate = new Date(eventTime);
        const hours = eventDate.getHours().toString().padStart(2, '0');
        const minutes = eventDate.getMinutes().toString().padStart(2, '0');
        eventTimeStr = `${hours}:${minutes}`;
        console.log('[TimelineChartModal] 事件发生时间:', eventTimeStr);
      } catch (e) {
        console.error('[TimelineChartModal] 解析事件时间失败:', e);
      }
    }

    // 图表配置（H5 响应式）
    const option: echarts.EChartsOption = {
      backgroundColor: '#1a1a1a',
      title: {
        text: `${stock?.stock_name || stock?.stock_code} - 分时图`,
        left: 'center',
        top: isMobile ? 5 : 10,
        textStyle: {
          color: '#e0e0e0',
          fontSize: isMobile ? 14 : 18,
          fontWeight: 'bold',
        },
      },
      tooltip: {
        trigger: 'axis',
        backgroundColor: 'rgba(30, 30, 30, 0.95)',
        borderColor: '#404040',
        borderWidth: 1,
        textStyle: {
          color: '#e0e0e0',
        },
        axisPointer: {
          type: 'cross',
          crossStyle: {
            color: '#999',
          },
        },
        formatter: (params: any) => {
          const dataIndex = params[0]?.dataIndex;
          if (dataIndex === undefined) return '';

          const item = data[dataIndex];
          if (!item) return '';

          // 安全格式化数字
          const safeFixed = (val: any, digits = 2) =>
            val != null && !isNaN(val) ? Number(val).toFixed(digits) : '-';

          const changePercent = item.change_percent ?? 0;
          const changeColor = changePercent >= 0 ? '#ef5350' : '#26a69a';
          const changeSign = changePercent >= 0 ? '+' : '';

          return `
            <div style="padding: 8px;">
              <div style="font-weight: bold; margin-bottom: 8px;">${item.time || '-'}</div>
              <div style="display: flex; justify-content: space-between; margin-bottom: 4px;">
                <span>价格:</span>
                <span style="color: ${changeColor}; font-weight: bold; margin-left: 20px;">${safeFixed(item.price)}</span>
              </div>
              <div style="display: flex; justify-content: space-between; margin-bottom: 4px;">
                <span>均价:</span>
                <span style="color: #ffa726; margin-left: 20px;">${safeFixed(item.avg_price)}</span>
              </div>
              <div style="display: flex; justify-content: space-between; margin-bottom: 4px;">
                <span>涨跌幅:</span>
                <span style="color: ${changeColor}; margin-left: 20px;">${changeSign}${safeFixed(changePercent)}%</span>
              </div>
              <div style="display: flex; justify-content: space-between;">
                <span>成交量:</span>
                <span style="margin-left: 20px;">${item.volume != null ? (item.volume / 100).toFixed(0) : '-'}手</span>
              </div>
            </div>
          `;
        },
      },
      grid: [
        {
          left: isMobile ? '12%' : '5%',
          right: isMobile ? '5%' : '5%',
          top: isMobile ? '12%' : '15%',
          height: isMobile ? '58%' : '55%',
        },
        {
          left: isMobile ? '12%' : '5%',
          right: isMobile ? '5%' : '5%',
          top: isMobile ? '75%' : '75%',
          height: isMobile ? '18%' : '15%',
        },
      ],
      xAxis: [
        {
          type: 'category',
          data: times,
          gridIndex: 0,
          axisLine: {
            lineStyle: {
              color: '#404040',
            },
          },
          axisLabel: {
            color: '#999',
            fontSize: isMobile ? 10 : 12,
            interval: Math.floor(times.length / (isMobile ? 4 : 6)),
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: '#2a2a2a',
            },
          },
        },
        {
          type: 'category',
          data: times,
          gridIndex: 1,
          axisLine: {
            lineStyle: {
              color: '#404040',
            },
          },
          axisLabel: {
            color: '#999',
            fontSize: isMobile ? 10 : 12,
            interval: Math.floor(times.length / (isMobile ? 4 : 6)),
          },
        },
      ],
      yAxis: [
        {
          scale: true,
          gridIndex: 0,
          splitNumber: isMobile ? 4 : 5,
          splitLine: {
            show: true,
            lineStyle: {
              color: '#2a2a2a',
            },
          },
          axisLine: {
            lineStyle: {
              color: '#404040',
            },
          },
          axisLabel: {
            color: '#999',
            fontSize: isMobile ? 10 : 12,
            formatter: (value: number) => (value != null && !isNaN(value)) ? value.toFixed(2) : '-',
          },
        },
        {
          scale: true,
          gridIndex: 1,
          splitNumber: isMobile ? 2 : 3,
          splitLine: {
            show: false,
          },
          axisLine: {
            lineStyle: {
              color: '#404040',
            },
          },
          axisLabel: {
            color: '#999',
            fontSize: isMobile ? 10 : 12,
            formatter: (value: number) => {
              if (value == null || isNaN(value)) return '-';
              if (value >= 10000) {
                return (value / 10000).toFixed(1) + '万';
              }
              return value.toFixed(0);
            },
          },
        },
      ],
      series: [
        {
          name: '价格',
          type: 'line',
          data: prices,
          xAxisIndex: 0,
          yAxisIndex: 0,
          smooth: true,
          symbol: 'none',
          lineStyle: {
            color: '#2196f3',
            width: 2,
          },
          areaStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: 'rgba(33, 150, 243, 0.3)' },
              { offset: 1, color: 'rgba(33, 150, 243, 0.05)' },
            ]),
          },
          markLine: eventTimeStr ? {
            silent: false,
            symbol: 'none',
            label: {
              show: true,
              position: 'insideEndTop',
              formatter: '事件发生',
              color: '#ffd700',
              fontSize: 12,
              fontWeight: 'bold',
              backgroundColor: 'rgba(0, 0, 0, 0.7)',
              padding: [4, 8],
              borderRadius: 4,
            },
            lineStyle: {
              color: '#ffd700',
              width: 2,
              type: 'solid',
            },
            data: [
              {
                xAxis: eventTimeStr,
                label: {
                  formatter: '⚡ 事件发生',
                },
              },
            ],
          } : undefined,
        },
        {
          name: '均价',
          type: 'line',
          data: avgPrices,
          xAxisIndex: 0,
          yAxisIndex: 0,
          smooth: true,
          symbol: 'none',
          lineStyle: {
            color: '#ffa726',
            width: 1.5,
            type: 'dashed',
          },
        },
        {
          name: '成交量',
          type: 'bar',
          data: volumes,
          xAxisIndex: 1,
          yAxisIndex: 1,
          itemStyle: {
            color: (params: any) => {
              return volumeColors[params.dataIndex];
            },
          },
        },
      ],
      dataZoom: [
        {
          type: 'inside',
          xAxisIndex: [0, 1],
          start: 0,
          end: 100,
        },
      ],
    };

      chartInstance.current.setOption(option);
      console.log('[TimelineChartModal] 图表option已设置');

      // 强制resize以确保图表正确显示
      setTimeout(() => {
        chartInstance.current?.resize();
        console.log('[TimelineChartModal] 图表已resize');
      }, 100);

      return true;
    };

    // 立即尝试更新，如果失败则重试
    if (!updateChart()) {
      console.log('[TimelineChartModal] 第一次更新失败，200ms后重试...');
      const retryTimer = setTimeout(() => {
        updateChart();
      }, 200);

      return () => clearTimeout(retryTimer);
    }
  }, [data, stock, isMobile]);

  // 加载数据
  useEffect(() => {
    if (isOpen) {
      loadData();
    }
  }, [isOpen, stock?.stock_code, eventTime]);

  if (!stock) return null;

  return (
    <Modal isOpen={isOpen} onClose={onClose} size={size} isCentered>
      <ModalOverlay bg="blackAlpha.700" />
      <ModalContent
        w={isMobile ? '96vw' : '90vw'}
        maxW={isMobile ? '96vw' : '1400px'}
        borderRadius={isMobile ? '12px' : '8px'}
        bg="#1a1a1a"
        border="2px solid #ffd700"
        boxShadow="0 0 30px rgba(255, 215, 0, 0.5)"
        overflow="visible"
      >
        <ModalHeader pb={isMobile ? 2 : 3} borderBottomWidth="1px" borderColor="#404040">
          <VStack align="flex-start" spacing={0}>
            <HStack>
              <Text fontSize={isMobile ? 'md' : 'lg'} fontWeight="bold" color="#e0e0e0">
                {stock.stock_name || stock.stock_code} ({stock.stock_code})
              </Text>
            </HStack>
            <Text fontSize={isMobile ? 'xs' : 'sm'} color="#999">
              分时走势图
            </Text>
          </VStack>
        </ModalHeader>
        <ModalCloseButton color="#999" _hover={{ color: '#e0e0e0' }} />
        <ModalBody p={isMobile ? 2 : 4}>
          {error && (
            <Alert status="error" bg="#2a1a1a" borderColor="#ef5350" mb={4}>
              <AlertIcon color="#ef5350" />
              <Text color="#e0e0e0">{error}</Text>
            </Alert>
          )}

          <Box position="relative" w="100%">
            {loading && (
              <Flex
                position="absolute"
                top="0"
                left="0"
                right="0"
                bottom="0"
                bg="rgba(26, 26, 26, 0.7)"
                zIndex="10"
                alignItems="center"
                justifyContent="center"
              >
                <VStack spacing={4}>
                  <CircularProgress isIndeterminate color="blue.400" />
                  <Text color="#e0e0e0">加载分时数据...</Text>
                </VStack>
              </Flex>
            )}
            {/* 使用 aspect-ratio 保持图表宽高比，与日K线保持一致 */}
            <Box
              ref={chartRef}
              w="100%"
              sx={{
                aspectRatio: isMobile ? '1.8 / 1' : '2.5 / 1',
              }}
              minH={isMobile ? '280px' : '400px'}
            />
          </Box>
        </ModalBody>
      </ModalContent>
    </Modal>
  );
};

export default TimelineChartModal;
