import { formatMoney } from "../../utils/format.js";

export function createGeoOption(items) {
  const points = items
    .filter((item) => Array.isArray(item.geo_point) && item.geo_point.length === 2)
    .filter((item) => Number(item.recharge_usd_minor) > 0)
    .map((item) => [...item.geo_point, Number(item.recharge_usd_minor) || 0, item.country]);
  const max = Math.max(...points.map((item) => item[2]), 1);
  const min = Math.min(...points.map((item) => item[2]), max);
  return {
    animationDuration: 650,
    geo: {
      center: [38, 12],
      emphasis: { disabled: true },
      itemStyle: {
        areaColor: "#18354e",
        borderColor: "rgba(62, 139, 184, 0.52)",
        borderWidth: 0.65
      },
      label: { show: false },
      layoutCenter: ["50%", "51%"],
      layoutSize: "112%",
      map: "databi-world",
      roam: false,
      silent: true,
      zoom: 1.04
    },
    series: [
      {
        coordinateSystem: "geo",
        data: points,
        itemStyle: {
          color: ({ value }) => colorByValue(value[2], min, max, 0.2),
          shadowBlur: 28,
          shadowColor: "rgba(39, 228, 245, 0.6)"
        },
        silent: true,
        symbolSize: (value) => 14 + (value[2] / max) * 32,
        type: "scatter",
        z: 2
      },
      {
        coordinateSystem: "geo",
        data: points,
        itemStyle: {
          borderColor: "rgba(232, 255, 255, 0.9)",
          borderWidth: 1.5,
          color: ({ value }) => colorByValue(value[2], min, max, 1),
          shadowBlur: 24,
          shadowColor: "rgba(39, 228, 245, 0.74)"
        },
        rippleEffect: { brushType: "stroke", number: 3, scale: 3.6 },
        symbolSize: (value) => 6 + (value[2] / max) * 15,
        type: "effectScatter",
        z: 3
      }
    ],
    tooltip: {
      backgroundColor: "#08243a",
      borderColor: "#1a5f82",
      formatter: ({ value }) => `${value[3]}<br/>${formatMoney(value[2])}`,
      textStyle: { color: "#e9f6ff" }
    }
  };
}

function colorByValue(value, min, max, alpha = 1) {
  const strength = normalizeStrength(value, min, max);
  const low = [66, 129, 255];
  const mid = [39, 228, 245];
  const high = [36, 215, 159];
  const from = strength < 0.55 ? low : mid;
  const to = strength < 0.55 ? mid : high;
  const local = strength < 0.55 ? strength / 0.55 : (strength - 0.55) / 0.45;
  const [red, green, blue] = from.map((channel, index) => Math.round(channel + (to[index] - channel) * local));
  return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
}

function normalizeStrength(value, min, max) {
  if (max <= min) {
    return 1;
  }
  return Math.min(Math.max((Math.sqrt(value) - Math.sqrt(min)) / (Math.sqrt(max) - Math.sqrt(min)), 0), 1);
}
