import createExperimentIcon from '@/assets/img/create-experiment.png';
import editExperimentIcon from '@/assets/img/edit-experiment.png';
import KFModal from '@/components/KFModal';
import { type PipelineGlobalParam } from '@/types';
import { to } from '@/utils/promise';
import { Button, Form, Input, Radio, Select, Typography, type FormRule } from 'antd';
import { useState } from 'react';
import styles from './index.less';

type FormData = {
  name?: string;
  description?: string;
  workflow_id?: string | number;
  global_param?: PipelineGlobalParam[];
};

type AddExperimentModalProps = {
  isAdd: boolean;
  open: boolean;
  onCancel: () => void;
  onFinish: (values: any, isRun: boolean) => void;
  workflowList: Workflow[];
  initialValues: FormData;
};

interface Workflow {
  id: string | number;
  name: string;
  global_param?: PipelineGlobalParam[] | null;
}

// 根据参数设置输入组件
export const getParamComponent = (paramType: number): JSX.Element => {
  // 防止后台返回不是 number 类型
  if (Number(paramType) === 3) {
    return (
      <Radio.Group>
        <Radio value={1}>是</Radio>
        <Radio value={0}>否</Radio>
      </Radio.Group>
    );
  }
  // if (isSensitive && Number(isSensitive) === 1) {
  //   return <Input.Password placeholder="请输入值" visibilityToggle={false} allowClear />;
  // }
  return <Input placeholder="请输入值" allowClear />;
};

// 根据参数设置校验规则
export const getParamRules = (paramType: number, required: boolean = false): FormRule[] => {
  const rules = [];
  // 防止后台返回不是 number 类型
  if (Number(paramType) === 2) {
    rules.push({
      pattern: /^-?((0(\.0*[1-9]\d*)?)|([1-9]\d*(\.\d+)?))$/,
      message: '整型必须是数字',
    });
  }
  if (required) {
    rules.push({ required: true, message: '请输入值' });
  }
  return rules;
};

// 根据参数设置 label
export const getParamLabel = (param: PipelineGlobalParam): React.ReactNode => {
  const paramTypes: Readonly<Record<number, string>> = {
    1: '字符串',
    2: '整型',
    3: '布尔类型',
  };
  const label = param.param_name + `（${paramTypes[param.param_type]}）`;
  return <Typography.Text ellipsis={{ tooltip: label }}>{label}</Typography.Text>;
};

function AddExperimentModal({
  isAdd,
  open,
  onCancel,
  onFinish,
  workflowList = [],
  initialValues = {},
}: AddExperimentModalProps) {
  const modalTitle = isAdd ? '新建实验' : '配置实验';
  const modalIcon = isAdd ? createExperimentIcon : editExperimentIcon;
  const workflowDisabled = isAdd ? false : true;
  const [globalParam, setGlobalParam] = useState<PipelineGlobalParam[]>(
    initialValues.global_param || [],
  );
  const [form] = Form.useForm();

  const tailLayout = {
    labelCol: { span: 24 },
    wrapperCol: { span: 24 },
  };

  const layout = {
    labelCol: { span: 5 },
    wrapperCol: { span: 19 },
  };

  const paramLayout = {
    labelCol: { span: 6 },
    wrapperCol: { span: 18 },
  };

  // 除了流水线选择发生变化
  const handleWorkflowChange = (id: string | number) => {
    const pipeline: Workflow | undefined = workflowList.find((v) => v.id === id);
    if (pipeline && pipeline.global_param) {
      setGlobalParam(pipeline.global_param);
      form.setFieldValue('global_param', pipeline.global_param);
    } else {
      setGlobalParam([]);
      form.setFieldValue('global_param', []);
    }
  };

  const handleRun = async (run: boolean) => {
    const [values, error] = await to(form.validateFields());
    if (!error && values) {
      onFinish(values, run);
    }
  };

  const footer = [
    <Button key="cancel" onClick={onCancel}>
      取消
    </Button>,
    <Button key="submit" type={isAdd ? 'primary' : 'default'} onClick={() => handleRun(false)}>
      确定
    </Button>,
  ];
  if (!isAdd) {
    footer.push(
      <Button key="run" type="primary" onClick={() => handleRun(true)}>
        确定并运行
      </Button>,
    );
  }

  return (
    <KFModal
      className={styles['add-experiment-modal']}
      title={modalTitle}
      image={modalIcon}
      open={open}
      onCancel={onCancel}
      destroyOnClose={true}
      width={825}
      footer={footer}
    >
      <Form
        name="form"
        layout="horizontal"
        initialValues={initialValues}
        autoComplete="off"
        form={form}
        {...layout}
        labelAlign="left"
      >
        <Form.Item
          label="实验名称"
          name="name"
          rules={[{ required: true, message: '请输入实验名称' }]}
        >
          <Input placeholder="请输入实验名称" maxLength={64} showCount allowClear />
        </Form.Item>
        <Form.Item
          label="实验描述"
          name="description"
          rules={[{ required: true, message: '请输入实验描述' }]}
          style={{ marginBottom: '48px' }}
        >
          <Input.TextArea
            placeholder="请输入实验描述"
            maxLength={128}
            autoSize={{ minRows: 2, maxRows: 5 }}
            showCount
            allowClear
          />
        </Form.Item>
        <Form.Item
          label="选择流水线模板"
          name="workflow_id"
          rules={[{ required: true, message: '请选择流水线模板' }]}
        >
          <Select
            disabled={workflowDisabled}
            placeholder="请选择流水线模板"
            onChange={handleWorkflowChange}
          >
            {Array.isArray(workflowList)
              ? workflowList.map((item) => {
                  return (
                    <Select.Option key={item.id} value={item.id}>
                      {item.name}
                    </Select.Option>
                  );
                })
              : null}
          </Select>
        </Form.Item>
        {globalParam.length > 0 && (
          <Form.Item label="运行参数" tooltip="展示关联的流水线的参数" {...tailLayout}>
            <div className={styles.global_param_item}>
              <Form.List name="global_param">
                {(fields) =>
                  fields.map(({ key, name, ...restField }) => (
                    <Form.Item
                      {...restField}
                      {...paramLayout}
                      key={key}
                      label={getParamLabel(globalParam[name])}
                      name={[name, 'param_value']}
                      rules={getParamRules(globalParam[name]['param_type'], true)}
                    >
                      {getParamComponent(globalParam[name]['param_type'])}
                    </Form.Item>
                  ))
                }
              </Form.List>
            </div>
          </Form.Item>
        )}
      </Form>
    </KFModal>
  );
}

export default AddExperimentModal;
