import type { EChartsOption } from 'echarts';

import type { StabilityAnalysisRow, StabilityExpectedPeriod } from '#/api/x/lims/wendingxing';

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

export interface StabilityChartModel {
  categories: string[];
  item_code: string;
  item_id: string;
  item_name: string;
  key: string;
  lower_limit: string;
  series: StabilityChartSeries[];
  standard_id: string;
  text_only: boolean;
  unit: string;
  upper_limit: string;
}

interface CategoryEntry {
  key: string;
  label: string;
  order: number;
}

export function buildStabilityChartModels(rows: StabilityAnalysisRow[], _expectedPeriods: StabilityExpectedPeriod[] = []): StabilityChartModel[] {
  const groups = new Map<string, StabilityAnalysisRow[]>();
  for (const row of rows) {
    const signature = [row.xiangmu_bianma || row.xiangmu_id, row.biaozhun_id || '', row.xiaxian || '', row.shangxian || '', row.unit || ''].join('|');
    groups.set(signature, [...(groups.get(signature) || []), row]);
  }

  return [...groups.entries()].map(([key, groupRows]) => buildChartModel(key, groupRows));
}

function buildChartModel(key: string, rows: StabilityAnalysisRow[]): StabilityChartModel {
  const first = rows[0]!;
  const categories = buildCategories(rows);
  const textOnly = isTextDataType(first.shuju_leixing);
  if (textOnly) {
    return {
      categories: categories.map((category) => category.label),
      item_code: first.xiangmu_bianma,
      item_id: first.xiangmu_id,
      item_name: first.xiangmu_mingcheng,
      key,
      lower_limit: first.xiaxian || '',
      series: [],
      standard_id: first.biaozhun_id || '',
      text_only: true,
      unit: first.unit || '',
      upper_limit: first.shangxian || '',
    };
  }

  const categoryIndex = new Map(categories.map((category, index) => [category.key, index]));
  const series: StabilityChartSeries[] = [];
  const limitSeries: StabilityChartSeries[] = [];
  if (first.xiaxian_value !== null && Number.isFinite(first.xiaxian_value)) {
    limitSeries.push(createLimitSeries('lower-limit', '下限', first.xiaxian_value, categories.length));
  }
  if (first.shangxian_value !== null && Number.isFinite(first.shangxian_value)) {
    limitSeries.push(createLimitSeries('upper-limit', '上限', first.shangxian_value, categories.length));
  }

  const duplicateBatches = duplicateBatchNumbers(rows);
  const byBatch = new Map<string, StabilityAnalysisRow[]>();
  for (const row of rows) {
    byBatch.set(row.batch_key, [...(byBatch.get(row.batch_key) || []), row]);
  }
  for (const [batchKey, batchRows] of byBatch) {
    const values: Array<null | number> = categories.map(() => null);
    const points: Array<null | StabilityAnalysisRow> = categories.map(() => null);
    const latestByCategory = new Map<string, StabilityAnalysisRow>();
    for (const row of batchRows) {
      const periodKey = categoryKey(row);
      const current = latestByCategory.get(periodKey);
      if (!current || (row.jieguo_luru_riqi || '').localeCompare(current.jieguo_luru_riqi || '') >= 0) {
        latestByCategory.set(periodKey, row);
      }
    }
    for (const [periodKey, row] of latestByCategory) {
      const index = categoryIndex.get(periodKey);
      if (index === undefined) continue;
      values[index] = row.numeric_result;
      points[index] = row;
    }
    const sample = batchRows[0]!;
    series.push({
      data: values,
      id: batchKey,
      kind: 'record',
      name: duplicateBatches.has(sample.pihao) ? `${sample.jihua_bianhao} / ${sample.pihao}` : sample.pihao,
      points,
    });
  }
  series.push(...limitSeries);

  return {
    categories: categories.map((category) => category.label),
    item_code: first.xiangmu_bianma,
    item_id: first.xiangmu_id,
    item_name: first.xiangmu_mingcheng,
    key,
    lower_limit: first.xiaxian || '',
    series,
    standard_id: first.biaozhun_id || '',
    text_only: false,
    unit: first.unit || '',
    upper_limit: first.shangxian || '',
  };
}

function buildCategories(rows: StabilityAnalysisRow[]): CategoryEntry[] {
  const entries = new Map<string, CategoryEntry>();
  for (const row of rows) {
    const key = categoryKey(row);
    if (!entries.has(key)) {
      entries.set(key, {
        key,
        label: formatPeriod(row),
        order: Number.isFinite(row.zhouqi_order) ? row.zhouqi_order : Number.MAX_SAFE_INTEGER,
      });
    }
  }
  return [...entries.values()].sort((left, right) => left.order - right.order || left.key.localeCompare(right.key));
}

function categoryKey(row: StabilityAnalysisRow) {
  return `${row.zhouqi}|${row.zhouqi_danwei}`;
}

function formatPeriod(row: StabilityAnalysisRow) {
  return formatPeriodValues(row.zhouqi, row.zhouqi_danwei);
}

function formatPeriodValues(period: string, unit: string) {
  return Number(period) === 0 ? '0' : `${formatDisplayNumber(period)}${formatPeriodUnit(unit)}`;
}

export function formatDisplayNumber(value: string) {
  const normalized = String(value ?? '').trim();
  if (!normalized) return '-';
  if (!/^[+-]?\d+(?:\.\d+)?$/.test(normalized)) return normalized;
  return normalized.replace(/(\.\d*?[1-9])0+$|\.0+$/, '$1');
}

export function formatPeriodUnit(value: string) {
  const normalized = String(value ?? '').trim();
  const unitMap: Record<string, string> = {
    d: '天',
    day: '天',
    days: '天',
    h: '小时',
    hour: '小时',
    hours: '小时',
    m: '月',
    month: '月',
    months: '月',
    w: '周',
    week: '周',
    weeks: '周',
    y: '年',
    year: '年',
    years: '年',
  };
  return unitMap[normalized.toLocaleLowerCase()] || normalized || '/';
}

function createLimitSeries(id: string, name: string, value: number, length: number): StabilityChartSeries {
  return {
    data: Array.from({ length }, () => value),
    id,
    kind: 'limit',
    name,
    points: Array.from({ length }, () => null),
  };
}

function duplicateBatchNumbers(rows: StabilityAnalysisRow[]) {
  const plansByBatch = new Map<string, Set<string>>();
  for (const row of rows) {
    const plans = plansByBatch.get(row.pihao) || new Set<string>();
    plans.add(row.jihua_id);
    plansByBatch.set(row.pihao, plans);
  }
  return new Set([...plansByBatch.entries()].filter(([, plans]) => plans.size > 1).map(([batch]) => batch));
}

function isTextDataType(dataType: string) {
  return /文本|文字|定性|字符|string|text/i.test(dataType || '');
}

export function createStabilityChartOption(model: StabilityChartModel, title: string): EChartsOption {
  const seriesById = new Map(model.series.map((series) => [series.id, series]));
  return {
    animationDuration: 300,
    grid: { bottom: 76, containLabel: true, left: 28, right: 44, top: 72 },
    legend: { bottom: 8, type: 'scroll' },
    series: model.series.map((series) => {
      if (series.kind === 'limit') {
        const color = series.id === 'upper-limit' ? '#ef4444' : '#f59e0b';
        return {
          connectNulls: false,
          data: series.data,
          endLabel: { color, formatter: ({ value }: { value: unknown }) => String(value), show: true },
          id: series.id,
          itemStyle: { color },
          lineStyle: { color, type: 'dashed', width: 1.5 },
          name: series.name,
          showSymbol: false,
          type: 'line',
        };
      }
      return {
        connectNulls: false,
        data: series.data,
        id: series.id,
        lineStyle: { width: 2 },
        name: series.name,
        showSymbol: true,
        symbol: 'circle',
        symbolSize: 7,
        type: 'line',
      };
    }),
    title: { left: 'center', text: title, textStyle: { fontSize: 18, fontWeight: 600 } },
    tooltip: {
      trigger: 'axis',
      formatter: (params: any) => {
        const list = Array.isArray(params) ? params : [params];
        const lines = [`周期：${list[0]?.axisValueLabel || ''}`];
        for (const item of list) {
          const source = seriesById.get(String(item.seriesId));
          if (!source || source.kind === 'limit') {
            lines.push(`${item.marker || ''}${item.seriesName}：${item.value ?? '-'}`);
            continue;
          }
          const point = source.points[item.dataIndex];
          if (!point) continue;
          lines.push(
            `${item.marker || ''}${item.seriesName}：${point.raw_result || '-'}`,
            `考察编号：${point.jihua_bianhao || '-'}`,
            `品名：${point.yangpin_mingcheng || '-'}`,
            `上下限：${point.xiaxian || '-'} ~ ${point.shangxian || '-'}`,
            `单位：${point.unit || '-'}`,
            `录入日期：${point.jieguo_luru_riqi || '-'}`,
          );
        }
        return lines.join('<br/>');
      },
    },
    xAxis: { boundaryGap: false, data: model.categories, type: 'category' },
    yAxis: { name: model.unit, scale: true, type: 'value' },
  };
}
