import type { EChartsOption } from 'echarts';

export interface WaterTrendItem {
  id: string;
  name: string;
  trend_enabled: boolean;
  unit: string;
}

export interface WaterTrendRecord {
  ceshi_jieguo: null | number;
  jianyan_xiang_id: string;
  jianyan_riqi: string;
  jianyan_xiangmu_id: string;
  quyangdian_id: string;
  quyangdian_mingcheng: string;
  renwu_jianyan_xiang_kuaizhao_id: string;
}

export interface WaterTrendStandard {
  biaozhun_banben?: string;
  biaozhun_bianhao?: string;
  biaozhun_shangxian?: null | number;
  biaozhun_xiaxian?: null | number;
  jianyan_xiangmu_id: string;
  renwu_jianyan_xiang_kuaizhao_id: string;
  trend_enabled: boolean;
  unit: string;
}

export interface WaterTrendSeries {
  data: Array<null | number>;
  id: string;
  kind: 'limit' | 'record';
  name: string;
}

export type WaterTrendChartType = 'bar' | 'line';

export interface WaterTrendModel {
  categories: string[];
  item: WaterTrendItem;
  key: string;
  series: WaterTrendSeries[];
  standard: WaterTrendStandard;
  unit: string;
}

interface BuildWaterTrendModelsOptions {
  items: WaterTrendItem[];
  records: WaterTrendRecord[];
  standards: WaterTrendStandard[];
}

export function buildWaterTrendModels({ items, records, standards }: BuildWaterTrendModelsOptions): WaterTrendModel[] {
  const standardsBySnapshotId = new Map(
    standards
      .filter((standard) => standard.trend_enabled && standard.renwu_jianyan_xiang_kuaizhao_id)
      .map((standard) => [standard.renwu_jianyan_xiang_kuaizhao_id, standard]),
  );

  return items.flatMap((item) => {
    if (!item.trend_enabled) {
      return [];
    }

    const recordsByStandard = new Map<string, { records: WaterTrendRecord[]; standard: WaterTrendStandard }>();
    for (const record of records) {
      if (record.jianyan_xiangmu_id !== item.id || !record.jianyan_riqi) {
        continue;
      }
      const standard = standardsBySnapshotId.get(record.renwu_jianyan_xiang_kuaizhao_id);
      if (!standard || standard.jianyan_xiangmu_id !== item.id) {
        continue;
      }
      const signature = buildStandardSignature(standard);
      const group = recordsByStandard.get(signature);
      if (group) {
        group.records.push(record);
      } else {
        recordsByStandard.set(signature, { records: [record], standard });
      }
    }

    return [...recordsByStandard.entries()].map(([signature, group]) => buildWaterTrendModel(item, signature, group.standard, group.records));
  });
}

function buildStandardSignature(standard: WaterTrendStandard) {
  return [
    standard.biaozhun_bianhao || '',
    standard.biaozhun_banben || '',
    standard.biaozhun_xiaxian ?? '',
    standard.biaozhun_shangxian ?? '',
    standard.unit || '',
  ].join('|');
}

function buildWaterTrendModel(
  item: WaterTrendItem,
  standardSignature: string,
  standard: WaterTrendStandard,
  records: WaterTrendRecord[],
): WaterTrendModel {
  const orderedRecords = [...records].sort(
    (left, right) =>
      left.jianyan_riqi.localeCompare(right.jianyan_riqi) || left.jianyan_xiang_id.localeCompare(right.jianyan_xiang_id),
  );
  const categories = orderedRecords.map((record) => record.jianyan_riqi);
  const series: WaterTrendSeries[] = [];

  const addLimitSeries = (value: null | number | undefined, id: string, name: string) => {
    if (typeof value === 'number' && Number.isFinite(value)) {
      series.push({ data: categories.map(() => value), id, kind: 'limit', name });
    }
  };

  addLimitSeries(standard.biaozhun_xiaxian, 'lower-limit', '最低限');
  addLimitSeries(standard.biaozhun_shangxian, 'upper-limit', '最高限');

  const recordsByPoint = new Map<string, Map<string, WaterTrendRecord>>();
  for (const record of orderedRecords) {
    const pointRecords = recordsByPoint.get(record.quyangdian_id) || new Map<string, WaterTrendRecord>();
    pointRecords.set(record.jianyan_xiang_id, record);
    recordsByPoint.set(record.quyangdian_id, pointRecords);
  }

  for (const [pointId, pointRecords] of recordsByPoint) {
    series.push({
      data: orderedRecords.map((record) => {
        const value = pointRecords.get(record.jianyan_xiang_id)?.ceshi_jieguo;
        return typeof value === 'number' && Number.isFinite(value) ? value : null;
      }),
      id: `point-${pointId}`,
      kind: 'record',
      name: pointRecords.values().next().value?.quyangdian_mingcheng || pointId,
    });
  }

  return {
    categories,
    item,
    key: `${item.id}:${standardSignature}`,
    series,
    standard,
    unit: standard.unit || item.unit,
  };
}

export function createWaterTrendOption(model: WaterTrendModel, title: string, chartType: WaterTrendChartType = 'line'): EChartsOption {
  const recordNameCounts = model.series.reduce((counts, series) => {
    if (series.kind === 'record') {
      counts.set(series.name, (counts.get(series.name) || 0) + 1);
    }
    return counts;
  }, new Map<string, number>());
  const chartSeries = model.series.map((series) => ({
    ...series,
    name: series.kind === 'record' && (recordNameCounts.get(series.name) || 0) > 1 ? `${series.name}（${series.id.replace('point-', '')}）` : series.name,
  }));

  return {
    color: ['#d94a4a', '#356fc5', '#12a594', '#ed9b23', '#7658ab', '#5c7080'],
    graphic: {
      bottom: 4,
      left: 'center',
      style: {
        fill: '#666',
        font: '13px sans-serif',
        text: `标准编号：${model.standard.biaozhun_bianhao || '-'}；版本：${model.standard.biaozhun_banben || '-'}`,
      },
      type: 'text',
    },
    grid: { bottom: 104, containLabel: true, left: 70, right: 40, top: 86 },
    legend: {
      bottom: 34,
      data: chartSeries.map((series) => series.name),
      type: 'scroll',
    },
    series: chartSeries.map((series) => {
      const type = series.kind === 'limit' ? 'line' : chartType;
      return {
        ...(type === 'bar' ? { barMaxWidth: 36 } : {}),
        data: series.data,
        id: series.id,
        lineStyle: series.kind === 'limit' ? { type: 'dashed', width: 2 } : { width: 2 },
        name: series.name,
        symbol: series.kind === 'limit' ? 'none' : 'circle',
        type,
      };
    }),
    title: {
      left: 'center',
      text: title,
      textStyle: { fontSize: 20, fontWeight: 700 },
    },
    toolbox: { feature: { saveAsImage: {} }, right: 16, top: 14 },
    tooltip: { trigger: 'axis' },
    xAxis: {
      axisLabel: {
        interval: 0,
        rotate: model.categories.length > 8 ? 35 : 0,
      },
      data: model.categories,
      name: '时间',
      type: 'category',
    },
    yAxis: {
      name: model.unit || '检测值',
      nameGap: 18,
      type: 'value',
    },
  };
}
