'use client';

/**
 * Lightweight Charts 图表组件
 * 支持多指标切换、多窗口布局
 */

import { useEffect, useRef, useCallback, useState } from 'react';
import { createChart, ColorType, IChartApi, CandlestickData, LineData, Time, HistogramData, SeriesMarker } from 'lightweight-charts';
import type { KLine } from '@/lib/api';
import type { Trade } from '@/store/gameStore';
import * as indicators from '@/lib/indicators';

interface ChartProps {
  data: KLine[];
  currentIndex: number;
  className?: string;
  mainIndicator: string;
  subIndicator1: string;
  subIndicator2: string;
  onCrosshairMove?: (data: KLine | null) => void;
  initialIndex?: number; // 初始索引，用于判断是否需要滚动到起始位置
  history?: Trade[]; // 交易历史，用于显示买卖标记
}

export default function Chart({ 
  data, 
  currentIndex, 
  className = '',
  mainIndicator,
  subIndicator1,
  subIndicator2,
  onCrosshairMove,
  initialIndex,
  history = []
}: ChartProps) {
  const chartContainerRef = useRef<HTMLDivElement>(null);
  const chartRef = useRef<IChartApi | null>(null);
  const seriesRef = useRef<any>({}); // 存储所有 series 引用
  const [legendData, setLegendData] = useState<any>(null);
  
  // 使用 ref 存储最新的数据和回调，避免闭包陷阱
  const dataRef = useRef(data);
  const currentIndexRef = useRef(currentIndex);
  const onCrosshairMoveRef = useRef(onCrosshairMove);
  
  // 记录上一次的数据长度，用于检测游戏开始或重开
  const prevDataLengthRef = useRef(0);
  // 记录上一次的 initialIndex，用于检测游戏是否重开
  const prevInitialIndexRef = useRef<number | undefined>(undefined);
  
  // 同步更新 refs
  useEffect(() => {
    dataRef.current = data;
  }, [data]);
  
  useEffect(() => {
    currentIndexRef.current = currentIndex;
  }, [currentIndex]);
  
  useEffect(() => {
    onCrosshairMoveRef.current = onCrosshairMove;
  }, [onCrosshairMove]);
  
  // 转换 K 线数据
  const convertToChartData = useCallback((klines: KLine[], endIndex: number): CandlestickData[] => {
    return klines.slice(0, endIndex + 1).map((k) => ({
      time: k.date as Time,
      open: k.open,
      high: k.high,
      low: k.low,
      close: k.close,
    }));
  }, []);

  // 初始化图表
  useEffect(() => {
    if (!chartContainerRef.current) return;
    
    const chart = createChart(chartContainerRef.current, {
      layout: {
        background: { type: ColorType.Solid, color: '#0D1421' },
        textColor: '#9CA3AF',
        fontFamily: "'Roboto', sans-serif",
      },
      grid: {
        vertLines: { color: '#1F2937' },
        horzLines: { color: '#1F2937' },
      },
      width: chartContainerRef.current.clientWidth,
      height: chartContainerRef.current.clientHeight,
      crosshair: {
        mode: 1,
        vertLine: {
          color: '#6B7280',
          width: 1,
          style: 3,
          labelBackgroundColor: '#374151',
        },
        horzLine: {
          color: '#6B7280',
          width: 1,
          style: 3,
          labelBackgroundColor: '#374151',
        },
      },
      timeScale: {
        borderColor: '#374151',
        timeVisible: true,
        rightOffset: 12,
        barSpacing: 6,
        minBarSpacing: 0.1, // 允许极致缩小，使 K 线看起来像曲线
      },
    });
    
    chartRef.current = chart;
    
    // 基础 K 线系列 (始终存在)
    const candlestickSeries = chart.addCandlestickSeries({
      upColor: '#FD1050',
      downColor: '#00F0F0',
      borderUpColor: '#FD1050',
      borderDownColor: '#00F0F0',
      wickUpColor: '#FD1050',
      wickDownColor: '#00F0F0',
    });
    seriesRef.current.candlestick = candlestickSeries;

    // 十字光标移动事件
    chart.subscribeCrosshairMove((param) => {
      if (!param.time || !param.point || param.point.x < 0 || param.point.y < 0) {
        setLegendData(null);
        // 无光标时，传递 null 表示应显示最新数据
        onCrosshairMoveRef.current?.(null);
        return;
      }
      
      const data: any = { time: param.time }; // 捕获时间
      // 获取 K 线数据
      const candleData = param.seriesData.get(candlestickSeries) as CandlestickData;
      if (candleData) {
        data.open = candleData.open;
        data.high = candleData.high;
        data.low = candleData.low;
        data.close = candleData.close;
      }

      // 获取其他指标数据
      Object.entries(seriesRef.current).forEach(([key, series]: [string, any]) => {
        if (key === 'candlestick') return;
        const val = param.seriesData.get(series);
        if (val !== undefined) {
          data[key] = (val as any).value;
        }
      });
      
      setLegendData(data);
      
      // 根据 time 找到原始 K 线数据并回调
      const timeStr = param.time.toString();
      const currentData = dataRef.current.slice(0, currentIndexRef.current + 1);
      const originalKLine = currentData.find(k => k.date === timeStr);
      if (originalKLine) {
        onCrosshairMoveRef.current?.(originalKLine);
      }
    });

    const handleResize = () => {
      if (chartContainerRef.current && chartRef.current) {
        chartRef.current.applyOptions({
          width: chartContainerRef.current.clientWidth,
          height: chartContainerRef.current.clientHeight,
        });
      }
    };
    
    const resizeObserver = new ResizeObserver(handleResize);
    resizeObserver.observe(chartContainerRef.current);
    
    return () => {
      resizeObserver.disconnect();
      chart.remove();
      chartRef.current = null;
      seriesRef.current = {};
    };
  }, []);

  // 布局与指标更新逻辑
  useEffect(() => {
    if (!chartRef.current || data.length === 0) return;
    
    const chart = chartRef.current;
    const currentData = data.slice(0, currentIndex + 1);
    
    // 1. 更新 K 线数据
    seriesRef.current.candlestick.setData(convertToChartData(data, currentIndex));
    
    // 1.5 添加买卖标记
    // 按天去重：同一天只显示一个 B 或 S
    const dailyMarkers = new Map<string, { type: 'buy' | 'sell' }>();
    history.forEach(trade => {
      const date = trade.date;
      // 如果同一天既有买又有卖，保留买入标记（或者你可以根据逻辑调整优先级）
      if (!dailyMarkers.has(date) || trade.type === 'buy') {
        dailyMarkers.set(date, { type: trade.type });
      }
    });

    const markers: SeriesMarker<Time>[] = Array.from(dailyMarkers.entries())
      .filter(([date]) => {
        const visibleData = currentData.find(k => k.date === date);
        return visibleData !== undefined;
      })
      .map(([date, trade]) => ({
        time: date as Time,
        position: trade.type === 'buy' ? 'belowBar' as const : 'aboveBar' as const,
        color: trade.type === 'buy' ? '#A855F7' : '#3B82F6', // 紫色/蓝色
        shape: trade.type === 'buy' ? 'arrowUp' as const : 'arrowDown' as const,
        text: trade.type === 'buy' ? '𝗕' : '𝗦', // 数学粗体字符
        size: 1 as const,
      }));
    
    seriesRef.current.candlestick.setMarkers(markers);

    // 2. 清理旧指标 Series
    Object.keys(seriesRef.current).forEach(key => {
      if (key !== 'candlestick') {
        chart.removeSeries(seriesRef.current[key]);
        delete seriesRef.current[key];
      }
    });

    // 3. 计算布局 (Scale Margins)
    const sub1Visible = subIndicator1 !== 'HIDE';
    const sub2Visible = subIndicator2 !== 'HIDE';
    
    // 定义间隙 (2%)
    const GAP = 0.02;
    
    let mainBottom = 0;
    let sub1Top = 0, sub1Bottom = 0;
    let sub2Top = 0;

    if (sub1Visible && sub2Visible) {
      // 两个副图：主图 58%, 副图1 18%, 副图2 18%, 间隙 4%
      mainBottom = 0.40 + GAP; // 0.42
      sub1Top = 0.60 + GAP;    // 0.62
      sub1Bottom = 0.20;       // 0.20
      sub2Top = 0.80 + GAP;    // 0.82
    } else if (sub1Visible || sub2Visible) {
      // 一个副图：主图 73%, 副图 23%, 间隙 2%
      mainBottom = 0.25 + GAP; // 0.27
      sub1Top = 0.75 + GAP;    // 0.77
      sub1Bottom = 0;
      sub2Top = 0.75 + GAP;    // 0.77
    } else {
      mainBottom = 0; // 主图 100%
    }

    // 设置主图布局
    chart.priceScale('right').applyOptions({
      scaleMargins: { top: 0.05, bottom: mainBottom },
    });

    // 4. 绘制主图指标
    if (mainIndicator === 'MA') {
      const ma5 = chart.addLineSeries({ color: '#FFFFFF', lineWidth: 1, priceScaleId: 'right', priceLineVisible: false, lastValueVisible: false });
      const ma10 = chart.addLineSeries({ color: '#E6A23C', lineWidth: 1, priceScaleId: 'right', priceLineVisible: false, lastValueVisible: false });
      const ma20 = chart.addLineSeries({ color: '#D81B60', lineWidth: 1, priceScaleId: 'right', priceLineVisible: false, lastValueVisible: false });
      const ma60 = chart.addLineSeries({ color: '#00E676', lineWidth: 1, priceScaleId: 'right', priceLineVisible: false, lastValueVisible: false });
      const ma120 = chart.addLineSeries({ color: '#2979FF', lineWidth: 1, priceScaleId: 'right', priceLineVisible: false, lastValueVisible: false });
      
      ma5.setData(indicators.calculateMA(currentData, 5).map(d => ({ time: d.time as Time, value: d.value })));
      ma10.setData(indicators.calculateMA(currentData, 10).map(d => ({ time: d.time as Time, value: d.value })));
      ma20.setData(indicators.calculateMA(currentData, 20).map(d => ({ time: d.time as Time, value: d.value })));
      ma60.setData(indicators.calculateMA(currentData, 60).map(d => ({ time: d.time as Time, value: d.value })));
      ma120.setData(indicators.calculateMA(currentData, 120).map(d => ({ time: d.time as Time, value: d.value })));
      
      seriesRef.current.ma5 = ma5;
      seriesRef.current.ma10 = ma10;
      seriesRef.current.ma20 = ma20;
      seriesRef.current.ma60 = ma60;
      seriesRef.current.ma120 = ma120;
    } else if (mainIndicator === 'BOLL') {
      const bollData = indicators.calculateBOLL(currentData);
      const up = chart.addLineSeries({ color: '#E6A23C', lineWidth: 1, priceScaleId: 'right', priceLineVisible: false, lastValueVisible: false });
      const mb = chart.addLineSeries({ color: '#FFFFFF', lineWidth: 1, priceScaleId: 'right', priceLineVisible: false, lastValueVisible: false });
      const dn = chart.addLineSeries({ color: '#D81B60', lineWidth: 1, priceScaleId: 'right', priceLineVisible: false, lastValueVisible: false });
      
      up.setData(bollData.map(d => ({ time: d.time as Time, value: d.up })));
      mb.setData(bollData.map(d => ({ time: d.time as Time, value: d.mb })));
      dn.setData(bollData.map(d => ({ time: d.time as Time, value: d.dn })));
      
      seriesRef.current.boll_up = up;
      seriesRef.current.boll_mb = mb;
      seriesRef.current.boll_dn = dn;
    } else if (mainIndicator === 'ENE') {
      const eneData = indicators.calculateENE(currentData);
      const up = chart.addLineSeries({ color: '#E6A23C', lineWidth: 1, priceScaleId: 'right', priceLineVisible: false, lastValueVisible: false });
      const mb = chart.addLineSeries({ color: '#FFFFFF', lineWidth: 1, priceScaleId: 'right', priceLineVisible: false, lastValueVisible: false });
      const dn = chart.addLineSeries({ color: '#D81B60', lineWidth: 1, priceScaleId: 'right', priceLineVisible: false, lastValueVisible: false });
      
      up.setData(eneData.map(d => ({ time: d.time as Time, value: d.up })));
      mb.setData(eneData.map(d => ({ time: d.time as Time, value: d.mb })));
      dn.setData(eneData.map(d => ({ time: d.time as Time, value: d.dn })));
      
      seriesRef.current.ene_up = up;
      seriesRef.current.ene_mb = mb;
      seriesRef.current.ene_dn = dn;
    }

    // 5. 绘制副图指标函数
    const drawSubIndicator = (type: string, scaleId: string, top: number, bottom: number) => {
      if (type === 'HIDE') return;

      if (type === 'VOL') {
        const volSeries = chart.addHistogramSeries({
          priceFormat: { type: 'volume' },
          priceScaleId: scaleId,
        });
        volSeries.setData(currentData.map(k => ({
          time: k.date as Time,
          value: k.volume,
          color: k.close >= k.open ? '#FD1050' : '#00F0F0', // 使用与 K 线一致的实色
        })));
        seriesRef.current[`${scaleId}_vol`] = volSeries;
      } else if (type === 'MACD') {
        const macdData = indicators.calculateMACD(currentData);
        // 先画柱子，再画线（后画的在上层）
        const macdSeries = chart.addHistogramSeries({ priceScaleId: scaleId });
        const diffSeries = chart.addLineSeries({ color: '#FFFFFF', lineWidth: 1, priceScaleId: scaleId });
        const deaSeries = chart.addLineSeries({ color: '#E6A23C', lineWidth: 1, priceScaleId: scaleId });
        
        macdSeries.setData(macdData.map(d => ({
          time: d.time as Time,
          value: d.macd,
          color: d.macd > 0 ? '#FD1050' : '#00F0F0'
        })));
        diffSeries.setData(macdData.map(d => ({ time: d.time as Time, value: d.diff })));
        deaSeries.setData(macdData.map(d => ({ time: d.time as Time, value: d.dea })));
        
        seriesRef.current[`${scaleId}_macd`] = macdSeries;
        seriesRef.current[`${scaleId}_diff`] = diffSeries;
        seriesRef.current[`${scaleId}_dea`] = deaSeries;
      } else if (type === 'KDJ') {
        const kdjData = indicators.calculateKDJ(currentData);
        const kSeries = chart.addLineSeries({ color: '#FFFFFF', lineWidth: 1, priceScaleId: scaleId });
        const dSeries = chart.addLineSeries({ color: '#E6A23C', lineWidth: 1, priceScaleId: scaleId });
        const jSeries = chart.addLineSeries({ color: '#D81B60', lineWidth: 1, priceScaleId: scaleId });
        
        kSeries.setData(kdjData.map(d => ({ time: d.time as Time, value: d.k })));
        dSeries.setData(kdjData.map(d => ({ time: d.time as Time, value: d.d })));
        jSeries.setData(kdjData.map(d => ({ time: d.time as Time, value: d.j })));
        
        seriesRef.current[`${scaleId}_k`] = kSeries;
        seriesRef.current[`${scaleId}_d`] = dSeries;
        seriesRef.current[`${scaleId}_j`] = jSeries;
      } else if (type === 'RSI') {
        const rsiData = indicators.calculateRSI(currentData);
        const rsiSeries = chart.addLineSeries({ color: '#FFFFFF', lineWidth: 1, priceScaleId: scaleId });
        rsiSeries.setData(rsiData.map(d => ({ time: d.time as Time, value: d.value })));
        seriesRef.current[`${scaleId}_rsi`] = rsiSeries;
      } else if (type === 'WR') {
        const wrData = indicators.calculateWR(currentData);
        const wrSeries = chart.addLineSeries({ color: '#FFFFFF', lineWidth: 1, priceScaleId: scaleId });
        wrSeries.setData(wrData.map(d => ({ time: d.time as Time, value: d.value })));
        seriesRef.current[`${scaleId}_wr`] = wrSeries;
      } else if (type === 'CCI') {
        const cciData = indicators.calculateCCI(currentData);
        const cciSeries = chart.addLineSeries({ color: '#FFFFFF', lineWidth: 1, priceScaleId: scaleId });
        cciSeries.setData(cciData.map(d => ({ time: d.time as Time, value: d.value })));
        seriesRef.current[`${scaleId}_cci`] = cciSeries;
      }

      // 关键修正：先创建 Series，再配置 PriceScale
      chart.priceScale(scaleId).applyOptions({
        scaleMargins: { top, bottom },
        visible: true,
      });
    };

    // 绘制副图
    if (sub1Visible) {
      drawSubIndicator(subIndicator1, 'sub1', sub1Top, sub1Bottom);
    }
    if (sub2Visible) {
      drawSubIndicator(subIndicator2, 'sub2', sub2Top, 0);
    }

    // 判断是否需要滚动到起始位置
    // 情况1: 数据从空变为有数据（游戏开始）
    // 情况2: initialIndex 发生变化（游戏重开）
    // 情况3: 数据长度变小（游戏重置）
    const isNewData = prevDataLengthRef.current === 0 && currentData.length > 0;
    const isInitialIndexChanged = prevInitialIndexRef.current !== initialIndex;
    const isReset = prevDataLengthRef.current > currentData.length;
    const shouldScrollToStart = isNewData || isInitialIndexChanged || isReset;
    
    prevDataLengthRef.current = currentData.length;
    prevInitialIndexRef.current = initialIndex;
    
    if (shouldScrollToStart && currentData.length > 0) {
      // 延迟执行滚动，确保图表已完全渲染
      setTimeout(() => {
        if (chartRef.current) {
          const timeScale = chartRef.current.timeScale();
          // 使用 setVisibleLogicalRange 确保逻辑索引生效
          // from: 0 (第一根K线)
          // to: 120 (屏幕宽度对应120根K线，如果数据不足则右侧留白)
          timeScale.setVisibleLogicalRange({
            from: 0,
            to: 120
          });
        }
      }, 100);
    }

  }, [data, currentIndex, mainIndicator, subIndicator1, subIndicator2, convertToChartData, initialIndex, history]);

  // 渲染图例
  const renderLegend = () => {
    // 1. 确定要显示的数据源
    let displayValues: any = {};
    
    if (legendData) {
      // 有光标：使用光标数据
      displayValues = legendData;
    } else {
      // 无光标：计算最新数据的指标值
      // 注意：这里每次渲染都计算可能会有性能损耗，但在数据量不大(500)时可接受
      // 理想情况下应该在 useEffect 中计算并存入 state，但为了逻辑简单先这样做
      const currentData = data.slice(0, currentIndex + 1);
      const lastIndex = currentData.length - 1;
      
      if (lastIndex >= 0) {
        if (mainIndicator === 'MA') {
          const ma5 = indicators.calculateMA(currentData, 5)[lastIndex]?.value;
          const ma10 = indicators.calculateMA(currentData, 10)[lastIndex]?.value;
          const ma20 = indicators.calculateMA(currentData, 20)[lastIndex]?.value;
          const ma60 = indicators.calculateMA(currentData, 60)[lastIndex]?.value;
          const ma120 = indicators.calculateMA(currentData, 120)[lastIndex]?.value;
          displayValues = { ma5, ma10, ma20, ma60, ma120 };
        } else if (mainIndicator === 'BOLL') {
          const boll = indicators.calculateBOLL(currentData)[lastIndex];
          displayValues = { boll_up: boll?.up, boll_mb: boll?.mb, boll_dn: boll?.dn };
        } else if (mainIndicator === 'ENE') {
          const ene = indicators.calculateENE(currentData)[lastIndex];
          displayValues = { ene_up: ene?.up, ene_mb: ene?.mb, ene_dn: ene?.dn };
        }
        
        // 副图指标计算 (可选，如果需要副图也常显示)
        // 这里暂时只处理主图，因为副图数据在 StockHeader 中没有显示，
        // 如果用户需要看副图数值，通常会移动光标。
        // 如果需要副图常显，可以继续添加逻辑。
      }
    }
    
    const formatVal = (v: any) => {
      if (typeof v === 'number' && !isNaN(v)) return v.toFixed(2);
      return '--';
    };

    return (
      <div className="absolute top-2 left-2 flex flex-col gap-1 text-[10px] lg:text-xs font-mono select-none pointer-events-none z-10 bg-transparent p-1 rounded max-w-[calc(100%-20px)]">
        {/* 主图指标 - 只显示当前选中的，支持自动换行 */}
        <div className="flex flex-wrap gap-x-2 gap-y-0.5">
          {mainIndicator === 'MA' && (
            <>
              <span className="text-white whitespace-nowrap">MA5:{formatVal(displayValues.ma5)}</span>
              <span className="text-[#E6A23C] whitespace-nowrap">MA10:{formatVal(displayValues.ma10)}</span>
              <span className="text-[#D81B60] whitespace-nowrap">MA20:{formatVal(displayValues.ma20)}</span>
              <span className="text-[#00E676] whitespace-nowrap">MA60:{formatVal(displayValues.ma60)}</span>
              <span className="text-[#2979FF] whitespace-nowrap">MA120:{formatVal(displayValues.ma120)}</span>
            </>
          )}
          
          {mainIndicator === 'BOLL' && (
            <>
              <span className="text-[#E6A23C] whitespace-nowrap">UP:{formatVal(displayValues.boll_up)}</span>
              <span className="text-white whitespace-nowrap">MB:{formatVal(displayValues.boll_mb)}</span>
              <span className="text-[#D81B60] whitespace-nowrap">DN:{formatVal(displayValues.boll_dn)}</span>
            </>
          )}

          {mainIndicator === 'ENE' && (
            <>
              <span className="text-[#E6A23C] whitespace-nowrap">UP:{formatVal(displayValues.ene_up)}</span>
              <span className="text-white whitespace-nowrap">MB:{formatVal(displayValues.ene_mb)}</span>
              <span className="text-[#D81B60] whitespace-nowrap">DN:{formatVal(displayValues.ene_dn)}</span>
            </>
          )}
        </div>
      </div>
    );
  };

  // 渲染分隔线
  const renderSeparators = () => {
    const sub1Visible = subIndicator1 !== 'HIDE';
    const sub2Visible = subIndicator2 !== 'HIDE';
    
    if (!sub1Visible && !sub2Visible) return null;

    let sep1Top = '0%';
    let sep2Top = '0%';
    
    if (sub1Visible && sub2Visible) {
      sep1Top = '60%'; // 主图与副图1的分隔
      sep2Top = '80%'; // 副图1与副图2的分隔
    } else {
      sep1Top = '75%'; // 主图与副图的分隔
    }

    return (
      <>
        {/* 主图与副图的分隔线 (明显区分) */}
        <div 
          className="absolute left-0 right-0 h-[2px] bg-[#2A2D3C] z-20 pointer-events-none"
          style={{ top: sep1Top }}
        />
        
        {/* 副图1与副图2的分隔线 (轻微区分) */}
        {sub1Visible && sub2Visible && (
          <div 
            className="absolute left-0 right-0 h-[1px] bg-[#1F2937] z-20 pointer-events-none border-t border-dashed border-gray-700"
            style={{ top: sep2Top }}
          />
        )}
      </>
    );
  };

  return (
    <div className={`relative w-full h-full ${className}`}>
      <div ref={chartContainerRef} className="w-full h-full" />
      {renderSeparators()}
      {renderLegend()}
    </div>
  );
}

