/**
 * SmartScatterChart — 散点图（native 实现）
 *
 * 与折/柱不同：数据是离散 (x, y) 数值对，不走类目轴，无网格线。
 * 内部全 SVG：
 *  - 双数值轴（带箭头 marker）
 *  - 双均线（虚线 + 文字「均线」）
 *  - 4 个轴端 / 象限文字
 *  - 每个点自带 hover：放大 + 浅色光晕
 *  - hover 时弹出 ChartTooltip 跟随该点
 */
import { useId, useMemo, useState } from 'react';
import { ChartRoot, linearScale, 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_FILL = '#98A2B3';
const DOT_R = 5;

const ANNOTATION_COLOR = 'var(--color-foreground-secondary, #475467)';
const AXIS_BASELINE = 'var(--color-border-chart-axis, #98A2B3)';
const GUIDE_STROKE = 'var(--color-border-chart-grid, #E4E7EC)';

function hexToRgba(hex, a) {
  if (!hex?.startsWith('#')) return null;
  let h = hex.slice(1);
  if (h.length === 8) h = h.slice(0, 6);
  if (h.length === 3) h = h.split('').map((c) => c + c).join('');
  if (h.length !== 6) return null;
  const r = parseInt(h.slice(0, 2), 16);
  const g = parseInt(h.slice(2, 4), 16);
  const b = parseInt(h.slice(4, 6), 16);
  return `rgba(${r},${g},${b},${a})`;
}
function seriesFillFromColor(solidHex, alpha = 0.22) {
  return hexToRgba(solidHex, alpha) ?? solidHex;
}

const DEMO_A = [
  { x: 16, y: 74 }, { x: 24, y: 32 }, { x: 36, y: 56 },
  { x: 44, y: 26 }, { x: 52, y: 70 }, { x: 61, y: 40 },
  { x: 69, y: 82 }, { x: 78, y: 60 }, { x: 86, y: 52 },
  { x: 29, y: 68 }, { x: 41, y: 44 }, { x: 57, y: 22 },
  { x: 73, y: 32 }, { x: 84, y: 78 }, { x: 33, y: 24 },
  { x: 47, y: 62 }, { x: 63, y: 50 }, { x: 76, y: 28 },
  { x: 21, y: 46 }, { x: 88, y: 70 },
];
const DEMO_B = DEMO_A.map((p, idx) => ({
  x: Math.max(6, Math.min(94, 100 - p.x + ((idx % 3) - 1) * 4)),
  y: Math.max(6, Math.min(94, p.y + (idx % 2 === 0 ? 7 : -8))),
}));

function mergeConfig(c) {
  const d = {
    height: 340,
    showLegend: true,
    legendPosition: 'bottom',
    showXAxis: true,
    showYAxis: true,
    xMean: 'auto',
    yMean: 'auto',
    margin: { top: 20, right: 20, bottom: 10, left: 20 },
    resolveRoot: undefined,
  };
  if (!c || typeof c !== 'object') return d;
  const legendPosition = ['top', 'bottom'].includes(c.legendPosition)
    ? c.legendPosition
    : d.legendPosition;
  return {
    ...d,
    ...c,
    legendPosition,
    margin: { ...d.margin, ...(c.margin || {}) },
    height: Number(c.height) || d.height,
  };
}

function autoMean() {
  // 默认固定居中，保持四象限语义稳定
  return 50;
}

function formatScatterMetricValue(value) {
  if (value == null) return '—';
  if (typeof value === 'number' && Number.isFinite(value)) {
    return value.toLocaleString('en-US');
  }
  return String(value);
}

export default function SmartScatterChart({ spec }) {
  const { data: rawData, series: rawSeries, config: rawConfig } = spec || {};
  const config = mergeConfig(rawConfig);
  const {
    height,
    showLegend,
    legendPosition,
    showXAxis,
    showYAxis,
    margin: marginCfg,
    resolveRoot,
  } = config;

  const resolveOpts = useMemo(() => (resolveRoot ? { root: resolveRoot } : {}), [resolveRoot]);
  const markerId = useId().replace(/:/g, '');
  const [hovered, setHovered] = useState(null); // { si, pi }

  const series = useMemo(() => {
    let raw;
    if (Array.isArray(rawSeries) && rawSeries.length > 0) raw = rawSeries;
    else if (Array.isArray(rawData) && rawData.length > 0) raw = [{ name: '数据指标', colorToken: 'data-0', data: rawData }];
    else raw = [
      { name: '数据指标 1', colorToken: 'data-0', data: DEMO_A },
      { name: '数据指标 2', colorToken: 'data-4', data: DEMO_B },
    ];
    return raw.map((s, idx) => {
      const tok = normalizeDataColorToken(s.colorToken || getDefaultDataColorToken(idx));
      const solid = resolveColorToken(tok, resolveOpts) || FALLBACK_FILL;
      return {
        name: s.name ?? `系列 ${idx + 1}`,
        data: Array.isArray(s.data) ? s.data : [],
        color: solid,
        fill: seriesFillFromColor(solid, 0.22),
        stroke: solid,
      };
    });
  }, [rawSeries, rawData, resolveOpts]);

  const xMean = useMemo(
    () => (config.xMean !== 'auto' ? Number(config.xMean) || 50 : autoMean()),
    [config.xMean],
  );
  const yMean = useMemo(
    () => (config.yMean !== 'auto' ? Number(config.yMean) || 50 : autoMean()),
    [config.yMean],
  );

  // ── margin（含 legend 占位）
  const showLegendBar = showLegend && series.length > 0;
  const margin = useMemo(() => {
    const m = {
      top: Math.max(Number(marginCfg?.top) || 0, 20),
      right: Math.max(Number(marginCfg?.right) || 0, 20),
      bottom: Math.max(Number(marginCfg?.bottom) || 0, 10),
      left: Math.max(Number(marginCfg?.left) || 0, 20),
    };
    if (showLegendBar) {
      if (legendPosition === 'top') m.top += 28;
      else if (legendPosition === 'bottom') m.bottom += 28;
      else if (legendPosition === 'left') m.left += 96;
      else if (legendPosition === 'right') m.right += 96;
    }
    return m;
  }, [marginCfg, showLegendBar, legendPosition]);

  return (
    <div
      className="smart-scatter-chart"
      style={{
        position: 'relative',
        width: '100%',
        height,
        outline: 'none',
        overflow: 'visible',
        background: 'var(--color-surface, #FFFFFF)',
      }}
      tabIndex={-1}
    >
      <ChartRoot height={height} margin={margin}>
        {({ width, plot }) => {
          const xScale = linearScale([0, 100], [plot.x, plot.x + plot.w]);
          const yScale = linearScale([0, 100], [plot.y + plot.h, plot.y]);
          const xPx = xScale(xMean);
          const yPx = yScale(yMean);

          const hoveredSeries = hovered ? series[hovered.si] : null;
          const hoveredPoint = hoveredSeries?.data?.[hovered?.pi];

          return (
            <>
              <svg width={width} height={height} style={{ display: 'block', overflow: 'visible' }}>
                <defs>
                  <marker
                    id={markerId}
                    viewBox="0 0 8 8"
                    refX="4"
                    refY="4"
                    markerWidth="8"
                    markerHeight="8"
                    orient="auto-start-reverse"
                  >
                    <path
                      d="M 0 0 L 4 4 L 0 8"
                      fill="none"
                      stroke={AXIS_BASELINE}
                      strokeWidth={1}
                      strokeLinecap="round"
                      strokeLinejoin="round"
                    />
                  </marker>
                </defs>

                {/* 均线（先画，避免压点） */}
                {Number.isFinite(xPx) && (
                  <line
                    x1={xPx}
                    x2={xPx}
                    y1={plot.y}
                    y2={plot.y + plot.h}
                    stroke={GUIDE_STROKE}
                    strokeDasharray="3 3"
                    strokeWidth={1}
                  />
                )}
                {Number.isFinite(yPx) && (
                  <line
                    x1={plot.x}
                    x2={plot.x + plot.w}
                    y1={yPx}
                    y2={yPx}
                    stroke={GUIDE_STROKE}
                    strokeDasharray="3 3"
                    strokeWidth={1}
                  />
                )}

                {/* 双数值轴（带箭头）*/}
                {showXAxis && (
                  <line
                    x1={plot.x}
                    x2={plot.x + plot.w}
                    y1={plot.y + plot.h}
                    y2={plot.y + plot.h}
                    stroke={AXIS_BASELINE}
                    strokeWidth={1}
                    fill="none"
                    markerEnd={`url(#${markerId})`}
                  />
                )}
                {showYAxis && (
                  <line
                    x1={plot.x}
                    x2={plot.x}
                    y1={plot.y + plot.h}
                    y2={plot.y}
                    stroke={AXIS_BASELINE}
                    strokeWidth={1}
                    fill="none"
                    markerEnd={`url(#${markerId})`}
                  />
                )}

                {/* 散点 */}
                {series.map((s, si) => (
                  <g key={`${s.name}-${si}`}>
                    {s.data.map((pt, pi) => {
                      const cx = xScale(Number(pt.x));
                      const cy = yScale(Number(pt.y));
                      if (!Number.isFinite(cx) || !Number.isFinite(cy)) return null;
                      const isActive = hovered?.si === si && hovered?.pi === pi;
                      return (
                        <g
                          key={pi}
                          style={{ cursor: 'pointer' }}
                          onPointerEnter={(e) => setHovered({ si, pi, clientX: e.clientX, clientY: e.clientY })}
                          onPointerMove={(e) => setHovered({ si, pi, clientX: e.clientX, clientY: e.clientY })}
                          onPointerLeave={() => setHovered(null)}
                        >
                          {isActive && (
                            <>
                              <circle cx={cx} cy={cy} r={DOT_R * 2.15} fill={s.color} fillOpacity={0.14} />
                              <circle cx={cx} cy={cy} r={DOT_R + 3.5} fill="rgba(18, 20, 34, 0.07)" />
                            </>
                          )}
                          <circle
                            cx={cx}
                            cy={cy}
                            r={isActive ? DOT_R + 1.25 : DOT_R}
                            fill={isActive ? s.color : s.fill}
                            stroke={s.color}
                            strokeWidth={1}
                          />
                        </g>
                      );
                    })}
                  </g>
                ))}

                {/* 文字注解：先底层象限，再顶层「高 / 均线」 */}
                <g pointerEvents="none" aria-hidden>
                  {/* 象限文案 */}
                  <text
                    x={plot.x + 24}
                    y={plot.y + plot.h - 18}
                    textAnchor="start"
                    style={{ fill: ANNOTATION_COLOR, fontSize: 14, fontWeight: 600, fontFamily: 'inherit' }}
                  >表现较差</text>
                  <text
                    x={plot.x + plot.w - 24}
                    y={plot.y + 24}
                    textAnchor="end"
                    dominantBaseline="hanging"
                    style={{ fill: ANNOTATION_COLOR, fontSize: 14, fontWeight: 600, fontFamily: 'inherit' }}
                  >表现优异</text>

                  {/* Y 轴顶端「高」 */}
                  <text
                    x={plot.x - 8}
                    y={plot.y + 2}
                    textAnchor="end"
                    style={{ fill: ANNOTATION_COLOR, fontSize: 12, fontFamily: 'inherit' }}
                  >高</text>
                  {/* X 轴右端「高」 */}
                  <text
                    x={plot.x + plot.w - 2}
                    y={plot.y + plot.h + 16}
                    textAnchor="end"
                    style={{ fill: ANNOTATION_COLOR, fontSize: 12, fontFamily: 'inherit' }}
                  >高</text>

                  {/* 均线文案 */}
                  {Number.isFinite(xPx) && (
                    <text
                      x={xPx}
                      y={plot.y + 14}
                      textAnchor="middle"
                      style={{ fill: ANNOTATION_COLOR, fontSize: 12, fontFamily: 'inherit' }}
                    >均线</text>
                  )}
                  {Number.isFinite(yPx) && (
                    <text
                      x={plot.x + plot.w - 8}
                      y={yPx}
                      textAnchor="end"
                      dominantBaseline="middle"
                      style={{ fill: ANNOTATION_COLOR, fontSize: 12, fontFamily: 'inherit' }}
                    >均线</text>
                  )}
                </g>
              </svg>

              {/* Legend */}
              {showLegendBar && (
                <div
                  style={{
                    position: 'absolute',
                    left: 0,
                    right: 0,
                    ...(legendPosition === 'top' ? { top: 0 } : {}),
                    ...(legendPosition === 'bottom' ? { bottom: 0 } : {}),
                    ...(legendPosition === 'left' ? { left: 0, top: '50%', transform: 'translateY(-50%)', right: 'auto', width: 96 } : {}),
                    ...(legendPosition === 'right' ? { right: 0, top: '50%', transform: 'translateY(-50%)', left: 'auto', width: 96 } : {}),
                    padding: '4px 8px',
                  }}
                >
                  <Legend
                    items={series.map((s) => ({ name: s.name, color: s.color }))}
                    shape="dot"
                    position={legendPosition}
                  />
                </div>
              )}

              {/* Tooltip 浮层（HTML 层），跟随当前 hover 点 */}
              {hovered && hoveredSeries && hoveredPoint && (
                <FloatingTooltip mouse={{ clientX: hovered.clientX, clientY: hovered.clientY }}>
                  <ChartTooltip
                    variant="chart"
                    label={null}
                    rows={[
                      {
                        name: 'X轴',
                        value: formatScatterMetricValue(hoveredPoint.x),
                        color: hoveredSeries.color,
                        dataKey: 'x',
                      },
                      {
                        name: 'Y轴',
                        value: formatScatterMetricValue(hoveredPoint.y),
                        color: hoveredSeries.color,
                        dataKey: 'y',
                      },
                    ]}
                  />
                </FloatingTooltip>
              )}
            </>
          );
        }}
      </ChartRoot>
    </div>
  );
}
