import TableColTitle from '@/components/TableColTitle';
import TrialStatusCell from '@/pages/HyperParameter/components/TrialStatusCell';
import { HyperParameterTrial } from '@/pages/HyperParameter/types';
import { getExpMetricsReq } from '@/services/hyperParameter';
import { to } from '@/utils/promise';
import tableCellRender, { TableCellValueType } from '@/utils/table';
import { App, Button, Table, type TableProps } from 'antd';
import classNames from 'classnames';
import { useEffect, useState } from 'react';
import TrialFileTree from '../TrialFileTree';
import styles from './index.less';

type ExperimentHistoryProps = {
  trialList?: HyperParameterTrial[];
};

function ExperimentHistory({ trialList = [] }: ExperimentHistoryProps) {
  const [expandedRowKeys, setExpandedRowKeys] = useState<string[]>([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const { message } = App.useApp();
  const [tableData, setTableData] = useState<HyperParameterTrial[]>([]);
  const [loading, setLoading] = useState(false);

  // 防止 Tabs 卡顿
  useEffect(() => {
    setLoading(true);
    setTimeout(() => {
      setTableData(trialList);
      setLoading(false);
    }, 500);
  }, [trialList]);

  // 计算 column
  const first: HyperParameterTrial | undefined = trialList ? trialList[0] : undefined;
  const config: Record<string, any> = first?.config ?? {};
  const metricAnalysis: Record<string, any> = first?.metric_analysis ?? {};
  const paramsNames = Object.keys(config);
  const metricNames = Object.keys(metricAnalysis);

  const trialColumns: TableProps<HyperParameterTrial>['columns'] = [
    {
      title: '序号',
      dataIndex: 'index',
      key: 'index',
      width: 100,
      fixed: 'left',
      render: (_text, record, index: number) => {
        return (
          <div className={styles['cell-index']}>
            <span className={styles['cell-index__text']}>{index + 1}</span>
            {record.is_best && <span className={styles['cell-index__best-tag']}>最佳</span>}
          </div>
        );
      },
    },
    {
      title: '基本信息',
      align: 'center',
      children: [
        {
          title: '运行次数',
          dataIndex: 'training_iteration',
          key: 'training_iteration',
          width: 120,
          fixed: 'left',
          render: tableCellRender(false),
        },
        {
          title: '平均时长（秒）',
          dataIndex: 'time_avg',
          key: 'time_avg',
          width: 150,
          fixed: 'left',
          render: tableCellRender(false, TableCellValueType.Custom, {
            format: (value = 0) => Number(value).toFixed(2),
          }),
        },
        {
          title: '状态',
          dataIndex: 'status',
          key: 'status',
          width: 120,
          fixed: 'left',
          render: TrialStatusCell,
        },
      ],
    },
  ];

  if (paramsNames.length) {
    trialColumns.push({
      title: '运行参数',
      dataIndex: 'config',
      key: 'config',
      align: 'center',
      children: paramsNames.map((name) => ({
        title: <TableColTitle title={name} />,
        dataIndex: ['config', name],
        key: name,
        width: 120,
        align: 'center',
        render: tableCellRender(true),
      })),
    });
  }

  if (metricNames.length) {
    trialColumns.push({
      title: `指标分析（${first?.metric ?? ''}）`,
      dataIndex: 'metrics',
      key: 'metrics',
      align: 'center',
      children: metricNames.map((name) => ({
        title: <TableColTitle title={name} />,
        dataIndex: ['metric_analysis', name],
        key: name,
        width: 120,
        align: 'center',
        render: tableCellRender(true),
      })),
    });
  }

  // 自定义展开视图
  const expandedRowRender = (record: HyperParameterTrial) => {
    return <TrialFileTree title="寻优结果" file={record.file}></TrialFileTree>;
  };

  // 展开实例
  const handleExpandChange = (expanded: boolean, record: HyperParameterTrial) => {
    if (expanded) {
      setExpandedRowKeys([record.trial_id]);
    } else {
      setExpandedRowKeys([]);
    }
  };

  // 选择行
  const rowSelection: TableProps<HyperParameterTrial>['rowSelection'] = {
    type: 'checkbox',
    columnWidth: 48,
    fixed: 'left',
    selectedRowKeys,
    onChange: (selectedRowKeys: React.Key[]) => {
      setSelectedRowKeys(selectedRowKeys);
    },
  };

  // 对比
  const handleComparisonClick = () => {
    if (selectedRowKeys.length < 1) {
      message.error('请至少选择一项');
      return;
    }
    getExpMetrics();
  };

  // 获取对比 url
  const getExpMetrics = async () => {
    const [res] = await to(getExpMetricsReq(selectedRowKeys));
    if (res && res.data) {
      const url = res.data;
      window.open(url, '_blank');
    }
  };

  return (
    <div className={styles['experiment-history']}>
      <div className={styles['experiment-history__content']}>
        <Button type="default" onClick={handleComparisonClick}>
          可视化对比
        </Button>
        <div
          className={classNames(
            'vertical-scroll-table-no-page',
            styles['experiment-history__content__table'],
          )}
        >
          <Table
            loading={loading}
            rowClassName={(record) => (record.is_best ? styles['table-best-row'] : '')}
            dataSource={tableData}
            columns={trialColumns}
            pagination={false}
            bordered={true}
            scroll={{ y: 'calc(100% - 110px)', x: '100%' }}
            rowKey="trial_id"
            expandable={{
              expandedRowRender: expandedRowRender,
              onExpand: handleExpandChange,
              expandedRowKeys: expandedRowKeys,
              rowExpandable: (record: HyperParameterTrial) => !!record.file,
            }}
            rowSelection={rowSelection}
          />
        </div>
      </div>
    </div>
  );
}

export default ExperimentHistory;
