import { useCallback, useMemo, useState } from 'react';
import { Legend, FloatingTooltip } from './native';
import { resolveColorToken } from '../utils/token-resolver.js';
import {
  normalizeDataColorToken,
  getDefaultDataColorToken,
} from './chart-common';
import ChartTooltip from './ChartTooltip';

export { CHART_DATA_COLOR_SLOTS } from './chart-common';

const FALLBACK_DATA_COLOR = '#98A2B3';
const FALLBACK_RADAR_AXIS_TONE = '#98A2B3';
const RADAR_LAYOUT_PADDING_PX = 20;
const RADAR_LEGEND_GAP_PX = 20;
const RADAR_CHART_MARGIN_PX = 16;
/** 当雷达图可用半径小于该阈值时，自动隐藏角度轴文字标签，避免与图形重叠；hover 由 tooltip 展示具体指标 */
const RADAR_HIDE_LABEL_RADIUS_PX = 70;

const DEFAULT_DATA_8 = [
  { name: '维度一', series_0: 54, series_1: 64 },
  { name: '维度二', series_0: 58, series_1: 38 },
  { name: '维度三', series_0: 22, series_1: 24 },
  { name: '维度四', series_0: 62, series_1: 52 },
  { name: '维度五', series_0: 28, series_1: 78 },
  { name: '维度六', series_0: 66, series_1: 34 },
  { name: '维度七', series_0: 42, series_1: 56 },
  { name: '维度八', series_0: 34, series_1: 18 },
];

const GRID_STROKE = 'var(--color-border-divider, #E5E6EB)';

function formatRadarValue(value) {
  const n = Number(value);
  if (!Number.isFinite(n)) return '—';
  return n.toLocaleString('en-US');
}

function mergeConfig(config) {
  const defaults = {
    height: 340,
    maxValue: 80,
    tickCount: 5,
    showLegend: true,
    showGrid: true,
    showAxis: true,
    legendPosition: 'top',
    margin: {
      top: RADAR_CHART_MARGIN_PX,
      right: RADAR_CHART_MARGIN_PX,
      bottom: RADAR_CHART_MARGIN_PX,
      left: RADAR_CHART_MARGIN_PX,
    },
    resolveRoot: undefined,
  };
  if (!config || typeof config !== 'object') return defaults;
  return {
    ...defaults,
    ...config,
    showLegend: config.showLegend !== false,
    showGrid: config.showGrid !== false,
    showAxis: config.showAxis !== false,
    tickCount: Number(config.tickCount) > 1 ? Number(config.tickCount) : defaults.tickCount,
    maxValue: Number(config.maxValue) > 0 ? Number(config.maxValue) : defaults.maxValue,
    height: Number(config.height) > 0 ? Number(config.height) : defaults.height,
    margin: { ...defaults.margin, ...(config.margin || {}) },
    legendPosition: ['top', 'bottom'].includes(config.legendPosition)
      ? config.legendPosition
      : defaults.legendPosition,
  };
}

/**
 * SmartRadarChart（native 实现）
 *
 * 全特性：
 * - 多系列雷达（描边 + 半透明填充）
 * - 多边形 PolarGrid（按 tickCount 同心多边形 + 径向辐条）
 * - 角度轴名（PolarAngleAxis）
 * - 半径轴刻度数字（PolarRadiusAxis，竖直方向）
 * - 顶点点位 hover 高亮 dot
 * - 跟手 tooltip（聚合所有系列，最近顶点）
 * - Legend 四向布局（top/bottom/left/right）
 */
export default function SmartRadarChart({ spec }) {
  const config = mergeConfig(spec?.config);
  const resolveOpts = useMemo(
    () => (config.resolveRoot ? { root: config.resolveRoot } : {}),
    [config.resolveRoot],
  );
  const radarAxisTone = useMemo(
    () => resolveColorToken('text-disabled', resolveOpts) || FALLBACK_RADAR_AXIS_TONE,
    [resolveOpts],
  );

  const data = useMemo(
    () => (Array.isArray(spec?.data) && spec.data.length > 0 ? spec.data : DEFAULT_DATA_8),
    [spec?.data],
  );

  const series = useMemo(() => {
    const raw = Array.isArray(spec?.series) && spec.series.length > 0
      ? spec.series
      : [
          { dataKey: 'series_0', name: '数据指标', colorToken: 'data-1' },
          { dataKey: 'series_1', name: '数据指标', colorToken: 'data-7' },
        ];
    return raw.map((item, index) => {
      const token = normalizeDataColorToken(item?.colorToken || getDefaultDataColorToken(index));
      const color = resolveColorToken(token, resolveOpts) || FALLBACK_DATA_COLOR;
      return {
        dataKey: item?.dataKey || `series_${index}`,
        name: item?.name || `数据指标 ${index + 1}`,
        color,
      };
    });
  }, [spec?.series, resolveOpts]);

  const radiusTicks = useMemo(() => {
    const slots = Math.max(2, Math.floor(config.tickCount));
    const step = config.maxValue / (slots - 1);
    return Array.from({ length: slots }, (_, idx) => Math.round(step * idx));
  }, [config.tickCount, config.maxValue]);

  const legendPosition = config.legendPosition;
  const showLegend = config.showLegend;

  const legendLayoutStyle = showLegend
    ? {
        width: '100%',
        height: '100%',
        display: 'grid',
        boxSizing: 'border-box',
        padding: RADAR_LAYOUT_PADDING_PX,
        rowGap: legendPosition === 'top' || legendPosition === 'bottom' ? RADAR_LEGEND_GAP_PX : 0,
        columnGap: legendPosition === 'left' || legendPosition === 'right' ? RADAR_LEGEND_GAP_PX : 0,
        ...(legendPosition === 'top'
          ? { gridTemplateRows: 'auto 1fr', gridTemplateColumns: '1fr' }
          : legendPosition === 'bottom'
            ? { gridTemplateRows: '1fr auto', gridTemplateColumns: '1fr' }
            : legendPosition === 'left'
              ? { gridTemplateRows: '1fr', gridTemplateColumns: 'auto 1fr' }
              : { gridTemplateRows: '1fr', gridTemplateColumns: '1fr auto' }),
      }
    : { width: '100%', height: '100%' };

  const chartHostStyle = showLegend
    ? legendPosition === 'top'
      ? { gridArea: '2 / 1 / 3 / 2', minWidth: 0, minHeight: 0 }
      : legendPosition === 'bottom'
        ? { gridArea: '1 / 1 / 2 / 2', minWidth: 0, minHeight: 0 }
        : legendPosition === 'left'
          ? { gridArea: '1 / 2 / 2 / 3', minWidth: 0, minHeight: 0 }
          : { gridArea: '1 / 1 / 2 / 2', minWidth: 0, minHeight: 0 }
    : { width: '100%', height: '100%' };

  return (
    <div
      className="smart-radar-chart"
      style={{
        width: '100%',
        height: config.height,
        outline: 'none',
        background: 'var(--color-surface, #FFFFFF)',
      }}
    >
      <div style={legendLayoutStyle}>
        {showLegend && legendPosition === 'top' ? (
          <div style={{ gridArea: '1 / 1 / 2 / 2', alignSelf: 'center', justifySelf: 'center' }}>
            <Legend items={series.map((s) => ({ name: s.name, color: s.color }))} shape="dot" position="top" />
          </div>
        ) : null}
        {showLegend && legendPosition === 'bottom' ? (
          <div style={{ gridArea: '2 / 1 / 3 / 2', alignSelf: 'center', justifySelf: 'center' }}>
            <Legend items={series.map((s) => ({ name: s.name, color: s.color }))} shape="dot" position="bottom" />
          </div>
        ) : null}
        {showLegend && legendPosition === 'left' ? (
          <div style={{ gridArea: '1 / 1 / 2 / 2', alignSelf: 'center', justifySelf: 'start' }}>
            <Legend items={series.map((s) => ({ name: s.name, color: s.color }))} shape="dot" position="left" />
          </div>
        ) : null}
        {showLegend && legendPosition === 'right' ? (
          <div style={{ gridArea: '1 / 2 / 2 / 3', alignSelf: 'center', justifySelf: 'end' }}>
            <Legend items={series.map((s) => ({ name: s.name, color: s.color }))} shape="dot" position="right" />
          </div>
        ) : null}

        <div style={chartHostStyle}>
          <RadarSvg
            data={data}
            series={series}
            margin={config.margin}
            maxValue={config.maxValue}
            radiusTicks={radiusTicks}
            showGrid={config.showGrid}
            showAxis={config.showAxis}
            axisColor={radarAxisTone}
          />
        </div>
      </div>
    </div>
  );
}

/**
 * SVG 雷达图主体：自适应容器尺寸
 */
function RadarSvg({ data, series, margin, maxValue, radiusTicks, showGrid, showAxis, axisColor }) {
  const [size, setSize] = useState({ w: 0, h: 0 });
  const containerRef = useCallback((node) => {
    if (!node) return;
    const ro = new ResizeObserver((entries) => {
      for (const e of entries) {
        const r = e.contentRect;
        setSize({ w: Math.floor(r.width), h: Math.floor(r.height) });
      }
    });
    ro.observe(node);
    const r = node.getBoundingClientRect();
    setSize({ w: Math.floor(r.width), h: Math.floor(r.height) });
  }, []);

  const [activeIdx, setActiveIdx] = useState(null);
  const [mouse, setMouse] = useState(null);

  // 几何
  // 当容器较小时收紧轴名留白，并切换为「紧凑模式」隐藏文字标签，避免与图形重叠
  const baseSizeMin = Math.min(
    Math.max(0, size.w - margin.left - margin.right),
    Math.max(0, size.h - margin.top - margin.bottom),
  );
  const compact = baseSizeMin > 0 && baseSizeMin / 2 < RADAR_HIDE_LABEL_RADIUS_PX;
  const pad = compact ? 4 : 28; // 给轴名留白
  const innerW = Math.max(0, size.w - margin.left - margin.right - pad * 2);
  const innerH = Math.max(0, size.h - margin.top - margin.bottom - pad * 2);
  const cx = margin.left + pad + innerW / 2;
  const cy = margin.top + pad + innerH / 2;
  const r = Math.max(0, Math.min(innerW, innerH) / 2);
  const showAxisLabels = showAxis && !compact;

  const N = data.length;
  // 顶点角度：12 点为 0，顺时针
  const angleAt = (i) => -Math.PI / 2 + (Math.PI * 2 * i) / N;
  const ptAt = (i, radius) => ({
    x: cx + radius * Math.cos(angleAt(i)),
    y: cy + radius * Math.sin(angleAt(i)),
  });

  /** 把数值转换为 polygon path */
  const buildPolygon = (values) => {
    if (N === 0) return '';
    const pts = values.map((v, i) => {
      const t = Math.max(0, Math.min(1, v / maxValue));
      const p = ptAt(i, r * t);
      return `${p.x},${p.y}`;
    });
    return `M${pts.join(' L')} Z`;
  };

  const handleMove = useCallback(
    (e) => {
      const rect = e.currentTarget.getBoundingClientRect();
      const px = e.clientX - rect.left;
      const py = e.clientY - rect.top;
      // 反查最近顶点 index
      const dx = px - cx;
      const dy = py - cy;
      // 距离中心太近时不激活
      const dist = Math.hypot(dx, dy);
      if (dist < 6 || N === 0) {
        setActiveIdx(null);
        setMouse({ x: px, y: py, clientX: e.clientX, clientY: e.clientY, containerW: rect.width });
        return;
      }
      // angle of mouse from +x axis
      let ang = Math.atan2(dy, dx); // -π..π
      // 将 angleAt(i) 列出与 ang 比对，取最小角差
      let best = 0;
      let bestDiff = Infinity;
      for (let i = 0; i < N; i++) {
        const a = angleAt(i);
        let d = Math.abs(((ang - a + Math.PI * 3) % (Math.PI * 2)) - Math.PI);
        if (d < bestDiff) {
          bestDiff = d;
          best = i;
        }
      }
      setActiveIdx(best);
      setMouse({ x: px, y: py, clientX: e.clientX, clientY: e.clientY, containerW: rect.width });
    },
    [cx, cy, N],
  );

  const handleLeave = useCallback(() => {
    setActiveIdx(null);
    setMouse(null);
  }, []);

  const activeRow = activeIdx != null ? data[activeIdx] : null;

  return (
    <div ref={containerRef} style={{ position: 'relative', width: '100%', height: '100%' }}>
      {size.w > 0 && size.h > 0 && (
        <svg
          width={size.w}
          height={size.h}
          style={{ display: 'block', overflow: 'visible' }}
          onMouseMove={handleMove}
          onMouseLeave={handleLeave}
        >
          {/* 多边形网格 */}
          {showGrid && N >= 3 && radiusTicks.map((tickV, ringIdx) => {
            const t = maxValue > 0 ? tickV / maxValue : 0;
            const points = Array.from({ length: N }, (_, i) => {
              const p = ptAt(i, r * t);
              return `${p.x},${p.y}`;
            }).join(' ');
            return (
              <polygon
                key={`grid-ring-${ringIdx}`}
                points={points}
                fill="none"
                stroke={GRID_STROKE}
                strokeWidth={1}
                strokeDasharray="3 3"
              />
            );
          })}

          {/* 径向辐条 */}
          {showGrid && showAxis && Array.from({ length: N }).map((_, i) => {
            const p = ptAt(i, r);
            return (
              <line
                key={`spoke-${i}`}
                x1={cx}
                y1={cy}
                x2={p.x}
                y2={p.y}
                stroke={GRID_STROKE}
                strokeWidth={1}
                strokeDasharray="3 3"
              />
            );
          })}

          {/* 多系列 area + line */}
          {series.map((s) => {
            const values = data.map((d) => Number(d[s.dataKey]) || 0);
            const d = buildPolygon(values);
            if (!d) return null;
            return (
              <g key={`s-${s.dataKey}`}>
                <path d={d} fill={s.color} fillOpacity={0.16} stroke="none" />
                <path d={d} fill="none" stroke={s.color} strokeWidth={2} strokeLinejoin="round" />
                {/* hover 顶点 */}
                {activeIdx != null && (() => {
                  const v = Number(data[activeIdx]?.[s.dataKey]) || 0;
                  const t = Math.max(0, Math.min(1, v / maxValue));
                  const p = ptAt(activeIdx, r * t);
                  return (
                    <circle
                      cx={p.x}
                      cy={p.y}
                      r={5}
                      fill={s.color}
                      stroke="var(--color-surface, #FFFFFF)"
                      strokeWidth={2}
                    />
                  );
                })()}
              </g>
            );
          })}

          {/* 角度轴名 */}
          {showAxisLabels && data.map((d, i) => {
            const p = ptAt(i, r + 14);
            const a = angleAt(i);
            const cosA = Math.cos(a);
            const anchor = Math.abs(cosA) < 0.2 ? 'middle' : cosA > 0 ? 'start' : 'end';
            return (
              <text
                key={`name-${i}`}
                x={p.x}
                y={p.y}
                textAnchor={anchor}
                dominantBaseline="middle"
                fill={axisColor}
                fontSize={12}
              >
                {String(d.name)}
              </text>
            );
          })}

          {/* 半径轴刻度（垂直方向、上侧） */}
          {showAxisLabels && radiusTicks.map((tickV, idx) => {
            if (idx === 0) return null;
            const t = maxValue > 0 ? tickV / maxValue : 0;
            const p = ptAt(0, r * t); // i=0 即正上方
            return (
              <text
                key={`rtick-${idx}`}
                x={p.x + 4}
                y={p.y + 4}
                fill={axisColor}
                fontSize={12}
              >
                {String(tickV)}
              </text>
            );
          })}
        </svg>
      )}

      {/* Tooltip 跟手 */}
      {activeIdx != null && activeRow && mouse && (
        <FloatingTooltip mouse={{ clientX: mouse.clientX, clientY: mouse.clientY }}>
          <ChartTooltip
            variant="chart"
            label={String(activeRow.name)}
            rows={series.map((s) => ({
              name: s.name,
              value: formatRadarValue(activeRow[s.dataKey]),
              color: s.color,
              dataKey: s.dataKey,
            }))}
          />
        </FloatingTooltip>
      )}
    </div>
  );
}
