import { useEffect, useMemo, useState } from "react";
import { EChart } from "@/shared/charts/EChart.jsx";
import { readCssToken } from "@/shared/utils/cssTokens.js";

const numberFormatter = new Intl.NumberFormat("zh-CN");
const defaultColorTokens = ["--chart-blue", "--chart-green", "--chart-orange", "--chart-red", "--info"];

export function MultiSeriesLineChart({ ariaLabel, categories = [], emptyText = "当前无数据", series = [] }) {
    const reducedMotion = usePrefersReducedMotion();
    const normalized = useMemo(() => normalizeSeries(series, categories.length), [categories.length, series]);
    const option = useMemo(
        () => createMultiSeriesLineOption(categories, normalized, reducedMotion),
        [categories, normalized, reducedMotion],
    );

    if (!categories.length || !normalized.length) {
        return (
            <div aria-label={ariaLabel} className="multi-series-line-chart__empty" role="status">
                {emptyText}
            </div>
        );
    }

    return (
        <div aria-label={ariaLabel} className="multi-series-line-chart" role="group">
            <EChart className="multi-series-line-chart__canvas" option={option} />
        </div>
    );
}

export function normalizeSeries(series, categoryCount) {
    return (Array.isArray(series) ? series : [])
        .map((item, index) => ({
            color: readCssToken(item?.colorToken || defaultColorTokens[index % defaultColorTokens.length], "#64748b"),
            data: Array.from({ length: categoryCount }, (_, dataIndex) => {
                const value = Number(item?.data?.[dataIndex]);
                return Number.isFinite(value) ? value : 0;
            }),
            key: String(item?.key || `series-${index}`),
            name: String(item?.name || item?.key || `指标 ${index + 1}`),
            yAxisIndex: Number(item?.yAxisIndex) === 1 ? 1 : 0,
        }))
        .filter((item) => item.data.length > 0);
}

export function createMultiSeriesLineOption(categories, series, reducedMotion = false) {
    const gridColor = readCssToken("--chart-grid", "#e5e7eb");
    const axisColor = readCssToken("--text-tertiary", "#64748b");
    const hasSecondaryAxis = series.some((item) => item.yAxisIndex === 1);
    const yAxes = [createValueAxis(gridColor, axisColor, true)];
    if (hasSecondaryAxis) {
        yAxes.push(createValueAxis(gridColor, axisColor, false));
    }

    return {
        animation: !reducedMotion,
        animationDuration: reducedMotion ? 0 : 450,
        animationDurationUpdate: reducedMotion ? 0 : 300,
        color: series.map((item) => item.color),
        grid: { bottom: 18, containLabel: true, left: 8, right: hasSecondaryAxis ? 16 : 8, top: 44 },
        legend: {
            icon: "roundRect",
            itemHeight: 7,
            itemWidth: 14,
            textStyle: { color: readCssToken("--text-secondary", "#475569"), fontSize: 11 },
            top: 6,
        },
        tooltip: {
            trigger: "axis",
            backgroundColor: readCssToken("--chart-tooltip-bg", "#ffffff"),
            borderColor: readCssToken("--chart-tooltip-border", "#d8e0ec"),
            textStyle: { color: readCssToken("--chart-tooltip-text", "#0f172a") },
            valueFormatter: (value) => numberFormatter.format(Number(value) || 0),
        },
        xAxis: {
            type: "category",
            boundaryGap: false,
            data: categories,
            axisLabel: { color: axisColor, fontSize: 10, hideOverlap: true },
            axisLine: { lineStyle: { color: gridColor } },
            axisTick: { show: false },
        },
        yAxis: yAxes,
        series: series.map((item) => ({
            type: "line",
            name: item.name,
            data: item.data,
            yAxisIndex: item.yAxisIndex,
            smooth: 0.25,
            showSymbol: false,
            symbolSize: 5,
            lineStyle: { color: item.color, width: 2 },
            itemStyle: { color: item.color },
            emphasis: { focus: "series" },
        })),
    };
}

function createValueAxis(gridColor, axisColor, splitLine) {
    return {
        type: "value",
        min: 0,
        axisLabel: {
            color: axisColor,
            fontSize: 10,
            formatter: (value) => compactNumber(Number(value) || 0),
        },
        axisLine: { show: false },
        axisTick: { show: false },
        splitLine: { show: splitLine, lineStyle: { color: gridColor, type: "dashed" } },
    };
}

function compactNumber(value) {
    if (Math.abs(value) >= 100000000) return `${(value / 100000000).toFixed(1)}亿`;
    if (Math.abs(value) >= 10000) return `${(value / 10000).toFixed(1)}万`;
    return numberFormatter.format(value);
}

function usePrefersReducedMotion() {
    const [reducedMotion, setReducedMotion] = useState(() => readReducedMotionPreference());

    useEffect(() => {
        if (typeof window.matchMedia !== "function") return undefined;
        const media = window.matchMedia("(prefers-reduced-motion: reduce)");
        const update = (event) => setReducedMotion(event.matches);
        setReducedMotion(media.matches);
        media.addEventListener?.("change", update);
        return () => media.removeEventListener?.("change", update);
    }, []);

    return reducedMotion;
}

function readReducedMotionPreference() {
    return (
        typeof window !== "undefined" &&
        typeof window.matchMedia === "function" &&
        window.matchMedia("(prefers-reduced-motion: reduce)").matches
    );
}
