import ConfigInfo, { type BasicInfoData } from '@/components/ConfigInfo';
import {
  AutoMLTaskType,
  AutoMLType,
  ExperimentStatus,
  autoMLEnsembleClassOptions,
  autoMLTaskTypeOptions,
} from '@/enums';
import { useComputingResource } from '@/hooks/useComputingResource';
import {
  classificationAlgorithms,
  featureAlgorithms,
  regressorAlgorithms,
} from '@/pages/AutoML/components/CreateForm/utils';
import { AutoMLData } from '@/pages/AutoML/types';
import { type NodeStatus } from '@/types';
import { parseJsonText } from '@/utils';
import {
  formatBoolean,
  formatDataset,
  formatDate,
  formatEnum,
  type EnumOptions,
} from '@/utils/format';
import classNames from 'classnames';
import { useMemo } from 'react';
import ExperimentRunBasic from '../ExperimentRunBasic';
import styles from './index.less';

// 格式化优化方向
const formatOptimizeMode = (value: boolean) => {
  return value ? '越大越好' : '越小越好';
};

// 格式化权重
const formatMetricsWeight = (value: string) => {
  if (!value) {
    return '--';
  }
  const json = parseJsonText(value);
  if (!json) {
    return '--';
  }
  return Object.entries(json)
    .map(([key, value]) => `${key}:${value}`)
    .join('\n');
};

// 格式化算法
const formatAlgorithm = (algorithms: EnumOptions[]) => {
  return (value: string) => {
    if (!value) {
      return '--';
    }
    const list = value
      .split(',')
      .filter((v) => v !== '')
      .map((v) => v.trim());
    return list.map((v) => formatEnum(algorithms)(v)).join('，');
  };
};

type AutoMLBasicProps = {
  info?: AutoMLData;
  className?: string;
  isInstance?: boolean;
  workflowStatus?: NodeStatus;
  instanceStatus?: ExperimentStatus;
  instanceCreateTime?: string;
};

function AutoMLBasic({
  info,
  className,
  workflowStatus,
  instanceStatus,
  isInstance = false,
}: AutoMLBasicProps) {
  const getResourceDescription = useComputingResource()[1];
  const basicDatas: BasicInfoData[] = useMemo(() => {
    if (!info) {
      return [];
    }

    return [
      {
        label: '实验名称',
        value: info.name,
      },
      {
        label: '实验描述',
        value: info.description,
      },
      {
        label: '创建人',
        value: info.create_by,
      },
      {
        label: '创建时间',
        value: info.create_time,
        format: formatDate,
      },
      {
        label: '更新时间',
        value: info.update_time,
        format: formatDate,
      },
    ];
  }, [info]);

  const configDatas: BasicInfoData[] = useMemo(() => {
    if (!info) {
      return [];
    }
    if (info.type === AutoMLType.Table) {
      return [
        {
          label: '任务类型',
          value: info.task_type,
          format: formatEnum(autoMLTaskTypeOptions),
        },
        {
          label: '特征预处理算法',
          value: info.include_feature_preprocessor,
          format: formatAlgorithm(featureAlgorithms),
        },
        {
          label: '排除的特征预处理算法',
          value: info.exclude_feature_preprocessor,
          format: formatAlgorithm(featureAlgorithms),
        },
        {
          label: info.task_type === AutoMLTaskType.Regression ? '回归算法' : '分类算法',
          value:
            info.task_type === AutoMLTaskType.Regression
              ? info.include_regressor
              : info.include_classifier,
          format: formatAlgorithm(
            info.task_type === AutoMLTaskType.Regression
              ? regressorAlgorithms
              : classificationAlgorithms,
          ),
        },
        {
          label: info.task_type === AutoMLTaskType.Regression ? '排除的回归算法' : '排除的分类算法',
          value:
            info.task_type === AutoMLTaskType.Regression
              ? info.exclude_regressor
              : info.exclude_classifier,
          format: formatAlgorithm(
            info.task_type === AutoMLTaskType.Regression
              ? regressorAlgorithms
              : classificationAlgorithms,
          ),
        },
        {
          label: '集成方式',
          value: info.ensemble_class,
          format: formatEnum(autoMLEnsembleClassOptions),
        },
        {
          label: '集成模型数量',
          value: info.ensemble_size,
        },
        {
          label: '集成最佳模型数量',
          value: info.ensemble_nbest,
        },
        {
          label: '最大数量',
          value: info.max_models_on_disc,
        },
        {
          label: '内存限制（MB）',
          value: info.memory_limit,
        },
        {
          label: '单次时间限制（秒）',
          value: info.per_run_time_limit,
        },
        {
          label: '搜索时间限制（秒）',
          value: info.time_left_for_this_task,
        },
        {
          label: '重采样策略',
          value: info.resampling_strategy,
        },
        {
          label: '交叉验证折数',
          value: info.folds,
        },
        {
          label: '是否打乱',
          value: info.shuffle,
          format: formatBoolean,
        },
        {
          label: '训练集比率',
          value: info.train_size,
        },
        {
          label: '测试集比率',
          value: info.test_size,
        },
        {
          label: '计算指标',
          value: info.scoring_functions,
        },
        {
          label: '随机种子',
          value: info.seed,
        },
        {
          label: '数据集',
          value: info.dataset,
          format: formatDataset,
        },
        {
          label: '预测目标列',
          value: info.target_columns,
        },
      ];
    } else if (info.type === AutoMLType.Text) {
      return [
        {
          label: '模型',
          value: info.model_type,
        },
        {
          label: '数据集',
          value: info.dataset,
          format: formatDataset,
        },
        {
          label: '资源规格',
          value: info.computing_resource_id,
          format: getResourceDescription,
        },
        {
          label: 'batch_size',
          value: info.batch_size,
        },
        {
          label: 'epochs',
          value: info.epochs,
        },
        {
          label: '学习率',
          value: info.lr,
        },
      ];
    } else {
      return [
        {
          label: '数据集',
          value: info.dataset,
          format: formatDataset,
        },
        {
          label: '资源规格',
          value: info.computing_resource_id,
          format: getResourceDescription,
        },
        {
          label: '类别数量',
          value: info.num_classes,
        },
        {
          label: 'batch_size',
          value: info.batch_size,
        },
        {
          label: 'epochs',
          value: info.epochs,
        },
        {
          label: '学习率',
          value: info.lr,
        },
        {
          label: '是否验证',
          value: info.is_validate,
          format: formatBoolean,
        },
        {
          label: '训练集路径',
          value: info.train_data_prefix,
        },
        {
          label: '训练集标注文件',
          value: info.train_file_path,
        },
        ...(info.is_validate
          ? [
              {
                label: '验证集路径',
                value: info.valid_data_prefix,
              },
              {
                label: '验证集标注文件',
                value: info.valid_file_path,
              },
            ]
          : []),
      ];
    }
  }, [info, getResourceDescription]);

  const metricsData = useMemo(() => {
    if (!info) {
      return [];
    }
    return [
      {
        label: '指标名称',
        value: info.metric_name,
      },
      {
        label: '优化方向',
        value: info.greater_is_better,
        format: formatOptimizeMode,
      },
      {
        label: '指标权重',
        value: info.metrics,
        format: formatMetricsWeight,
      },
    ];
  }, [info]);

  return (
    <div className={classNames(styles['auto-ml-basic'], className)}>
      {isInstance && workflowStatus && (
        <ExperimentRunBasic workflowStatus={workflowStatus} instanceStatus={instanceStatus} />
      )}
      {!isInstance && (
        <ConfigInfo
          title="基本信息"
          datas={basicDatas}
          labelWidth={70}
          style={{ marginBottom: '20px' }}
        />
      )}
      <ConfigInfo
        title="配置信息"
        datas={configDatas}
        labelWidth={150}
        style={{ marginBottom: '20px' }}
      />
      {info?.type === AutoMLType.Table && (
        <ConfigInfo title="优化指标" datas={metricsData} labelWidth={70} />
      )}
    </div>
  );
}

export default AutoMLBasic;
