<template>
  <view class="ec-wrap">
    <!-- 通过 props 把 option 喂给 renderjs -->
    <view
      class="ec-canvas"
      :prop="option"
      :change:prop="ec.setOption"
      :data-theme="theme"
    />
  </view>
</template>

<script>
export default {
  name: "EChartsView",
  props: {
    option: { type: Object, default: () => ({}) },
    theme: { type: String, default: "light" },
  },
};
</script>

<script module="ec" lang="renderjs">
import * as echarts from "echarts";

// 使用 Map 存储多个图表实例（支持多个 EChartsView 组件）
const charts = new Map();
const resizeObservers = new Map();

// 地图数据加载状态
let chinaMapLoaded = false;
let chinaMapLoading = false;

// 内置的简化中国地图数据（50个主要城市或地区的边界）
const SIMPLIFIED_CHINA_MAP = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": { "name": "南海诸岛", "cp": [113.5439, 3.5951], "childNum": 0 },
      "geometry": { "type": "MultiPolygon", "coordinates": [[[[113.5439, 3.5951], [113.5439, 3.5951]]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "北京", "cp": [116.4074, 39.9042], "childNum": 16 },
      "geometry": { "type": "Polygon", "coordinates": [[[116, 39.5], [117, 39.5], [117, 40.5], [116, 40.5], [116, 39.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "天津", "cp": [117.2, 39.0842], "childNum": 16 },
      "geometry": { "type": "Polygon", "coordinates": [[[116.7, 38.7], [117.7, 38.7], [117.7, 39.5], [116.7, 39.5], [116.7, 38.7]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "河北", "cp": [114.5149, 38.0428], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[113.5, 37.5], [119.5, 37.5], [119.5, 42.5], [113.5, 42.5], [113.5, 37.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "山西", "cp": [112.5489, 37.8739], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[110.5, 35], [114.5, 35], [114.5, 40.5], [110.5, 40.5], [110.5, 35]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "内蒙古", "cp": [111.7558, 40.8183], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[97, 37], [126, 37], [126, 54], [97, 54], [97, 37]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "辽宁", "cp": [123.4328, 41.8045], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[118.5, 40], [126.5, 40], [126.5, 45], [118.5, 45], [118.5, 40]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "吉林", "cp": [125.3235, 43.8957], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[121, 41.5], [130, 41.5], [130, 48.5], [121, 48.5], [121, 41.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "黑龙江", "cp": [126.6424, 45.7568], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[121, 43.5], [135, 43.5], [135, 55], [121, 55], [121, 43.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "上海", "cp": [121.4737, 31.2304], "childNum": 16 },
      "geometry": { "type": "Polygon", "coordinates": [[[120.8, 30.7], [122, 30.7], [122, 31.9], [120.8, 31.9], [120.8, 30.7]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "江苏", "cp": [118.7969, 32.9387], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[118, 31], [122, 31], [122, 34.5], [118, 34.5], [118, 31]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "浙江", "cp": [120.1551, 30.2741], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[118.5, 28], [123, 28], [123, 31.5], [118.5, 31.5], [118.5, 28]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "安徽", "cp": [117.2272, 31.8654], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[114.5, 29.5], [119.5, 29.5], [119.5, 34.5], [114.5, 34.5], [114.5, 29.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "福建", "cp": [119.295492, 26.0745], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[118.5, 23.5], [121.5, 23.5], [121.5, 28], [118.5, 28], [118.5, 23.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "江西", "cp": [115.8581, 28.6832], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[113, 24], [118, 24], [118, 30], [113, 30], [113, 24]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "山东", "cp": [117.1205, 36.6519], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[114, 34.5], [122, 34.5], [122, 38], [114, 38], [114, 34.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "河南", "cp": [113.6254, 34.7466], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[111.5, 32], [117, 32], [117, 36.5], [111.5, 36.5], [111.5, 32]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "湖北", "cp": [114.3055, 30.5928], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[108, 28.5], [116, 28.5], [116, 33], [108, 33], [108, 28.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "湖南", "cp": [112.9388, 28.2282], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[108.5, 24.5], [114, 24.5], [114, 30], [108.5, 30], [108.5, 24.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "广东", "cp": [113.2644, 23.1291], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[112, 20.5], [116, 20.5], [116, 25], [112, 25], [112, 20.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "广西", "cp": [108.3661, 22.8170], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[104.5, 20.5], [112, 20.5], [112, 26.5], [104.5, 26.5], [104.5, 20.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "四川", "cp": [104.0665, 30.5702], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[100, 26], [108, 26], [108, 35], [100, 35], [100, 26]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "贵州", "cp": [106.7135, 26.5783], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[103.5, 24.5], [109.5, 24.5], [109.5, 29.5], [103.5, 29.5], [103.5, 24.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "云南", "cp": [102.7103, 24.8801], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[97.5, 21], [106.5, 21], [106.5, 30], [97.5, 30], [97.5, 21]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "陕西", "cp": [108.9402, 34.3416], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[105.5, 31.5], [111.5, 31.5], [111.5, 39], [105.5, 39], [105.5, 31.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "甘肃", "cp": [103.8343, 35.0080], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[92, 32], [108, 32], [108, 42], [92, 42], [92, 32]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "青海", "cp": [101.7782, 36.6171], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[89, 31.5], [104.5, 31.5], [104.5, 39.5], [89, 39.5], [89, 31.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "宁夏", "cp": [106.2586, 38.4680], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[104.5, 35.5], [107.5, 35.5], [107.5, 40], [104.5, 40], [104.5, 35.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "新疆", "cp": [87.6278, 43.7929], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[73, 26], [104, 26], [104, 49], [73, 49], [73, 26]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "西藏", "cp": [88.0959, 29.6470], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[78, 26], [99, 26], [99, 36.5], [78, 36.5], [78, 26]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "台湾", "cp": [120.9605, 23.6978], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[120.1, 22.5], [121.5, 22.5], [121.5, 25], [120.1, 25], [120.1, 22.5]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "香港", "cp": [114.1694, 22.3193], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[113.8, 22], [114.5, 22], [114.5, 22.6], [113.8, 22.6], [113.8, 22]]] }
    },
    {
      "type": "Feature",
      "properties": { "name": "澳门", "cp": [113.5439, 22.2987], "childNum": 0 },
      "geometry": { "type": "Polygon", "coordinates": [[[113.3, 22.1], [113.7, 22.1], [113.7, 22.5], [113.3, 22.5], [113.3, 22.1]]] }
    }
  ]
};

// 加载并注册中国地图
async function loadChinaMap() {
  if (chinaMapLoaded) {
    return Promise.resolve();
  }

  if (chinaMapLoading) {
    // 如果正在加载，等待加载完成
    return new Promise((resolve) => {
      const checkInterval = setInterval(() => {
        if (chinaMapLoaded) {
          clearInterval(checkInterval);
          resolve();
        }
      }, 100);
      // 最多等待 10 秒
      setTimeout(() => {
        clearInterval(checkInterval);
        resolve();
      }, 10000);
    });
  }

  chinaMapLoading = true;

  try {
    // 首先尝试从在线 CDN 加载中国地图 GeoJSON 数据
    let geoJson = null;
    let loaded = false;

    try {
      const response = await fetch('https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json', {
        timeout: 5000
      });
      if (response.ok) {
        geoJson = await response.json();
        loaded = true;
        console.log('[EChartsView] 从阿里云 CDN 加载中国地图数据成功');
      }
    } catch (e) {
      console.warn('[EChartsView] 从阿里云 CDN 加载失败，尝试备用源...', e);
    }

    // 如果第一个源失败，尝试备用源
    if (!loaded) {
      try {
        const backupResponse = await fetch('https://echarts.apache.org/examples/data/map/china.json', {
          timeout: 5000
        });
        if (backupResponse.ok) {
          geoJson = await backupResponse.json();
          loaded = true;
          console.log('[EChartsView] 从 ECharts 官方源加载中国地图数据成功');
        }
      } catch (e) {
        console.warn('[EChartsView] 从备用源加载也失败，使用内置简化地图', e);
      }
    }

    // 如果网络加载都失败，使用内置的简化地图
    if (!loaded) {
      geoJson = SIMPLIFIED_CHINA_MAP;
      console.log('[EChartsView] 使用内置简化中国地图数据');
    }

    // 注册地图
    if (geoJson) {
      echarts.registerMap('china', geoJson);
      chinaMapLoaded = true;
      console.log('[EChartsView] 中国地图数据已注册');
    } else {
      throw new Error('Failed to load or create China map data');
    }
  } catch (error) {
    console.error('[EChartsView] 加载中国地图数据失败:', error);
    // 降级方案：使用简化地图
    try {
      echarts.registerMap('china', SIMPLIFIED_CHINA_MAP);
      chinaMapLoaded = true;
      console.log('[EChartsView] 已使用内置简化地图作为降级方案');
    } catch (furtherError) {
      console.error('[EChartsView] 即使使用简化地图也失败:', furtherError);
    }
  } finally {
    chinaMapLoading = false;
  }
}

function getChartKey(el) {
  // 使用元素的唯一标识作为 key
  if (!el._echartsKey) {
    el._echartsKey = 'echarts_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
  }
  return el._echartsKey;
}

function ensureChart(el, retryCount = 0) {
  if (!el) return null;

  const key = getChartKey(el);
  let chart = charts.get(key);

  // 如果图表已存在且有效，直接返回
  if (chart && !chart.isDisposed()) {
    return chart;
  }

  // 如果图表已销毁，从 Map 中移除
  if (chart && chart.isDisposed()) {
    charts.delete(key);
    const ro = resizeObservers.get(key);
    if (ro) {
      ro.disconnect();
      resizeObservers.delete(key);
    }
    chart = null;
  }

  // 确保元素有尺寸
  const rect = el.getBoundingClientRect();
  const computedStyle = window.getComputedStyle(el);
  const width = parseFloat(computedStyle.width) || rect.width;
  const height = parseFloat(computedStyle.height) || rect.height;

  // 如果尺寸为 0，尝试延迟初始化（最多重试 10 次）
  if ((width === 0 || height === 0) && retryCount < 10) {
    if (retryCount === 0) {
      console.warn('[EChartsView] 容器尺寸为 0，延迟初始化', { width, height, rect });
    }

    // 使用指数退避策略，避免无限循环
    const delay = Math.min(100 * Math.pow(1.5, retryCount), 1000);
    setTimeout(() => {
      ensureChart(el, retryCount + 1);
    }, delay);
    return null;
  }

  // 如果重试次数过多，使用默认尺寸
  if (width === 0 || height === 0) {
    console.warn('[EChartsView] 容器尺寸仍为 0，使用默认尺寸', { width, height });
    // 使用父元素尺寸或默认值
    const parentRect = el.parentElement ? el.parentElement.getBoundingClientRect() : { width: 800, height: 400 };
    const finalWidth = width || parentRect.width || 800;
    const finalHeight = height || parentRect.height || 400;

    if (finalWidth > 0 && finalHeight > 0) {
      // 设置元素尺寸
      el.style.width = finalWidth + 'px';
      el.style.height = finalHeight + 'px';
    } else {
      console.error('[EChartsView] 无法确定容器尺寸，跳过初始化');
      return null;
    }
  }

      try {
        // 注意：地图数据加载在 setOption 中处理，这里不处理
        // 因为 ensureChart 是同步函数，不能使用 await

        chart = echarts.init(el, null, {
          renderer: "canvas",
          width: rect.width,
          height: rect.height
        });

        charts.set(key, chart);

    // 自适应：监听容器尺寸变化
    if (typeof ResizeObserver !== "undefined") {
      const ro = new ResizeObserver((entries) => {
        for (const entry of entries) {
          const { width, height } = entry.contentRect;
          const c = charts.get(key);
          if (c && !c.isDisposed() && width > 0 && height > 0) {
            try {
              c.resize({ width, height });
            } catch (e) {
              console.warn('[EChartsView] resize 失败', e);
            }
          }
        }
      });
      ro.observe(el);
      resizeObservers.set(key, ro);
    } else {
      // 兜底
      const resizeHandler = () => {
        const c = charts.get(key);
        if (c && !c.isDisposed()) {
          const rect = el.getBoundingClientRect();
          if (rect.width > 0 && rect.height > 0) {
            try {
              c.resize();
            } catch (e) {
              console.warn('[EChartsView] resize 失败', e);
            }
          }
        }
      };
      window.addEventListener("resize", resizeHandler);
      // 存储 handler 以便后续清理
      el._resizeHandler = resizeHandler;
    }

    return chart;
  } catch (e) {
    console.error('[EChartsView] 初始化失败', e);
    return null;
  }
}

function disposeChart(el) {
  if (!el) return;
  const key = getChartKey(el);
  const chart = charts.get(key);

  if (chart && !chart.isDisposed()) {
    try {
      chart.dispose();
    } catch (e) {
      console.warn('[EChartsView] dispose 失败', e);
    }
  }

  charts.delete(key);

  const ro = resizeObservers.get(key);
  if (ro) {
    ro.disconnect();
    resizeObservers.delete(key);
  }

  if (el._resizeHandler) {
    window.removeEventListener("resize", el._resizeHandler);
    delete el._resizeHandler;
  }
}

export default {
  mounted() {
    const el = this.$el.querySelector(".ec-canvas") || this.$el;
    if (!el) {
      console.error('[EChartsView] 找不到容器元素');
      return;
    }
    // 延迟初始化，确保 DOM 已渲染
    setTimeout(() => {
      ensureChart(el);
    }, 50);
  },
  beforeDestroy() {
    const el = this.$el.querySelector(".ec-canvas") || this.$el;
    if (el) {
      disposeChart(el);
    }
  },
  methods: {
    async setOption(option, oldOption) {
      const el = this.$el.querySelector(".ec-canvas") || this.$el;
      if (!el) {
        console.error('[EChartsView] setOption: 找不到容器元素');
        return;
      }

      // 检查 option 是否有效
      if (!option || typeof option !== 'object') {
        console.warn('[EChartsView] setOption: option 无效', option);
        return;
      }

      // 检查是否使用了地图，如果是，先加载地图数据
      const needsMap = option.geo || (option.series && Array.isArray(option.series) && option.series.some(s => s.type === 'map' && s.map === 'china'));
      if (needsMap) {
        await loadChinaMap();
      }

      // 保存 option 供 ensureChart 使用
      el._pendingOption = option;

      // 确保图表已初始化
      let c = ensureChart(el);
      if (!c) {
        // 如果容器尺寸为 0，使用 ResizeObserver 等待容器尺寸可用
        if (typeof ResizeObserver !== "undefined") {
          let roTimeout = null;
          const ro = new ResizeObserver(async (entries) => {
            for (const entry of entries) {
              const { width, height } = entry.contentRect;
              if (width > 0 && height > 0) {
                ro.disconnect();
                if (roTimeout) clearTimeout(roTimeout);
                c = ensureChart(el);
                if (c && !c.isDisposed()) {
                  try {
                    // 如果使用地图，确保地图已加载
                    if (needsMap) {
                      await loadChinaMap();
                    }
                    const plainOption = JSON.parse(JSON.stringify(option));
                    c.setOption(plainOption, true);
                    requestAnimationFrame(() => {
                      const c2 = charts.get(getChartKey(el));
                      if (c2 && !c2.isDisposed()) {
                        try {
                          c2.resize({ width, height });
                        } catch (e) {
                          // 忽略已销毁的错误
                        }
                      }
                    });
                  } catch (e) {
                    console.error('[EChartsView] setOption 失败', e);
                  }
                }
                break;
              }
            }
          });
          ro.observe(el);
          // 设置超时，避免无限等待（5秒后强制使用默认尺寸）
          roTimeout = setTimeout(() => {
            ro.disconnect();
            console.warn('[EChartsView] ResizeObserver 超时，尝试使用默认尺寸初始化');
            // 尝试使用父元素尺寸或默认值
            const parentRect = el.parentElement ? el.parentElement.getBoundingClientRect() : null;
            const defaultWidth = parentRect ? parentRect.width : 800;
            const defaultHeight = parentRect ? parentRect.height : 400;
            if (defaultWidth > 0 && defaultHeight > 0) {
              el.style.width = defaultWidth + 'px';
              el.style.height = defaultHeight + 'px';
              c = ensureChart(el);
              if (c && !c.isDisposed()) {
                try {
                  const plainOption = JSON.parse(JSON.stringify(option));
                  c.setOption(plainOption, true);
                } catch (e) {
                  console.error('[EChartsView] setOption 失败', e);
                }
              }
            }
          }, 5000);
        } else {
          // 兜底：延迟重试（最多3次）
          let retryCount = 0;
          const maxRetries = 3;
          const retry = () => {
            if (retryCount >= maxRetries) {
              console.warn('[EChartsView] 重试次数过多，跳过初始化');
              return;
            }
            retryCount++;
            setTimeout(async () => {
              if (needsMap) {
                await loadChinaMap();
              }
              c = ensureChart(el);
              if (c && !c.isDisposed()) {
                try {
                  const plainOption = JSON.parse(JSON.stringify(option));
                  c.setOption(plainOption, true);
                } catch (e) {
                  console.error('[EChartsView] setOption 失败', e);
                }
              } else if (retryCount < maxRetries) {
                retry();
              }
            }, 200 * retryCount);
          };
          retry();
        }
        return;
      }

      // 检查图表是否已销毁
      if (c.isDisposed()) {
        console.warn('[EChartsView] setOption: 图表已销毁，重新初始化');
        charts.delete(getChartKey(el));
        if (needsMap) {
          await loadChinaMap();
        }
        c = ensureChart(el);
        if (!c) return;
      }

      try {
        // 如果使用地图，确保地图已加载
        if (needsMap) {
          await loadChinaMap();
        }
        // 深拷贝 option 确保是纯 JS 对象
        const plainOption = JSON.parse(JSON.stringify(option));
        c.setOption(plainOption, true);

        // 使用 requestAnimationFrame 避免 resize 警告
        requestAnimationFrame(() => {
          const key = getChartKey(el);
          const c2 = charts.get(key);
          if (c2 && !c2.isDisposed()) {
            const rect = el.getBoundingClientRect();
            if (rect.width > 0 && rect.height > 0) {
              try {
                c2.resize({ width: rect.width, height: rect.height });
              } catch (e) {
                // 忽略已销毁的错误（可能组件已卸载）
              }
            }
          }
        });
      } catch (e) {
        console.error('[EChartsView] setOption 失败', e, option);
      }
    },
  },
};
</script>

<style>
.ec-wrap {
  position: relative !important;
  width: 100%;
  height: 100%;
  overflow: hidden; /* 防止 canvas 越界 */
}

.ec-canvas {
  position: absolute !important;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  width: 100% !important;
  height: 100% !important;
  display: block;
}
</style>
