/*
 * @Author: 赵伟
 * @Date: 2024-04-16 13:58:08
 * @Description: 模型部署列表
 */
import BasicInfo from '@/components/BasicInfo';
import KFIcon from '@/components/KFIcon';
import PageTitle from '@/components/PageTitle';
import SubAreaTitle from '@/components/SubAreaTitle';
import { ServiceRunStatus, serviceStatusOptions } from '@/enums';
import { useCacheState } from '@/hooks/useCacheState';
import { useComputingResource } from '@/hooks/useComputingResource';
import {
  deleteServiceVersionReq,
  getServiceInfoReq,
  getServiceVersionsReq,
  stopServiceVersionReq,
} from '@/services/modelDeployment';
import themes from '@/styles/theme.less';
import { formatDate } from '@/utils/date';
import { openAntdModal } from '@/utils/modal';
import { to } from '@/utils/promise';
import SessionStorage from '@/utils/sessionStorage';
import tableCellRender, { TableCellValueType } from '@/utils/table';
import { modalConfirm } from '@/utils/ui';
import { useNavigate, useParams } from '@umijs/max';
import {
  App,
  Button,
  ConfigProvider,
  Input,
  Select,
  Table,
  type TablePaginationConfig,
  type TableProps,
} from 'antd';
import { type SearchProps } from 'antd/es/input';
import classNames from 'classnames';
import { useCallback, useEffect, useState } from 'react';
import ServiceRunStatusCell from '../components/ModelDeployStatusCell';
import VersionCompareModal from '../components/VersionCompareModal';
import {
  CreateServiceVersionFrom,
  ServiceData,
  ServiceOperationType,
  ServiceVersionData,
} from '../types';
import styles from './index.less';

const allServiceStatusOptions = [{ label: '全部', value: '' }, ...serviceStatusOptions];

function ServiceInfo() {
  const navigate = useNavigate();
  const { message } = App.useApp();
  const [cacheState, setCacheState] = useCacheState();
  const [serviceStatus, setServiceStatus] = useState(cacheState?.serviceStatus ?? '');
  const [searchText, setSearchText] = useState(cacheState?.searchText);
  const [inputText, setInputText] = useState(cacheState?.searchText);
  const [tableData, setTableData] = useState<ServiceVersionData[]>([]);
  const [total, setTotal] = useState(0);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [pagination, setPagination] = useState<TablePaginationConfig>(
    cacheState?.pagination ?? {
      current: 1,
      pageSize: 10,
    },
  );
  const params = useParams();
  const serviceId = params.serviceId;
  const [serviceInfo, setServiceInfo] = useState<ServiceData | undefined>(undefined);
  const basicInfo = [
    {
      label: '服务名称',
      value: serviceInfo?.service_name,
    },
    {
      label: '服务描述',
      value: serviceInfo?.description,
    },
    {
      label: '版本数量',
      value: serviceInfo?.version_count,
    },
    {
      label: '创建时间',
      value: serviceInfo?.create_time,
      format: formatDate,
    },
  ];
  const getResourceDescription = useComputingResource()[1];

  // 获取服务详情
  const getServiceInfo = useCallback(async () => {
    const [res] = await to(getServiceInfoReq(serviceId));
    if (res && res.data) {
      setServiceInfo(res.data);
    }
  }, [serviceId]);

  // 获取服务版本列表
  const getServiceVersions = useCallback(async () => {
    const params: Record<string, any> = {
      page: pagination.current! - 1,
      size: pagination.pageSize,
      version: searchText || undefined,
      run_state: serviceStatus,
      service_id: serviceId,
    };
    const [res] = await to(getServiceVersionsReq(params));
    if (res && res.data) {
      const { content = [], totalElements = 0 } = res.data;
      content.forEach((item: ServiceVersionData) => {
        if (item.model && !item.model.show_value) {
          item.model.show_value = `${item.model.name}:${item.model.version}`;
        }
      });
      setTableData(content);
      setTotal(totalElements);
    }
  }, [pagination, serviceStatus, searchText, serviceId]);

  useEffect(() => {
    getServiceInfo();
  }, [getServiceInfo]);

  useEffect(() => {
    getServiceVersions();
  }, [getServiceVersions]);

  // 删除模型部署
  const deleteServiceVersion = async (record: ServiceVersionData) => {
    const [res] = await to(deleteServiceVersionReq(record.id));
    if (res) {
      message.success('删除成功');
      // 如果是一页的唯一数据，删除后，请求第一页的数据
      // 否则直接刷新这一页的数据
      setPagination((prev) => {
        return {
          ...prev,
          current: tableData.length === 1 ? Math.max(1, prev.current! - 1) : prev.current,
        };
      });
      getServiceInfo();
    }
  };

  // 停止模型部署
  const stopServiceVersion = async (record: ServiceVersionData) => {
    const [res] = await to(stopServiceVersionReq(record.id));
    if (res) {
      message.success('操作成功');
      getServiceVersions();
    }
  };

  // 搜索
  const onSearch: SearchProps['onSearch'] = (value) => {
    setSearchText(value);
    setPagination((prev) => ({
      ...prev,
      current: 1,
    }));
  };

  // 处理删除
  const handleServiceVersionDelete = (record: ServiceVersionData) => {
    modalConfirm({
      title: '删除后，该服务版本将不可恢复',
      content: '是否确认删除?',
      onOk: () => {
        deleteServiceVersion(record);
      },
    });
  };

  // 处理停止
  const handleServiceVersionStop = async (record: ServiceVersionData) => {
    modalConfirm({
      title: '是否确认停止该服务?',
      isDelete: false,
      onOk: () => {
        stopServiceVersion(record);
      },
    });
  };

  // 创建、更新、重启服务版本
  const createServiceVersion = (type: ServiceOperationType, record?: ServiceVersionData) => {
    SessionStorage.setItem(
      SessionStorage.serviceVersionInfoKey,
      {
        ...record,
        operationType: type,
        lastPage: CreateServiceVersionFrom.ServiceInfo,
      },
      true,
    );

    setCacheState({
      pagination,
      searchText,
      serviceStatus: serviceStatus,
    });

    if (type === ServiceOperationType.Update) {
      navigate('updateVersion');
    } else if (type === ServiceOperationType.Restart) {
      navigate('restartVersion');
    } else {
      navigate('createVersion');
    }
  };

  // 查看详情
  const toDetail = (record: ServiceVersionData) => {
    setCacheState({
      pagination,
      searchText,
      serviceStatus: serviceStatus,
    });

    navigate(`versionInfo/${record.id}`);
  };

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

  // 版本对比
  const handleVersionCompare = () => {
    if (selectedRowKeys.length !== 2) {
      message.error('请选择两个版本进行对比');
      return;
    }

    openAntdModal(VersionCompareModal, {
      version1: selectedRowKeys[0] as string,
      version2: selectedRowKeys[1] as string,
    });
  };

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

  const columns: TableProps<ServiceVersionData>['columns'] = [
    {
      title: '序号',
      dataIndex: 'index',
      key: 'index',
      width: '20%',
      render: tableCellRender(false, TableCellValueType.Index, {
        page: pagination.current! - 1,
        pageSize: pagination.pageSize!,
      }),
    },
    {
      title: '服务版本',
      dataIndex: 'version',
      key: 'version',
      width: '20%',
      render: tableCellRender(),
    },
    {
      title: '模型版本',
      dataIndex: ['model', 'show_value'],
      key: 'model',
      width: '20%',
      render: tableCellRender(true),
    },
    {
      title: '镜像版本',
      dataIndex: ['image', 'showValue'],
      key: 'image',
      width: '20%',
      render: tableCellRender(true),
    },
    {
      title: '副本数量',
      dataIndex: 'replicas',
      key: 'replicas',
      render: tableCellRender(),
      width: '20%',
    },
    {
      title: '资源规格',
      dataIndex: 'computing_resource_id',
      key: 'computing_resource_id',
      width: '20%',
      render: tableCellRender(true, TableCellValueType.Custom, {
        format: getResourceDescription,
      }),
    },
    {
      title: '状态',
      dataIndex: 'run_state',
      key: 'run_state',
      width: '20%',
      render: ServiceRunStatusCell,
    },
    {
      title: '操作',
      dataIndex: 'operation',
      width: 320,
      key: 'operation',
      render: (_: any, record: ServiceVersionData) => (
        <div>
          <Button
            type="link"
            size="small"
            key="info"
            icon={<KFIcon type="icon-xiangqing" />}
            onClick={() => toDetail(record)}
          >
            详情
          </Button>
          <Button
            type="link"
            size="small"
            key="edit"
            icon={<KFIcon type="icon-bianji" />}
            onClick={() => createServiceVersion(ServiceOperationType.Update, record)}
          >
            更新
          </Button>
          {(record.run_state === ServiceRunStatus.Failed ||
            record.run_state === ServiceRunStatus.Stopped) && (
            <Button
              type="link"
              size="small"
              key="run"
              icon={<KFIcon type="icon-yunhang" />}
              onClick={() => createServiceVersion(ServiceOperationType.Restart, record)}
            >
              重启
            </Button>
          )}
          {(record.run_state === ServiceRunStatus.Running ||
            record.run_state === ServiceRunStatus.Init ||
            record.run_state === ServiceRunStatus.Pending) && (
            <Button
              type="link"
              size="small"
              key="stop"
              icon={<KFIcon type="icon-tingzhi" />}
              onClick={() => handleServiceVersionStop(record)}
            >
              停止
            </Button>
          )}

          <ConfigProvider
            theme={{
              token: {
                colorLink: themes['warningColor'],
              },
            }}
          >
            <Button
              type="link"
              size="small"
              key="remove"
              icon={<KFIcon type="icon-shanchu" />}
              onClick={() => handleServiceVersionDelete(record)}
            >
              删除
            </Button>
          </ConfigProvider>
        </div>
      ),
    },
  ];

  return (
    <div className={styles['service-info']}>
      <PageTitle title="服务详情"></PageTitle>
      <div className={styles['service-info__content']}>
        <SubAreaTitle
          title="基本信息"
          image={require('@/assets/img/mirror-basic.png')}
          style={{ marginBottom: '26px', flex: 'none' }}
        ></SubAreaTitle>
        <BasicInfo
          datas={basicInfo}
          labelWidth={66}
          labelAlign="justify"
          style={{ flex: 'none' }}
        ></BasicInfo>
        <SubAreaTitle
          title="服务版本"
          image={require('@/assets/img/service-version.png')}
          style={{ margin: '40px 0 26px', flex: 'none' }}
        ></SubAreaTitle>
        <div className={styles['service-info__content__filter']}>
          <Input.Search
            placeholder="按服务版本筛选"
            onSearch={onSearch}
            onChange={(e) => setInputText(e.target.value)}
            style={{ width: 300 }}
            value={inputText}
            allowClear
          />
          <Select
            style={{ width: 100, marginLeft: '20px' }}
            placeholder="请选择"
            onChange={(value) => setServiceStatus(value ?? '')}
            options={allServiceStatusOptions}
            value={serviceStatus}
            allowClear
          ></Select>
          <Button
            style={{ marginRight: '15px', marginLeft: 'auto' }}
            type="default"
            onClick={() => createServiceVersion(ServiceOperationType.Create)}
            icon={<KFIcon type="icon-xinjian2" />}
          >
            新增服务版本
          </Button>
          <Button style={{ marginRight: '15px' }} type="default" onClick={handleVersionCompare}>
            版本对比
          </Button>
          <Button
            style={{ marginRight: 0 }}
            type="default"
            onClick={getServiceVersions}
            icon={<KFIcon type="icon-shuaxin" />}
          >
            刷新
          </Button>
        </div>
        <div
          className={classNames('vertical-scroll-table', styles['service-info__content__table'])}
        >
          <Table
            dataSource={tableData}
            columns={columns}
            scroll={{ y: 'calc(100% - 55px)' }}
            pagination={{
              ...pagination,
              total: total,
              showSizeChanger: true,
              showQuickJumper: true,
              showTotal: () => `共${total}条`,
            }}
            onChange={handleTableChange}
            rowSelection={rowSelection}
            rowKey="id"
          />
        </div>
      </div>
    </div>
  );
}

export default ServiceInfo;
