import React, { useState, useRef, useLayoutEffect, useMemo } from 'react';
import Taro from '@tarojs/taro';
import { Canvas } from '@tarojs/components';
import uChartsClass from '../lib/u-charts-original.js';
import type { ChartsConfig, TouchEvent } from '../lib/u-charts-original';
import type { ExtendedCanvasContext } from '../types';

/**
 * BaseChart 组件的 Props 接口
 * 使用原始 u-charts.js + Canvas 2D API
 */
export interface BaseChartProps {
  /** Canvas 元素的 ID，必须唯一 */
  canvasId: string;
  /** 图表宽度（像素），默认为 750 */
  width?: number;
  /** 图表高度（像素），默认为 500 */
  height?: number;
  /** 图表类型 */
  type: ChartsConfig['type'];
  /** X 轴分类数据 */
  categories?: string[];
  /** 系列数据 */
  series?: ChartsConfig['series'];
  /** 额外的图表配置 */
  config?: Partial<ChartsConfig>;
  /** 触摸开始事件 */
  onTouchStart?: (e: TouchEvent) => void;
  /** 触摸移动事件 */
  onTouchMove?: (e: TouchEvent) => void;
  /** 触摸结束事件 */
  onTouchEnd?: (e: TouchEvent) => void;
}

/**
 * BaseChartInner 内部组件
 *
 * 实际的图表渲染组件，只在数据准备好后才会挂载
 * 使用空依赖数组确保只初始化一次
 */
const BaseChartInner: React.FC<BaseChartProps> = (props) => {
  const {
    canvasId,
    width = 750,
    height = 500,
    type,
    categories = [],
    series = [],
    config = {},
    onTouchStart,
    onTouchMove,
    onTouchEnd,
  } = props;

  const [cWidth, setCWidth] = useState(750);
  const [cHeight, setCHeight] = useState(500);

  const chartRef = useRef<any>(null);

  /**
   * 初始化图表实例
   * 使用 Canvas 2D API + 原始 u-charts.js
   * 参考 ColumnChartFCExample 的实现方式
   *
   * 注意：使用空依赖数组，只在组件首次挂载时执行一次
   * 数据变化通过 Wrapper 组件控制重新挂载来实现
   */
  useLayoutEffect(() => {
    console.debug('[BaseChart] useLayoutEffect 开始', { canvasId, width, height });

    // 计算响应式尺寸
    const sysInfo = Taro.getSystemInfoSync();
    // 这里的第一个 750 对应 css .charts 的 width
    const cw = width / 750 * sysInfo.windowWidth;
    // 这里的 500 对应 css .charts 的 height
    const ch = height / 750 * sysInfo.windowWidth;

    setCWidth(cw);
    setCHeight(ch);

    // 确保数据已准备好
    // 对于饼图（pie/ring），只需要 series 有数据
    // 对于其他图表，需要 categories 和 series 都有数据
    const isPieChart = type === 'pie' || type === 'ring';
    const isDataReady = isPieChart ? series.length > 0 : categories.length > 0 && series.length > 0;

    if (!isDataReady) {
      console.log('[BaseChart] 数据未准备好，等待数据...', {
        canvasId,
        type,
        isPieChart,
        categoriesLength: categories.length,
        seriesLength: series.length
      });
      return;
    }

    // 延迟初始化图表，等待 Canvas 尺寸渲染完成（参考 FC 示例）
    setTimeout(() => {
      // 使用 Canvas 2D API 的方式获取 context
      const query = Taro.createSelectorQuery();
      query.select('#' + canvasId).fields({ node: true, size: true }).exec((res) => {
        if (res[0]) {
          const canvas = res[0].node;
          const ctx = canvas.getContext('2d');

          console.debug('[BaseChartOriginal2D] canvas.width', canvas.width);
          console.debug('[BaseChartOriginal2D] canvas.height', canvas.height);

          // 将 Taro CanvasContext 转换为 uCharts 需要的 CanvasContext
          const extendedCtx = ctx as ExtendedCanvasContext;

          // Canvas 2D: 使用 canvas 的实际 width/height
          // 基础配置
          const chartConfig: ChartsConfig = {
            type,
            context: extendedCtx,
            categories,
            series,
            width: canvas.width,
            height: canvas.height,
            animation: true,
            background: '#FFFFFF',
            color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444'],
            padding: [15, 15, 0, 5],
            enableScroll: false,
            legend: {},
            xAxis: {
              disableGrid: true
            },
            yAxis: {
              data: [{ min: 0 }]
            },
            ...config,
          };

          chartRef.current = new uChartsClass(chartConfig);
          console.log('[BaseChart] 图表初始化完成:', canvasId, {
            cWidth, cHeight,
            canvasWidth: canvas.width,
            canvasHeight: canvas.height,
            categoriesLength: categories.length,
            seriesLength: series.length,
            categories,
            series,
          });
        } else {
          console.error('[BaseChart] 未获取到 canvas node:', canvasId);
        }
      });
    }, 500); // 延迟 500ms，等待 Canvas 尺寸渲染完成
  }, []); // 空依赖数组：只在首次挂载时执行一次

  /**
   * 触摸事件处理
   */
  const handleTouchStart = (e: any) => {
    if (chartRef.current) {
      chartRef.current.touchLegend(e);
      chartRef.current.showToolTip(e);
    }
    onTouchStart?.(e as TouchEvent);
  };

  const handleTouchMove = (e: any) => {
    if (chartRef.current) {
      chartRef.current.scroll(e);
    }
    onTouchMove?.(e as TouchEvent);
  };

  const handleTouchEnd = (e: any) => {
    if (chartRef.current) {
      chartRef.current.touchLegend(e);
      chartRef.current.showToolTip(e);
    }
    onTouchEnd?.(e as TouchEvent);
  };

  const canvasProps = { style: { width: cWidth, height: cHeight } };

  return (
    <Canvas
      canvas-id={canvasId}
      id={canvasId}
      {...canvasProps}
      onTouchStart={handleTouchStart}
      onTouchMove={handleTouchMove}
      onTouchEnd={handleTouchEnd}
      type="2d"
    />
  );
};

/**
 * BaseChart 组件
 *
 * 外层 Wrapper 组件，负责：
 * - 检查数据是否准备好
 * - 缓存 config 引用
 * - 只有数据准备好后才挂载 Inner 组件
 *
 * 使用原始 u-charts.js + Canvas 2D API
 * 参考 docs/小程序图表库示例/taro-2d柱状图使用示例.md
 */
export const BaseChart: React.FC<BaseChartProps> = (props) => {
  const {
    canvasId,
    width,
    height,
    type,
    categories = [],
    series = [],
    config = {},
    onTouchStart,
    onTouchMove,
    onTouchEnd,
  } = props;

  // 缓存配置，避免每次渲染创建新对象
  const stableConfig = useMemo(() => config, [JSON.stringify(config)]);

  // 只有数据准备好才渲染 Inner 组件
  // 对于饼图（pie/ring），只需要 series 有数据
  // 对于其他图表，需要 categories 和 series 都有数据
  const isPieChart = type === 'pie' || type === 'ring';
  const isReady = isPieChart ? series.length > 0 : categories.length > 0 && series.length > 0;

  if (!isReady) {
    return null;
  }

  return (
    <BaseChartInner
      canvasId={canvasId}
      width={width}
      height={height}
      type={type}
      categories={categories}
      series={series}
      config={stableConfig}
      onTouchStart={onTouchStart}
      onTouchMove={onTouchMove}
      onTouchEnd={onTouchEnd}
    />
  );
};

export default BaseChart;
