import SubAreaTitle from '@/components/SubAreaTitle';
import TableColTitle from '@/components/TableColTitle';
import { useCheck } from '@/hooks/useCheck';
import { getModelPageVersionsReq, getModelVersionsMetricsReq } from '@/services/dataset';
import { tableSorter } from '@/utils';
import { VersionChangedMessage } from '@/utils/constant';
import { to } from '@/utils/promise';
import tableCellRender from '@/utils/table';
import { Checkbox, Flex, Table, type TablePaginationConfig, type TableProps } from 'antd';
import { useEffect, useMemo, useState } from 'react';
import MetricsChart, { MetricsChatData } from '../MetricsChart';
import styles from './index.less';

enum MetricsType {
  Train = 'train', // 训练
  Evaluate = 'evaluate', // 评估
}

type TableData = {
  name: string;
  metrics_names?: string[];
  metrics?: Record<string, number>;
  params_names?: string[];
  params?: Record<string, number>;
};

type ModelMetricsProps = {
  resourceId: number;
  identifier: string;
  owner: string;
  version: string; // 当前版本
};

function ModelMetrics({ resourceId, identifier, owner, version }: ModelMetricsProps) {
  const [pagination, setPagination] = useState<TablePaginationConfig>({
    current: 1,
    pageSize: 10,
  });
  const [total, setTotal] = useState(0);
  const [tableData, setTableData] = useState<TableData[]>([]);
  const [chartData, setChartData] = useState<Record<string, MetricsChatData[]> | undefined>(
    undefined,
  );
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  // 获取所有的指标名称
  const allMetricsNames = useMemo(() => {
    const first: TableData | undefined = tableData.find(
      (item) => item.metrics_names && item.metrics_names.length > 0,
    );
    return first?.metrics_names ?? [];
  }, [tableData]);
  const [
    selectedMetrics,
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    _setSelectedMetrics,
    metricsChecked,
    metricsIndeterminate,
    checkAllMetrics,
    isSingleMetricsChecked,
    checkSingleMetrics,
  ] = useCheck(allMetricsNames);

  // 新增，删除版本时，重置分页，然后刷新版本列表
  useEffect(() => {
    const handleMessage = (e: MessageEvent) => {
      const { type } = e.data;
      if (type === VersionChangedMessage) {
        setPagination({
          current: 1,
          pageSize: 10,
        });
      }
    };

    window.addEventListener('message', handleMessage);
    return () => {
      window.removeEventListener('message', handleMessage);
    };
  }, []);

  useEffect(() => {
    // 获取模型版本列表，带有参数和指标数据
    const getModelPageVersions = async () => {
      const params = {
        page: pagination.current! - 1,
        size: pagination.pageSize,
        identifier: identifier,
        owner: owner,
        type: MetricsType.Train,
      };
      const [res] = await to(getModelPageVersionsReq(params));
      if (res && res.data) {
        const { content = [], totalElements = 0 } = res.data;
        setTableData(content);
        setTotal(totalElements);
      }
    };

    getModelPageVersions();
  }, [pagination, identifier, owner]);

  // 版本切换，自动勾选当前版本
  useEffect(() => {
    const curRow = tableData.find((item) => item.name === version);
    if (curRow && curRow.metrics_names && curRow.metrics_names.length > 0) {
      setSelectedRowKeys((prev) => {
        if (!prev.includes(version)) {
          return [version, ...prev];
        }
        return prev;
      });
    }
  }, [tableData, version]);

  useEffect(() => {
    // 获取模型版本指标的图表数据
    const getModelVersionsMetrics = async () => {
      const params = {
        versions: selectedRowKeys,
        metrics: selectedMetrics,
        type: MetricsType.Train,
        identifier: identifier,
        repo_id: resourceId,
      };
      const [res] = await to(getModelVersionsMetricsReq(params));
      if (res && res.data) {
        setChartData(res.data);
      }
    };

    if (selectedMetrics.length !== 0 && selectedRowKeys.length !== 0) {
      getModelVersionsMetrics();
    } else {
      setChartData(undefined);
    }
  }, [selectedMetrics, selectedRowKeys, identifier, resourceId]);

  // 分页切换
  const handleTableChange: TableProps<TableData>['onChange'] = (
    pagination,
    _filters,
    _sorter,
    { action },
  ) => {
    if (action === 'paginate') {
      setPagination(pagination);
    }
  };

  // 行勾选
  const rowSelection: TableProps<TableData>['rowSelection'] = {
    type: 'checkbox',
    fixed: 'left',
    selectedRowKeys,
    onChange: (selectedRowKeys: React.Key[]) => {
      setSelectedRowKeys(selectedRowKeys);
    },
    getCheckboxProps: (record: TableData) => ({
      disabled: !record.metrics_names || record.metrics_names.length === 0,
    }),
  };

  // 计算的表格数据
  const showTableData = useMemo(() => {
    const index = tableData.findIndex((item) => item.name === version);
    if (index !== -1) {
      const rowData = tableData[index];
      const newTableData = tableData.filter((_, idx) => idx !== index);
      return [rowData, ...newTableData];
    }
  }, [version, tableData]);

  // 表头
  const columns: TableProps<TableData>['columns'] = useMemo(() => {
    const firstMetrics: TableData | undefined = tableData.find(
      (item) => item.metrics_names && item.metrics_names.length > 0,
    );
    const firstParams: TableData | undefined = tableData.find(
      (item) => item.params_names && item.params_names.length > 0,
    );
    const metricsNames = firstMetrics?.metrics_names ?? [];
    const paramsNames = firstParams?.params_names ?? [];
    return [
      {
        title: '基本信息',
        align: 'center',
        children: [
          {
            title: '版本号',
            dataIndex: 'name',
            key: 'name',
            width: 180,
            fixed: 'left',
            align: 'center',
            render: tableCellRender(false),
          },
        ],
      },
      {
        title: `训练参数`,
        align: 'center',
        children: paramsNames.map((name) => ({
          title: <TableColTitle title={name} />,
          dataIndex: ['params', name],
          key: name,
          width: 150,
          align: 'center',
          render: tableCellRender(true),
          sorter: (a, b) => tableSorter(a.params?.[name], b.params?.[name]),
          showSorterTooltip: false,
        })),
      },
      {
        title: () => (
          <div>
            <Checkbox
              checked={metricsChecked}
              indeterminate={metricsIndeterminate}
              onChange={checkAllMetrics}
              disabled={metricsNames.length === 0}
            ></Checkbox>
            <span style={{ marginLeft: 4 }}>训练指标</span>
          </div>
        ),
        align: 'center',
        children: metricsNames.map((name) => ({
          title: (
            <Flex align="center">
              <Checkbox
                checked={isSingleMetricsChecked(name)}
                onChange={(e) => {
                  e.stopPropagation();
                  checkSingleMetrics(name);
                }}
                onClick={(e) => e.stopPropagation()}
              ></Checkbox>
              <TableColTitle style={{ marginLeft: 4 }} title={name} />
            </Flex>
          ),
          dataIndex: ['metrics', name],
          key: name,
          width: 150,
          align: 'center',
          render: tableCellRender(true),
          sorter: (a, b) => tableSorter(a.metrics?.[name], b.metrics?.[name]),
          showSorterTooltip: false,
        })),
      },
    ];
  }, [
    tableData,
    checkAllMetrics,
    checkSingleMetrics,
    isSingleMetricsChecked,
    metricsChecked,
    metricsIndeterminate,
  ]);

  return (
    <div className={styles['model-metrics']}>
      <div className={styles['model-metrics__table']}>
        <SubAreaTitle
          title="指标参数差异对比"
          image={require('@/assets/img/model-metrics.png')}
          style={{ marginBottom: '15px' }}
        ></SubAreaTitle>
        <Table
          dataSource={showTableData}
          columns={columns}
          rowSelection={rowSelection}
          bordered={true}
          pagination={{
            ...pagination,
            total: total,
            showSizeChanger: true,
            showQuickJumper: true,
            showTotal: () => `共${total}条`,
          }}
          onChange={handleTableChange}
          rowKey="name"
          tableLayout="fixed"
          scroll={{ x: '100%' }}
        />
      </div>
      <div className={styles['model-metrics__chart']}>
        {chartData &&
          Object.keys(chartData).map((key) => (
            <MetricsChart key={key} name={key} chartData={chartData[key]}></MetricsChart>
          ))}
      </div>
    </div>
  );
}

export default ModelMetrics;
