/*
 * @Author: 赵伟
 * @Date: 2024-04-16 13:58:08
 * @Description: 模型部署列表
 */
import CommonTableCell from '@/components/CommonTableCell';
import DateTableCell from '@/components/DateTableCell';
import KFIcon from '@/components/KFIcon';
import PageTitle from '@/components/PageTitle';
import { ModelDeploymentStatus, modelDeploymentStatusOptions } from '@/enums';
import { useCacheState } from '@/hooks/pageCacheState';
import {
  deleteModelDeploymentReq,
  getModelDeploymentListReq,
  stopModelDeploymentReq,
} from '@/services/modelDeployment';
import themes from '@/styles/theme.less';
import { to } from '@/utils/promise';
import { modelDeploymentInfoKey, setSessionStorageItem } from '@/utils/sessionStorage';
import { modalConfirm } from '@/utils/ui';
import { useNavigate } 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 { pick } from 'lodash';
import { useEffect, useState } from 'react';
import ModelDeploymentStatusCell from '../components/ModelDeployStatusCell';
import { ModelDeploymentData, ModelDeploymentOperationType } from '../types';
import styles from './index.less';

function ModelDeployment() {
  const navigate = useNavigate();
  const { message } = App.useApp();
  const [cacheState, setCacheState] = useCacheState();
  const [searchStatus, setSearchStatus] = useState(cacheState?.searchStatus ?? '');
  const [searchText, setSearchText] = useState(cacheState?.searchText);
  const [inputText, setInputText] = useState(cacheState?.searchText);
  const [tableData, setTableData] = useState<ModelDeploymentData[]>([]);
  const [total, setTotal] = useState(0);
  const [pagination, setPagination] = useState<TablePaginationConfig>(
    cacheState?.pagination ?? {
      current: 1,
      pageSize: 10,
    },
  );

  useEffect(() => {
    getModelDeploymentList();
  }, [pagination, searchText, searchStatus]);

  // 获取模型部署列表
  const getModelDeploymentList = async () => {
    const params: Record<string, any> = {
      page: pagination.current!,
      size: pagination.pageSize,
      service_name: searchText,
      status: searchStatus,
    };
    const [res] = await to(getModelDeploymentListReq(params));
    if (res && res.data) {
      const { service_list = [], total = 0 } = res.data;
      setTableData(service_list);
      setTotal(total);
    }
  };

  // 删除模型部署
  const deleteModelDeploy = async (record: ModelDeploymentData) => {
    const params = pick(record, ['service_id', 'service_ins_id']);
    const [res] = await to(deleteModelDeploymentReq(params));
    if (res) {
      message.success('删除成功');
      // 如果是一页的唯一数据，删除时，请求第一页的数据
      // 否则直接刷新这一页的数据
      // 避免回到第一页
      if (tableData.length > 1) {
        setPagination((prev) => ({
          ...prev,
          current: 1,
        }));
      } else {
        getModelDeploymentList();
      }
    }
  };

  // 停止模型部署
  const stopModelDeploy = async (record: ModelDeploymentData) => {
    const params = pick(record, ['service_id', 'service_ins_id']);
    const [res] = await to(stopModelDeploymentReq(params));
    if (res) {
      message.success('操作成功');
      getModelDeploymentList();
    }
  };

  // 搜索
  const onSearch: SearchProps['onSearch'] = (value) => {
    setSearchText(value);
  };

  // 处理删除
  const handleModelDeployDelete = (record: ModelDeploymentData) => {
    modalConfirm({
      title: '删除后，该模型部署将不可恢复',
      content: '是否确认删除?',
      onOk: () => {
        deleteModelDeploy(record);
      },
    });
  };

  // 处理停止
  const handleModelDeployStop = async (record: ModelDeploymentData) => {
    modalConfirm({
      content: '是否确认停止?',
      onOk: () => {
        stopModelDeploy(record);
      },
    });
  };

  // 创建、更新、重启模型部署
  const createModelDeployment = (
    type: ModelDeploymentOperationType,
    record?: ModelDeploymentData,
  ) => {
    setSessionStorageItem(
      modelDeploymentInfoKey,
      {
        ...record,
        operationType: type,
      },
      true,
    );

    setCacheState({
      pagination,
      searchText,
      searchStatus,
    });

    navigate(`/modelDeployment/create`);
  };

  // 查看详情
  const toDetail = (record: ModelDeploymentData) => {
    setSessionStorageItem(modelDeploymentInfoKey, record, true);

    setCacheState({
      pagination,
      searchText,
      searchStatus,
    });

    navigate(`/modelDeployment/info/${record.service_id}`);
  };

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

  const columns: TableProps<ModelDeploymentData>['columns'] = [
    {
      title: '序号',
      dataIndex: 'index',
      key: 'index',
      width: '20%',
      render(_text, _record, index) {
        return <span>{(pagination.current! - 1) * pagination.pageSize! + index + 1}</span>;
      },
    },
    {
      title: '服务名称',
      dataIndex: 'service_name',
      key: 'service_name',
      width: '20%',
      render: (text, record) => {
        return (
          <a className="kf-table-row-link" onClick={() => toDetail(record)}>
            {text}
          </a>
        );
      },
    },
    {
      title: '模型',
      dataIndex: ['model', 'show_value'],
      key: 'model',
      width: '20%',
      render: CommonTableCell(),
    },
    {
      title: '状态',
      dataIndex: 'status',
      key: 'status',
      width: '20%',
      render: ModelDeploymentStatusCell,
    },
    {
      title: '创建人',
      dataIndex: 'created_by',
      key: 'created_by',
      render: CommonTableCell(),
      width: '20%',
    },
    {
      title: '更新时间',
      dataIndex: 'update_time',
      key: 'update_time',
      width: '20%',
      render: DateTableCell,
    },
    {
      title: '操作',
      dataIndex: 'operation',
      width: 250,
      key: 'operation',
      render: (_: any, record: ModelDeploymentData) => (
        <div>
          <Button
            type="link"
            size="small"
            key="edit"
            icon={<KFIcon type="icon-bianji" />}
            onClick={() => createModelDeployment(ModelDeploymentOperationType.Update, record)}
          >
            更新
          </Button>
          {(record.status === ModelDeploymentStatus.Failed ||
            record.status === ModelDeploymentStatus.Stopped) && (
            <Button
              type="link"
              size="small"
              key="run"
              icon={<KFIcon type="icon-yunhang" />}
              onClick={() => createModelDeployment(ModelDeploymentOperationType.Restart, record)}
            >
              重启
            </Button>
          )}
          {(record.status === ModelDeploymentStatus.Running ||
            record.status === ModelDeploymentStatus.Init ||
            record.status === ModelDeploymentStatus.Pending) && (
            <Button
              type="link"
              size="small"
              key="stop"
              icon={<KFIcon type="icon-tingzhi" />}
              onClick={() => handleModelDeployStop(record)}
            >
              停止
            </Button>
          )}
          <ConfigProvider
            theme={{
              token: {
                colorLink: themes['warningColor'],
              },
            }}
          >
            <Button
              type="link"
              size="small"
              key="remove"
              icon={<KFIcon type="icon-shanchu" />}
              onClick={() => handleModelDeployDelete(record)}
            >
              删除
            </Button>
          </ConfigProvider>
        </div>
      ),
    },
  ];

  return (
    <div className={styles['model-deployment']}>
      <PageTitle title="模型列表"></PageTitle>
      <div className={styles['model-deployment__content']}>
        <div className={styles['model-deployment__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) => setSearchStatus(value)}
            options={modelDeploymentStatusOptions}
            value={searchStatus}
            allowClear
          ></Select>
          <Button
            style={{ marginLeft: '20px' }}
            type="default"
            onClick={() => createModelDeployment(ModelDeploymentOperationType.Create)}
            icon={<KFIcon type="icon-xinjian2" />}
          >
            创建推理服务
          </Button>
          <Button
            style={{ marginRight: 0, marginLeft: 'auto' }}
            type="default"
            onClick={getModelDeploymentList}
            icon={<KFIcon type="icon-shuaxin" />}
          >
            刷新
          </Button>
        </div>
        <div
          className={classNames(
            'vertical-scroll-table',
            styles['model-deployment__content__table'],
          )}
        >
          <Table
            dataSource={tableData}
            columns={columns}
            scroll={{ y: 'calc(100% - 55px)' }}
            pagination={{
              ...pagination,
              total: total,
              showSizeChanger: true,
              showQuickJumper: true,
              showTotal: () => `共${total}条`,
            }}
            onChange={handleTableChange}
            rowKey="service_id"
          />
        </div>
      </div>
    </div>
  );
}

export default ModelDeployment;
