import { groupBy } from '@/tools';

export function fromAnalysisModel(mode: 'tongue' | 'face', data: Record<string, any>): AnalysisModel;
export function fromAnalysisModel(mode: 'pulse', data: Record<string, any>): PulseAnalysisModel;
export function fromAnalysisModel(mode: 'alcohol', data: Record<string, any>): AlcoholAnalysisModel;
export function fromAnalysisModel(
  mode: 'tongue' | 'face' | 'pulse' | 'alcohol',
  data: Record<string, any>
): AnalysisModel | AlcoholAnalysisModel | PulseAnalysisModel {
  let model: AnalysisModel;
  switch (mode) {
    case 'tongue':
      model = fromTongueAnalysisModel(data);
      break;
    case 'face':
      model = fromFaceAnalysisModel(data);
      break;
    case 'pulse':
      return fromPulseAnalysisModel(data);
    case 'alcohol':
      return fromAlcoholAnalysisModel(data?.extendFlowData);
  }

  const group = groupBy<AnalysisException>(model.exception, (item) => item.cover ?? '') ?? {};
  model.exceptionGroup = Object.entries(group).map(([key, exception]) => ({ key, exception }));
  return model;
}

export interface PulseAnalysisModel extends Pick<Awaited<ReturnType<typeof Bridge.pulse>>, 'measureId' | 'summaryLabel' | 'summaryValue'> {
  hand?: number;
  results?: string;
  url?: string;
}

export interface AlcoholAnalysisModel {
  condition: string;
  description: string;
  volume: [min: number, max?: number];
}

export interface AnalysisModel {
  table: {
    columns: string[];
    data: { exception: boolean; invalid?: boolean; columns: string[] }[];
  };
  exception: AnalysisException[];
  exceptionGroup: {
    key: string;
    exception: AnalysisException[]
  }[];
  cover: string[];
  result: string;
}

export interface AnalysisException {
  title: string;
  cover?: string;
  description?: string;
  descriptions: { label: string; value: string }[];
  tags: string[];
}

function fromPulseAnalysisModel(data: Record<string, any>): PulseAnalysisModel {
  const pulse = (function (value) {
    if (typeof value === 'string')
      try {
        value = JSON.parse(value);
      } catch (e) {}
    return typeof value === 'object' ? value : {};
  })(data.pulseReport);

  const getSummary = (value?: string[]) => (Array.isArray(value) && value.length ? value : void 0);
  const summary =
    getSummary(pulse?.summary_desc?.summary) ??
    getSummary(pulse?.summary_desc?.left?.summary) ??
    getSummary(pulse?.summary_desc?.right?.summary) ??
    [];

  return {
    measureId: data?.measureId,
    hand: pulse?.hand ?? 0,
    summaryValue: pulse?.summary,
    summaryLabel: pulse?.summary_desc,
    results: summary.join(','),
    url: pulse?.url ?? void 0,
  };
}

function fromAlcoholAnalysisModel(data: Record<string, any>): AlcoholAnalysisModel {
  const volume: [number, number] = data?.alcoholCapacity?.match(/(\d+)/g)?.slice(0, 2)?.filter(Boolean)?.map((v: string) => +v) ?? [];
  return {
    condition: data?.alcoholCondition,
    description: data?.alcoholCapacity,
    volume: volume.sort((a, b) => a - b),
  };
}

function fromTongueAnalysisModel(data: Record<string, any>): AnalysisModel {
  const exception: AnalysisException[] = [];
  const fromTongueException = fromAnalysisException(exception);
  const c1 = data?.upImg ?? data?.tongueImgUrl;
  const c2 = data?.downImg ?? data?.tongueBackImgUrl;
  return {
    table: {
      columns: ['舌象维度', '检测结果', '标准值'],
      data: [
        fromTongueException(data?.tongueColor, '舌色'),
        fromTongueException(data?.tongueCoatingColor, '苔色'),
        fromTongueException(data?.tongueShape, '舌形'),
        fromTongueException(data?.tongueCoating, '苔质'),
        fromTongueException(data?.bodyFluid, '津液'),
        fromTongueException(data?.sublingualVein, '舌下'),
      ],
    },
    exception,
    exceptionGroup: [],
    result: data?.tongueAnalysisResult ?? data?.tongue ?? '',
    cover: Object.assign([c1, c2].filter(Boolean), {
      ['舌上']: c1,
      ['舌下']: c2,
    }),
  };
}

function fromFaceAnalysisModel(data: Record<string, any>): AnalysisModel {
  const exception: AnalysisException[] = [];
  const fromFaceException = fromAnalysisException(exception, (label, value) => `${label}${value}`);
  const c1 = data?.faceImg ?? data?.faceImgUrl;
  const c2 = data?.faceLeft ?? data?.faceLeftImgUrl;
  const c3 = data?.faceRight ?? data?.faceRightImgUrl;
  return {
    table: {
      columns: ['面象维度', '检测结果', '标准值'],
      data: [
        fromFaceException(data?.faceColor, '面色'),
        fromFaceException(data?.mainColor, '主色'),
        fromFaceException(data?.shine, '光泽'),
        fromFaceException(data?.blackEye, '黑眼圈'),
        // fromFaceException(data?.leftBlackEye, '左黑眼圈'),
        // fromFaceException(data?.rightBlackEye, '右黑眼圈'),
        fromFaceException(data?.lipColor, '唇色'),
        fromFaceException(data?.eyeContact, '眼神'),
        fromFaceException(data?.eyeColor, '目色'),
        // fromFaceException(data?.leftEyeColor, '左目色'),
        // fromFaceException(data?.rightEyeColor, '右目色'),
        fromFaceException(data?.hecticCheek, '两颧红'),
        fromFaceException(data?.noseFold, '鼻褶'),
        fromFaceException(data?.cyanGlabella, '眉间/鼻柱青色'),
        fromFaceException(data?.faceSkinDefects, '面部皮损'),
      ],
    },
    exception,
    exceptionGroup: [],
    result: data?.faceAnalysisResult ?? data?.face ?? '',
    cover: Object.assign([c1, c2, c3].filter(Boolean), {
      ['正面']: c1,
      ['左面']: c2,
      ['右面']: c3,
    }),
  };
}

function fromAnalysisException(exception: AnalysisException[], $title = (label: string, value: string) => value) {
  return function (data: { actualList?: Record<string, any>[]; standardValue?: string }, label: string) {
    let is = false;
    let invalid = false;
    const values =
      data?.actualList?.map((item) => {
        let title: string = item?.actualValue ?? '';
        const suffix = item?.contrast ?? 's';
        if (title.endsWith('不符合检测要求')) { invalid = true; }
        else if (suffix !== 's') {
          if (suffix !== 'r') title += ` (${suffix || ''}) `;
          is = true;
          exception.push({
            title: $title(label, title),
            cover: item.splitImage,
            descriptions: [
              item.features ? { label: '【特征】', value: item.features } : null,
              item.clinicalSignificance ? { label: '【临床意义】', value: item.clinicalSignificance } : null,
            ].filter((v) => !!v),
            tags: item.attrs ?? [],
          });
        }
        return title;
      }) ?? [];
    return {
      exception: is, invalid,
      columns: [label, values.join('<br>'), data?.standardValue ?? '']
    }
  };
}
