import KFIcon from '@/components/KFIcon';
import { AutoMLTaskType, ExperimentStatus } from '@/enums';
import LogList from '@/pages/Experiment/components/LogList';
import { getExperimentInsReq } from '@/services/autoML';
import { NodeStatus } from '@/types';
import { parseJsonText } from '@/utils';
import { safeInvoke } from '@/utils/functional';
import { to } from '@/utils/promise';
import { useParams } from '@umijs/max';
import { Tabs } from 'antd';
import { useEffect, useRef, useState } from 'react';
import AutoMLBasic from '../components/AutoMLBasic';
import ExperimentHistory from '../components/ExperimentHistory';
import ExperimentResult from '../components/ExperimentResult';
import { AutoMLData, AutoMLInstanceData } from '../types';
import styles from './index.less';

enum TabKeys {
  Params = 'params',
  Log = 'log',
  Result = 'result',
  History = 'history',
}

function AutoMLInstance() {
  const [activeTab, setActiveTab] = useState<string>(TabKeys.Params);
  const [autoMLInfo, setAutoMLInfo] = useState<AutoMLData | undefined>(undefined);
  const [instanceInfo, setInstanceInfo] = useState<AutoMLInstanceData | undefined>(undefined);
  const params = useParams();
  // const autoMLId = safeInvoke(Number)(params.autoMLId);
  const instanceId = safeInvoke(Number)(params.id);
  const evtSourceRef = useRef<EventSource | null>(null);

  useEffect(() => {
    if (instanceId) {
      getExperimentInsInfo();
    }
    return () => {
      closeSSE();
    };
  }, []);

  // 获取实验实例详情
  const getExperimentInsInfo = async () => {
    const [res] = await to(getExperimentInsReq(instanceId));
    if (res && res.data) {
      const info = res.data as AutoMLInstanceData;
      const { param, node_status, argo_ins_name, argo_ins_ns, status } = info;
      // 解析配置参数
      const paramJson = parseJsonText(param);
      if (paramJson) {
        setAutoMLInfo(paramJson);
      }
      // 进行节点状态
      const nodeStatusJson = parseJsonText(node_status);
      if (nodeStatusJson) {
        Object.keys(nodeStatusJson).forEach((key) => {
          if (key.startsWith('auto-ml')) {
            const value = nodeStatusJson[key];
            info.nodeStatus = value;
          }
        });
      }
      setInstanceInfo(info);
      // 运行中或者等待中，开启 SSE
      if (status === ExperimentStatus.Pending || status === ExperimentStatus.Running) {
        setupSSE(argo_ins_name, argo_ins_ns);
      }
    }
  };

  const setupSSE = (name: string, namespace: string) => {
    let { origin } = location;
    if (process.env.NODE_ENV === 'development') {
      origin = 'http://172.20.32.181:31213';
    }
    const params = encodeURIComponent(`metadata.namespace=${namespace},metadata.name=${name}`);
    const evtSource = new EventSource(
      `${origin}/api/v1/realtimeStatus?listOptions.fieldSelector=${params}`,
      { withCredentials: false },
    );
    evtSource.onmessage = (event) => {
      const data = event?.data;
      if (!data) {
        return;
      }
      const dataJson = parseJsonText(data);
      if (dataJson) {
        const nodes = dataJson?.result?.object?.status?.nodes;
        if (nodes) {
          const statusData = Object.values(nodes).find((node: any) =>
            node.displayName.startsWith('auto-ml'),
          ) as NodeStatus;
          if (statusData) {
            setInstanceInfo((prev) => ({
              ...(prev as AutoMLInstanceData),
              nodeStatus: statusData,
            }));

            // 实验结束，关闭 SSE
            if (
              statusData.phase !== ExperimentStatus.Pending &&
              statusData.phase !== ExperimentStatus.Running
            ) {
              closeSSE();
              getExperimentInsInfo();
            }
          }
        }
      }
    };
    evtSource.onerror = (error) => {
      console.error('SSE error: ', error);
    };

    evtSourceRef.current = evtSource;
  };

  const closeSSE = () => {
    if (evtSourceRef.current) {
      evtSourceRef.current.close();
      evtSourceRef.current = null;
    }
  };

  const basicTabItems = [
    {
      key: TabKeys.Params,
      label: '基本信息',
      icon: <KFIcon type="icon-jibenxinxi" />,
      children: (
        <AutoMLBasic
          className={styles['auto-ml-instance__basic']}
          info={autoMLInfo}
          runStatus={instanceInfo?.nodeStatus}
          isInstance
        />
      ),
    },
    {
      key: TabKeys.Log,
      label: '日志',
      icon: <KFIcon type="icon-rizhi1" />,
      children: (
        <div className={styles['auto-ml-instance__log']}>
          {instanceInfo && instanceInfo.nodeStatus && (
            <LogList
              instanceName={instanceInfo.argo_ins_name}
              instanceNamespace={instanceInfo.argo_ins_ns}
              pipelineNodeId={instanceInfo.nodeStatus.displayName}
              workflowId={instanceInfo.nodeStatus.id}
              instanceNodeStartTime={instanceInfo.nodeStatus.startedAt}
              instanceNodeStatus={instanceInfo.nodeStatus.phase as ExperimentStatus}
            ></LogList>
          )}
        </div>
      ),
    },
  ];

  const resultTabItems = [
    {
      key: TabKeys.Result,
      label: '实验结果',
      icon: <KFIcon type="icon-shiyanjieguo1" />,
      children: (
        <ExperimentResult fileUrl={instanceInfo?.result_path} imageUrl={instanceInfo?.img_path} />
      ),
    },
    {
      key: TabKeys.History,
      label: 'Trial 列表',
      icon: <KFIcon type="icon-Trialliebiao" />,
      children: (
        <ExperimentHistory
          fileUrl={instanceInfo?.run_history_path}
          isClassification={autoMLInfo?.task_type === AutoMLTaskType.Classification}
        />
      ),
    },
  ];

  const tabItems =
    instanceInfo?.status === ExperimentStatus.Succeeded
      ? [...basicTabItems, ...resultTabItems]
      : basicTabItems;

  return (
    <div className={styles['auto-ml-instance']}>
      <Tabs
        className={styles['auto-ml-instance__tabs']}
        items={tabItems}
        activeKey={activeTab}
        onChange={setActiveTab}
      />
    </div>
  );
}

export default AutoMLInstance;
