import * as echarts from "echarts"

export const chartFontFamily = "AlibabaPuHuiTi, Microsoft YaHei, Arial, sans-serif"
export const chartPalette = ["#24f6c4", "#32dcff", "#ffe06b", "#7ee269", "#ff9a62", "#9ea7ff"]

export const chartTextStyle = {
  color: "rgba(225, 249, 255, 0.78)",
  fontFamily: chartFontFamily,
  fontSize: 10,
}

export function chartTooltip(formatter, overrides = {}) {
  return {
    trigger: "item",
    appendToBody: true,
    confine: false,
    backgroundColor: "rgba(5, 31, 51, 0.96)",
    borderColor: "rgba(0, 210, 255, 0.54)",
    borderWidth: 1,
    padding: [7, 10],
    textStyle: {
      color: "#e7fbff",
      fontFamily: chartFontFamily,
      fontSize: 12,
      lineHeight: 18,
    },
    extraCssText: "box-shadow:0 0 18px rgba(0,210,255,.2);z-index:2147483647!important;pointer-events:none;",
    formatter,
    ...overrides,
  }
}

export function chartLegend(overrides = {}) {
  return {
    itemWidth: 10,
    itemHeight: 7,
    itemGap: 8,
    textStyle: {
      ...chartTextStyle,
      color: "rgba(222, 250, 255, 0.78)",
      fontSize: 10,
    },
    ...overrides,
  }
}

export function categoryAxis(data = [], overrides = {}) {
  return {
    type: "category",
    data,
    axisLabel: {
      ...chartTextStyle,
      color: "rgba(223, 250, 255, 0.68)",
      interval: 0,
      hideOverlap: true,
      margin: 8,
      ...(overrides.axisLabel || {}),
    },
    axisLine: { lineStyle: { color: "rgba(48, 220, 255, 0.26)" }, ...(overrides.axisLine || {}) },
    axisTick: { show: false, ...(overrides.axisTick || {}) },
    splitLine: { show: false, ...(overrides.splitLine || {}) },
    ...stripAxisOverrides(overrides),
  }
}

export function valueAxis(overrides = {}) {
  return {
    type: "value",
    axisLabel: {
      ...chartTextStyle,
      color: "rgba(223, 250, 255, 0.56)",
      ...(overrides.axisLabel || {}),
    },
    axisLine: { show: false, ...(overrides.axisLine || {}) },
    axisTick: { show: false, ...(overrides.axisTick || {}) },
    splitLine: {
      lineStyle: { color: "rgba(48, 220, 255, 0.1)", type: "dashed" },
      ...(overrides.splitLine || {}),
    },
    ...stripAxisOverrides(overrides),
  }
}

export function chartGrid(overrides = {}) {
  return {
    left: 42,
    right: 28,
    top: 30,
    bottom: 24,
    containLabel: false,
    ...overrides,
  }
}

export function verticalGradient(color, endColor = `${color}12`) {
  return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
    { offset: 0, color },
    { offset: 1, color: endColor },
  ])
}

export function horizontalGradient(color, startColor = `${color}20`, endColor = "#ffffff") {
  return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
    { offset: 0, color: startColor },
    { offset: 0.68, color },
    { offset: 1, color: endColor },
  ])
}

export function withChartDefaults(option = {}) {
  const normalized = {
    textStyle: {
      fontFamily: chartFontFamily,
      color: "rgba(225, 249, 255, 0.78)",
      ...(option.textStyle || {}),
    },
    animation: option.animation ?? true,
    animationDuration: option.animationDuration ?? 900,
    animationDurationUpdate: option.animationDurationUpdate ?? 700,
    animationEasing: option.animationEasing || "cubicOut",
    ...option,
  }
  normalizeChartTypography(normalized)
  return normalized
}

export function createSystemBarOption({
  categories = [],
  rows = [],
  unit = "",
  name = "指标",
  orientation = "vertical",
  colorIndex = 0,
  grid = {},
  showLabel = true,
} = {}) {
  const color = chartPalette[colorIndex % chartPalette.length]
  const horizontal = orientation === "horizontal"
  const data = rows.map((item, index) => ({
    name: item.name || categories[index],
    value: Number(item.value) || 0,
    itemStyle: {
      borderRadius: horizontal ? [0, 8, 8, 0] : [8, 8, 0, 0],
      color: horizontal ? horizontalGradient(item.color || color, "rgba(48, 220, 255, 0.14)", item.color || color) : verticalGradient(item.color || color),
    },
  }))

  return withChartDefaults({
    color: chartPalette,
    grid: chartGrid(horizontal ? { left: 72, right: showLabel ? 58 : 26, top: 24, bottom: 22, ...grid } : { left: 46, right: 24, top: 28, bottom: 42, ...grid }),
    tooltip: chartTooltip((params) => `${params.marker}${params.name}：${formatChartValue(params.value)}${unit}`),
    xAxis: horizontal ? valueAxis() : categoryAxis(categories, { axisLabel: { rotate: categories.length > 6 ? 24 : 0 } }),
    yAxis: horizontal ? categoryAxis(categories, { inverse: true, axisLabel: { color: "rgba(225, 249, 255, 0.82)" } }) : valueAxis(),
    series: [
      {
        name,
        type: "bar",
        barWidth: horizontal ? 12 : categories.length > 7 ? 14 : 20,
        data,
        label: {
          show: showLabel,
          position: horizontal ? "right" : "top",
          color: "#f7feff",
          fontSize: 10,
          formatter: ({ value }) => formatChartValue(value),
        },
      },
    ],
  })
}

export function createSystemGroupedBarOption({ categories = [], series = [], unit = "", grid = {} } = {}) {
  return withChartDefaults({
    color: chartPalette,
    grid: chartGrid({ left: 46, right: 20, top: 42, bottom: 42, ...grid }),
    tooltip: chartTooltip((params) => formatAxisTooltip(params, unit), { trigger: "axis", axisPointer: { type: "shadow" } }),
    legend: chartLegend({ top: 0, right: 4 }),
    xAxis: categoryAxis(categories),
    yAxis: valueAxis(),
    series: series.map((item, index) => ({
      name: item.name,
      type: "bar",
      barWidth: 10,
      data: item.values || [],
      itemStyle: {
        borderRadius: [6, 6, 0, 0],
        color: verticalGradient(chartPalette[index % chartPalette.length]),
      },
    })),
  })
}

export function createSystemStackedBarOption({ categories = [], series = [], unit = "", grid = {} } = {}) {
  return withChartDefaults({
    color: chartPalette,
    grid: chartGrid({ left: 48, right: 22, top: 42, bottom: 42, ...grid }),
    tooltip: chartTooltip((params) => formatAxisTooltip(params, unit), { trigger: "axis", axisPointer: { type: "shadow" } }),
    legend: chartLegend({ top: 0, right: 4 }),
    xAxis: categoryAxis(categories),
    yAxis: valueAxis(),
    series: series.map((item, index) => ({
      name: item.name,
      type: "bar",
      stack: "total",
      barWidth: 18,
      data: item.values || [],
      itemStyle: {
        color: verticalGradient(chartPalette[index % chartPalette.length]),
      },
    })),
  })
}

export function createSystemLineOption({ categories = [], series = [], unit = "", area = false, grid = {} } = {}) {
  return withChartDefaults({
    color: chartPalette,
    grid: chartGrid({ left: 46, right: 24, top: 42, bottom: 38, ...grid }),
    tooltip: chartTooltip((params) => formatAxisTooltip(params, unit), {
      trigger: "axis",
      axisPointer: {
        type: "line",
        lineStyle: { color: "rgba(255, 224, 107, 0.54)" },
      },
    }),
    legend: chartLegend({ top: 0, right: 4 }),
    xAxis: categoryAxis(categories),
    yAxis: valueAxis(),
    series: series.map((item, index) => {
      const color = item.color || chartPalette[index % chartPalette.length]
      return {
        name: item.name,
        type: "line",
        smooth: true,
        symbol: "circle",
        symbolSize: 7,
        data: item.values || [],
        lineStyle: {
          width: 3,
          color,
          shadowColor: `${color}55`,
          shadowBlur: 10,
        },
        itemStyle: {
          color: "#041522",
          borderColor: color,
          borderWidth: 2,
        },
        areaStyle: area
          ? {
              color: verticalGradient(color, `${color}08`),
            }
          : undefined,
      }
    }),
  })
}

export function createSystemPieOption({ rows = [], unit = "", name = "结构占比", rose = false, donut = true } = {}) {
  return withChartDefaults({
    color: chartPalette,
    tooltip: chartTooltip((params) => `${params.marker}${params.name}：${formatChartValue(params.value)}${unit}<br/>占比：${formatChartValue(params.percent)}%`),
    legend: chartLegend({
      orient: "vertical",
      right: 6,
      top: "middle",
      itemWidth: 9,
      itemHeight: 9,
    }),
    series: [
      {
        name,
        type: "pie",
        radius: donut ? ["45%", rose ? "74%" : "66%"] : rose ? [12, "72%"] : "64%",
        center: ["36%", "52%"],
        roseType: rose ? "radius" : undefined,
        avoidLabelOverlap: true,
        itemStyle: {
          borderColor: "rgba(3, 18, 31, 0.94)",
          borderWidth: 3,
        },
        label: {
          color: "#f7feff",
          fontSize: 10,
          formatter: "{b}\n{d}%",
        },
        labelLine: {
          length: 8,
          length2: 8,
          lineStyle: { color: "rgba(223, 250, 255, 0.42)" },
        },
        data: rows.map((row, index) => ({
          name: row.name,
          value: Number(row.value) || 0,
          itemStyle: { color: row.color || chartPalette[index % chartPalette.length] },
        })),
      },
    ],
  })
}

export function createSystemRadarOption({ indicators = [], rows = [], name = "综合评价" } = {}) {
  return withChartDefaults({
    color: chartPalette,
    tooltip: chartTooltip(),
    legend: chartLegend({ top: 0, right: 4 }),
    radar: {
      center: ["50%", "58%"],
      radius: "62%",
      indicator: indicators,
      splitNumber: 4,
      axisName: {
        color: "rgba(223, 250, 255, 0.78)",
        fontSize: 10,
      },
      axisLine: { lineStyle: { color: "rgba(48, 220, 255, 0.18)" } },
      splitLine: { lineStyle: { color: "rgba(48, 220, 255, 0.16)" } },
      splitArea: {
        areaStyle: {
          color: ["rgba(48, 220, 255, 0.04)", "rgba(36, 246, 196, 0.02)"],
        },
      },
    },
    series: [
      {
        name,
        type: "radar",
        data: rows.map((row, index) => ({
          name: row.name,
          value: row.values || [],
          areaStyle: { color: `${chartPalette[index % chartPalette.length]}24` },
          lineStyle: { color: chartPalette[index % chartPalette.length], width: 2 },
          itemStyle: { color: chartPalette[index % chartPalette.length] },
        })),
      },
    ],
  })
}

export function formatChartValue(value) {
  const number = Number(value)
  if (!Number.isFinite(number)) return "--"
  return Number.isInteger(number) ? number.toLocaleString("zh-CN") : number.toLocaleString("zh-CN", { maximumFractionDigits: 2 })
}

function stripAxisOverrides(overrides = {}) {
  const { axisLabel, axisLine, axisTick, splitLine, ...rest } = overrides
  return rest
}

function formatAxisTooltip(params, unit = "") {
  const rows = Array.isArray(params) ? params : [params]
  const title = rows[0]?.axisValueLabel || rows[0]?.name || ""
  const body = rows
    .map((item) => `${item.marker}${item.seriesName || item.name}：${formatChartValue(item.value)}${unit}`)
    .join("<br/>")
  return `${title}<br/>${body}`
}

function normalizeChartTypography(target) {
  if (!target || typeof target !== "object") return
  const styleKeys = ["textStyle", "axisLabel", "nameTextStyle", "label", "axisName"]
  styleKeys.forEach((key) => {
    if (!target[key] || typeof target[key] !== "object") return
    target[key] = normalizeTextObject(target[key])
  })
  Object.keys(target).forEach((key) => {
    const value = target[key]
    if (!value || typeof value !== "object") return
    if (key === "color" || key === "itemStyle" || key === "areaStyle" || key === "lineStyle") return
    if (Array.isArray(value)) {
      value.forEach(normalizeChartTypography)
      return
    }
    normalizeChartTypography(value)
  })
}

function normalizeTextObject(style) {
  const next = {
    fontFamily: style.fontFamily || chartFontFamily,
    ...style,
  }
  if (typeof next.fontSize === "number" && next.fontSize < 10) {
    next.fontSize = 10
  }
  return next
}
