/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import React, { Component, Fragment } from "react";
import {
  Modal,
  Form,
  Select,
  Input,
  Switch,
  Button,
  message,
  Tooltip,
  Popconfirm,
  Row,
  Col,
  Card,
  Icon,
  InputNumber,
  DatePicker,
  TimePicker,
  Tabs,
  Divider,
} from "antd";
import { connect } from "dva";
import classnames from "classnames";
import styles from "../index.less";
import { getIntlContent } from "../../../utils/IntlUtils";
import SelectorCopy from "./SelectorCopy";
import {
  findKeyByValue,
  formatDate,
  formatTime,
  formatDateString,
  formatTimeString,
} from "../../../utils/utils";
import DiscoveryImportModal from "../Discovery/DiscoveryImportModal";
import EditableFormTable from "../Discovery/DiscoveryUpstreamTable.js";

const { Item } = Form;
const { TabPane } = Tabs;
const { Option } = Select;
const { confirm } = Modal;

const formItemLayout = {
  labelCol: { sm: { span: 3 } },
  wrapperCol: { sm: { span: 21 } },
};
const formCheckLayout = {
  labelCol: { sm: { span: 18 } },
  wrapperCol: { sm: { span: 4 } },
};
const isDivideUpstreamsRequiresForPlugin = (pluginId) => {
  // 8:   springCloud
  return ["8"].includes(pluginId);
};

let id = 0;

@connect(({ pluginHandle, global, shenyuDict, discovery }) => ({
  pluginHandle,
  platform: global.platform,
  shenyuDict,
  discovery,
}))
class AddModal extends Component {
  constructor(props) {
    super(props);
    const { handle, pluginId } = props;
    let selectValue = `${props.type}` || null;
    let data = {};
    if (handle) {
      try {
        data = JSON.parse(handle);
      } catch (e) {
        // eslint-disable-next-line no-console
        console.error(e);
      }
    }

    const { divideUpstreams = [], gray = false, serviceId = "" } = data;
    const {
      discoveryUpstreams = [],
      isDiscovery,
      isAdd = true,
      discoveryConfig = {},
    } = this.props;

    if (isDivideUpstreamsRequiresForPlugin(pluginId)) {
      id = divideUpstreams.length;
    }

    this.state = {
      selectValue,
      gray,
      serviceId,
      divideUpstreams,
      visible: false,
      pluginHandleList: [],
      upstreams: discoveryUpstreams,
      recordCount: discoveryUpstreams ? discoveryUpstreams.length : 0,
      discoveryHandler: null,
      defaultValueList: null,
      configPropsJson: {},
      selectedDiscoveryValue: "local",
      showDiscoveryImportModal: false,
      importedDiscoveryId: "",
    };

    this.initSelectorCondition(props);

    if (isDiscovery && !isAdd) {
      this.state.configPropsJson = JSON.parse(discoveryConfig.props);
      this.state.selectedDiscoveryValue = discoveryConfig.discoveryType;
    }
    this.editableFormTableRef = React.createRef();
  }

  componentDidMount() {
    const { dispatch, pluginId, handle, multiSelectorHandle, isDiscovery } =
      this.props;
    this.setState({ pluginHandleList: [] });
    let type = 1;
    this.initDics();

    dispatch({
      type: "discovery/fetchEnumType",
    });

    dispatch({
      type: "pluginHandle/fetchByPluginId",
      payload: {
        pluginId,
        type,
        handle,
        isHandleArray: multiSelectorHandle,
        callBack: (pluginHandles) => {
          this.setPluginHandleList(pluginHandles);
          if (isDiscovery && Object.keys(pluginHandles).length > 0) {
            const filteredArray = pluginHandles[0].filter(
              (item) => item.field !== "discoveryHandler",
            );

            const handlerArray = pluginHandles[0].filter(
              (item) => item.field === "discoveryHandler",
            );
            this.setState({ discoveryHandler: handlerArray });

            pluginHandles[0] = filteredArray;
            this.setState({ pluginHandleList: pluginHandles });

            if (handlerArray.length !== 0) {
              let defaultValue = handlerArray[0].defaultValue;
              this.setState({ defaultValueList: defaultValue.split(",") });
            }
          }
        },
      },
    });
  }

  handleSubmit = (e) => {
    if (this.editableFormTableRef.current?.state?.editingKey) {
      confirm({
        title: getIntlContent("SHENYU.DISCOVERY.SELECTOR.EDITING.TITLE"),
        content: getIntlContent("SHENYU.DISCOVERY.SELECTOR.EDITING.CONTENT"),
        okText: getIntlContent("SHENYU.COMMON.SURE"),
        cancelText: getIntlContent("SHENYU.COMMON.CALCEL"),
        onOk: () => {
          this.submitForm(e);
        },
      });
    } else {
      this.submitForm(e);
    }
  };

  handleAdd = () => {
    let { selectorConditions } = this.state;
    selectorConditions.push({
      paramType: "uri",
      operator: "pathPattern",
      paramName: "/",
      paramValue: "",
    });
    this.setState({ selectorConditions }, () => {
      let len = selectorConditions.length || 0;
      let key = `paramTypeValueEn${len - 1}`;

      this.setState({ [key]: true });
    });
  };

  handleDelete = (index) => {
    let { selectorConditions } = this.state;
    if (selectorConditions && selectorConditions.length > 1) {
      selectorConditions.splice(index, 1);
    } else {
      message.destroy();
      message.error("At least one condition");
    }
    this.setState({ selectorConditions });
  };

  handleAddHandle = () => {
    let { pluginHandleList } = this.state;
    let pluginHandle = pluginHandleList[0];
    let toAddPluginHandle = pluginHandle.map((e) => {
      return { ...e, value: null };
    });
    pluginHandleList.push(toAddPluginHandle);
    this.setState({
      pluginHandleList,
    });
  };

  handleDeleteHandle = (index) => {
    let { pluginHandleList } = this.state;
    if (pluginHandleList.length === 1) {
      message.destroy();
      message.error(getIntlContent("SHENYU.PLUGIN.HANDLE.TIP"));
    } else {
      pluginHandleList.splice(index, 1);
      this.setState({ pluginHandleList });
    }
  };

  handleOptions() {
    const { discovery } = this.props;
    if (!discovery || !Array.isArray(discovery.typeEnums)) {
      return [];
    }
    return discovery.typeEnums.map((type) => (
      <Option key={type} value={type.toString()}>
        {type.toString()}
      </Option>
    ));
  }

  submitForm = (e) => {
    e.preventDefault();
    const { form, handleOk, multiSelectorHandle, pluginId, isDiscovery } =
      this.props;
    const {
      selectorConditions,
      selectValue,
      pluginHandleList,
      defaultValueList,
      configPropsJson,
      upstreams,
      importedDiscoveryId,
    } = this.state;
    let handle = [];

    form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        const mySubmit =
          selectValue !== "0" && this.checkConditions(selectorConditions);
        if (mySubmit || selectValue === "0") {
          if (isDiscovery) {
            if (
              new Set(upstreams.map((item) => item.url)).size !==
              upstreams.length
            ) {
              message.destroy();
              message.error(`Contains duplicate urls`);
              return;
            }
            // The discoveryProps refer to the attributes corresponding to each registration center mode
            const discoveryPropsJson = {};
            Object.entries(configPropsJson).forEach(([key]) => {
              discoveryPropsJson[key] = form.getFieldValue(key);
            });
            const discoveryProps = JSON.stringify(discoveryPropsJson);

            // The handler refers to the url, status, weight, protocol, etc. of the discovery module.
            let handler = {};
            if (defaultValueList !== null) {
              defaultValueList.forEach((item) => {
                if (values[item] !== undefined) {
                  handler[values[item]] = item;
                }
              });
            }
            handler = JSON.stringify(handler);

            handleOk({
              ...values,
              sort: Number(values.sort),
              selectorConditions,
              handler,
              discoveryProps,
              upstreams,
              importedDiscoveryId,
            });
          } else {
            pluginHandleList.forEach((handleList, index) => {
              handle[index] = {};
              handleList.forEach((item) => {
                if (isDivideUpstreamsRequiresForPlugin(pluginId)) {
                  const { keys, divideUpstreams } = values;
                  const data = {
                    [item.field]: values[item.field],
                    gray: values.gray,
                  };

                  if (
                    Array.isArray(divideUpstreams) &&
                    divideUpstreams.length
                  ) {
                    data.divideUpstreams = keys.map(
                      (key) => divideUpstreams[key],
                    );
                  }
                  handle[index] = data;
                  delete values[item.field];
                  delete values.divideUpstreams;
                  delete values.gray;
                  delete values.key;
                } else {
                  handle[index][item.field] = values[item.field + index];
                  delete values[item.field + index];
                }
              });
            });
            handleOk({
              ...values,
              handle: multiSelectorHandle
                ? JSON.stringify(handle)
                : JSON.stringify(handle[0]),
              sort: Number(values.sort),
              selectorConditions,
            });
          }
        }
      }
    });
  };

  conditionChange = (index, name, value) => {
    let { selectorConditions } = this.state;
    selectorConditions[index][name] = value;

    if (name === "paramType") {
      let key = `paramTypeValueEn${index}`;
      if (
        value === "uri" ||
        value === "host" ||
        value === "ip" ||
        value === "req_method" ||
        value === "domain"
      ) {
        this.setState({ [key]: true });
        selectorConditions[index].paramName = "/";
      } else {
        this.setState({ [key]: false });
      }
      if (value === "post") {
        selectorConditions[index].paramName = "filedName";
      }
      if (value === "query") {
        selectorConditions[index].paramName = "paramName";
      }
      if (value === "header") {
        selectorConditions[index].paramName = "headerName";
      }
      if (value === "cookie") {
        selectorConditions[index].paramName = "cookieName";
      }
      if (value === "uri") {
        selectorConditions[index].operator = "pathPattern";
      } else if (value === "req_method") {
        selectorConditions[index].operator = "=";
      } else {
        selectorConditions[index].operator = "";
      }
    }

    this.setState({ selectorConditions });
  };

  checkConditions = (selectorConditions) => {
    let result = true;
    if (selectorConditions) {
      selectorConditions.forEach((item, index) => {
        const { paramType, operator, paramName, paramValue } = item;
        if (
          !paramType ||
          !operator ||
          (operator !== "isBlank" && !paramValue)
        ) {
          message.destroy();
          message.error(`Line ${index + 1} condition is incomplete`);
          result = false;
        }
        if (paramType === "uri" || paramType === "host" || paramType === "ip") {
          // aaa
        } else {
          // eslint-disable-next-line no-lonely-if
          if (!paramName) {
            message.destroy();
            message.error(`Line ${index + 1} condition is incomplete`);
            result = false;
          }
        }
      });
    } else {
      message.destroy();
      message.error(`Incomplete condition`);
      result = false;
    }
    return result;
  };

  initSelectorCondition = (props) => {
    const selectorConditions = props.selectorConditions || [
      {
        paramType: "uri",
        operator: "pathPattern",
        paramName: "/",
        paramValue: "",
      },
    ];
    selectorConditions.forEach((item, index) => {
      const { paramType } = item;
      let key = `paramTypeValueEn${index}`;
      if (
        paramType === "uri" ||
        paramType === "host" ||
        paramType === "ip" ||
        paramType === "req_method" ||
        paramType === "domain"
      ) {
        this.state[key] = true;
        selectorConditions[index].paramName = "/";
      } else {
        this.state[key] = false;
      }
    });
    this.state.selectorConditions = selectorConditions;
  };

  initDics = () => {
    this.initDic("operator");
    this.initDic("matchMode");
    this.initDic("paramType");
    this.initDic("discoveryMode");
  };

  initDic = (type) => {
    const { dispatch, isAdd = true } = this.props;
    dispatch({
      type: "shenyuDict/fetchByType",
      payload: {
        type,
        callBack: (dics) => {
          this.state[`${type}Dics`] = dics;
          if (type === "discoveryMode" && isAdd) {
            let configProps = dics.filter(
              (item) => item.dictName === "zookeeper",
            );
            let propsEntries = JSON.parse(configProps[0]?.dictValue || "{}");
            this.setState({ configPropsJson: propsEntries });
          }
        },
      },
    });
  };

  getSelectValue = (value) => {
    this.setState({
      selectValue: value,
    });
  };

  renderPluginHandler = () => {
    const { pluginHandleList, divideUpstreams, gray, serviceId } = this.state;
    const {
      form: { getFieldDecorator, getFieldValue, setFieldsValue },
      multiSelectorHandle,
      pluginId,
      isDiscovery,
    } = this.props;
    const labelWidth = 75;

    if (isDiscovery) {
      return;
    }

    if (isDivideUpstreamsRequiresForPlugin(pluginId)) {
      getFieldDecorator("keys", {
        initialValue: Array.from({
          length: divideUpstreams.length,
        }).map((_, i) => i),
      });
      const keys = getFieldValue("keys");
      const Rule = keys.map((key, index) => (
        <Item
          required
          key={key}
          {...(index === 0
            ? { labelCol: { span: 3 }, wrapperCol: { span: 21 } }
            : { wrapperCol: { span: 21, offset: 3 } })}
          label={index === 0 ? "divideUpstreams" : ""}
        >
          <Card>
            <div
              style={{
                display: "flex",
                alignItems: "center",
                justifycontent: "space-between",
              }}
            >
              <div style={{ flex: 1 }}>
                <Row gutter={30}>
                  <Col span={10}>
                    <Item
                      label="protocol"
                      {...{ labelCol: { span: 9 }, wrapperCol: { span: 15 } }}
                    >
                      {getFieldDecorator(`divideUpstreams[${key}].protocol`, {
                        initialValue: divideUpstreams[key]
                          ? divideUpstreams[key].protocol
                          : "",
                        rules: [
                          {
                            required: true,
                            message: "protocol is required",
                          },
                        ],
                      })(<Input allowClear />)}
                    </Item>
                  </Col>
                  <Col span={14} style={{ marginLeft: "-20px" }}>
                    <Item
                      label="upstreamUrl"
                      {...{ labelCol: { span: 9 }, wrapperCol: { span: 15 } }}
                    >
                      {getFieldDecorator(
                        `divideUpstreams[${key}].upstreamUrl`,
                        {
                          initialValue: divideUpstreams[key]
                            ? divideUpstreams[key].upstreamUrl
                            : "",
                          rules: [
                            {
                              required: true,
                              message: "upstreamUrl is required",
                            },
                          ],
                        },
                      )(<Input allowClear />)}
                    </Item>
                  </Col>
                </Row>
                <Row gutter={30}>
                  <Col span={10}>
                    <Item
                      label="weight"
                      {...{ labelCol: { span: 9 }, wrapperCol: { span: 15 } }}
                    >
                      {getFieldDecorator(`divideUpstreams[${key}].weight`, {
                        initialValue: divideUpstreams[key]
                          ? divideUpstreams[key].weight
                          : "",
                        rules: [
                          {
                            required: true,
                            message: "weight is required",
                          },
                        ],
                      })(
                        <InputNumber
                          min={0}
                          max={100}
                          style={{ width: "100%" }}
                        />,
                      )}
                    </Item>
                  </Col>
                  <Col span={14} style={{ marginLeft: "-20px" }}>
                    <Item
                      label="timestamp"
                      {...{ labelCol: { span: 9 }, wrapperCol: { span: 15 } }}
                    >
                      {getFieldDecorator(`divideUpstreams[${key}].timestamp`, {
                        initialValue: divideUpstreams[key]
                          ? divideUpstreams[key].timestamp
                          : "",
                        rules: [
                          {
                            required: true,
                            message: "timestamp is required",
                          },
                        ],
                      })(<InputNumber style={{ width: "100%" }} />)}
                    </Item>
                  </Col>
                </Row>
                <Row gutter={30}>
                  <Col span={10}>
                    <Item
                      label="status"
                      {...{ labelCol: { span: 9 }, wrapperCol: { span: 15 } }}
                    >
                      {getFieldDecorator(`divideUpstreams[${key}].status`, {
                        initialValue: divideUpstreams[key]
                          ? divideUpstreams[key].status
                          : false,
                        valuePropName: "checked",
                        rules: [
                          {
                            required: true,
                            message: "status is required",
                          },
                        ],
                      })(<Switch />)}
                    </Item>
                  </Col>
                  <Col span={14} style={{ marginLeft: "-20px" }}>
                    <Item
                      label="warmup"
                      {...{ labelCol: { span: 9 }, wrapperCol: { span: 15 } }}
                    >
                      {getFieldDecorator(`divideUpstreams[${key}].warmup`, {
                        initialValue: divideUpstreams[key]
                          ? divideUpstreams[key].warmup
                          : "",
                        rules: [
                          {
                            required: true,
                            message: "warmup is required",
                          },
                        ],
                      })(<InputNumber style={{ width: "100%" }} />)}
                    </Item>
                  </Col>
                </Row>
              </div>
              <div style={{ width: 64, textAlign: "right" }}>
                <Icon
                  onClick={() => {
                    setFieldsValue({
                      keys: keys.filter((k) => k !== key),
                    });
                  }}
                  type="minus-circle-o"
                  style={{
                    fontSize: 18,
                    color: "#ff0000",
                    cursor: "pointer",
                  }}
                />
              </div>
            </div>
          </Card>
        </Item>
      ));

      return (
        <div className={styles.springCloud}>
          <Item label="serviceId" {...formItemLayout}>
            <div style={{ display: "flex", alignItems: "center" }}>
              {getFieldDecorator("serviceId", {
                initialValue: serviceId,
                rules: [
                  {
                    required: true,
                  },
                ],
              })(
                <Input
                  style={{ width: "50%" }}
                  allowClear
                  placeholder="serviceId"
                />,
              )}

              <Item label="gray" {...formCheckLayout} style={{ margin: 0 }}>
                {getFieldDecorator("gray", {
                  valuePropName: "checked",
                  initialValue: gray,
                  rules: [
                    {
                      required: true,
                    },
                  ],
                })(<Switch />)}
              </Item>
            </div>
          </Item>
          {Rule}
          <Item label="" {...{ wrapperCol: { span: 21, offset: 3 } }}>
            <Button
              className={styles.addButton}
              type="primary"
              onClick={() => {
                const keysData = getFieldValue("keys");
                // eslint-disable-next-line no-plusplus
                const nextKeys = keysData.concat(id++);
                setFieldsValue({
                  keys: nextKeys,
                });
              }}
            >
              Add divide upstream
            </Button>
          </Item>
        </div>
      );
    }

    if (Array.isArray(pluginHandleList) && pluginHandleList.length) {
      return (
        <Item
          label={getIntlContent("SHENYU.COMMON.DEAL")}
          {...formItemLayout}
          className={styles.rootFormItem}
        >
          <div
            className={styles.handleWrap}
            style={{
              marginTop: 0,
            }}
          >
            <div>
              {pluginHandleList.map((handleList, index) => {
                return (
                  <div
                    key={index}
                    style={{
                      display: "flex",
                      justifyContent: "space-between",
                      flexDirection: "row",
                    }}
                  >
                    <ul
                      className={classnames({
                        [styles.handleUl]: true,
                        [styles.handleSelectorUl]: true,
                        [styles.springUl]: true,
                      })}
                      style={{
                        width: "100%",
                        padding: 0,
                        marginBottom: "-6px",
                      }}
                    >
                      {handleList &&
                        handleList.map((item) => {
                          let required = item.required === "1";
                          let defaultValue =
                            item.value === 0 || item.value === false
                              ? item.value
                              : item.value || item.defaultValue;
                          let placeholder = item.label || item.placeholder;
                          let checkRule = item.checkRule;
                          let fieldName = item.field + index;
                          let rules = [];
                          if (required) {
                            rules.push({
                              required: { required },
                              message:
                                getIntlContent("SHENYU.COMMON.PLEASEINPUT") +
                                item.label,
                            });
                          }
                          if (checkRule) {
                            rules.push({
                              // eslint-disable-next-line no-eval
                              pattern: eval(checkRule),
                              message: `${getIntlContent(
                                "SHENYU.PLUGIN.RULE.INVALID",
                              )}:(${checkRule})`,
                            });
                          }
                          if (item.dataType === 1) {
                            return (
                              <li key={fieldName}>
                                <Tooltip title={placeholder}>
                                  <Item>
                                    {getFieldDecorator(fieldName, {
                                      rules,
                                      initialValue: defaultValue,
                                    })(
                                      <Input
                                        allowClear
                                        addonBefore={
                                          <div style={{ width: labelWidth }}>
                                            {item.label}
                                          </div>
                                        }
                                        placeholder={placeholder}
                                        key={fieldName}
                                      />,
                                    )}
                                  </Item>
                                </Tooltip>
                              </li>
                            );
                          } else if (item.dataType === 3 && item.dictOptions) {
                            return (
                              <li key={fieldName}>
                                <Tooltip title={placeholder}>
                                  <Item>
                                    {getFieldDecorator(fieldName, {
                                      rules,
                                      initialValue:
                                        defaultValue === true
                                          ? "true"
                                          : defaultValue === false
                                            ? "false"
                                            : defaultValue,
                                    })(
                                      <Select
                                        placeholder={placeholder}
                                        style={{ width: "100%" }}
                                      >
                                        {item.dictOptions.map((option) => {
                                          const optionValue =
                                            option.dictValue === true
                                              ? "true"
                                              : option.dictValue === false
                                                ? "false"
                                                : option.dictValue;
                                          return (
                                            <Option
                                              key={optionValue}
                                              value={optionValue}
                                            >
                                              {option.dictName} ({item.label})
                                            </Option>
                                          );
                                        })}
                                      </Select>,
                                    )}
                                  </Item>
                                </Tooltip>
                              </li>
                            );
                          } else {
                            return (
                              <li key={fieldName}>
                                <Tooltip title={item.label}>
                                  <Item>
                                    {getFieldDecorator(fieldName, {
                                      rules,
                                      initialValue: defaultValue,
                                    })(
                                      <Input
                                        allowClear
                                        addonBefore={
                                          <div style={{ width: labelWidth }}>
                                            {item.label}
                                          </div>
                                        }
                                        placeholder={placeholder}
                                        key={fieldName}
                                        onChange={(e) => {
                                          this.onDealChange(
                                            e.target.value,
                                            item,
                                          );
                                        }}
                                      />,
                                    )}
                                  </Item>
                                </Tooltip>
                              </li>
                            );
                          }
                        })}
                    </ul>
                    {multiSelectorHandle && (
                      <div style={{ width: 80 }}>
                        <Popconfirm
                          title={getIntlContent("SHENYU.COMMON.DELETE")}
                          placement="bottom"
                          onCancel={(e) => {
                            e.stopPropagation();
                          }}
                          onConfirm={(e) => {
                            e.stopPropagation();
                            this.handleDeleteHandle(index);
                          }}
                          okText={getIntlContent("SHENYU.COMMON.SURE")}
                          cancelText={getIntlContent("SHENYU.COMMON.CALCEL")}
                        >
                          <Button type="danger">
                            {getIntlContent("SHENYU.COMMON.DELETE.NAME")}
                          </Button>
                        </Popconfirm>
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
            {multiSelectorHandle && (
              <div style={{ width: 80, marginLeft: 5 }}>
                <Button onClick={this.handleAddHandle} type="primary">
                  {getIntlContent("SHENYU.COMMON.ADD")}
                </Button>
              </div>
            )}
          </div>
        </Item>
      );
    }
    return null;
  };

  setPluginHandleList = (pluginHandles) => {
    this.setState({ pluginHandleList: pluginHandles });
  };

  handleCopyData = (copyData) => {
    if (!copyData) {
      this.setState({ visible: false });
      return;
    }
    const { form } = this.props;
    const {
      selectorConditions,
      name,
      type,
      matchMode,
      continued,
      loged,
      enabled,
      sort,
    } = copyData;

    const formData = {
      name,
      type: type.toString(),
      continued,
      loged,
      enabled,
      sort,
    };

    if (formData.type === "1") {
      formData.matchMode = matchMode.toString();
      this.initSelectorCondition({
        selectorConditions: selectorConditions.map((v) => {
          const {
            id: rawId,
            selectorId,
            dateCreated,
            dateUpdated,
            ...condition
          } = v;
          return condition;
        }),
      });
    }
    form.setFieldsValue(formData);
    this.setState({ visible: false, selectValue: formData.type });
  };

  handleImportDiscoveryConfig = (configData) => {
    const { form } = this.props;
    const {
      type = "",
      serverList = "",
      id: discoveryId = "",
      props = "{}",
    } = configData || {};
    const formData = {
      selectedDiscoveryType: type,
      serverList,
    };
    this.setState(
      {
        selectedDiscoveryValue: type,
        showDiscoveryImportModal: false,
        importedDiscoveryId: discoveryId,
      },
      () => {
        form.setFieldsValue(formData);
        this.state.configPropsJson = JSON.parse(props);
      },
    );
  };

  onDealChange = (value, item) => {
    item.value = value;
  };

  handleTableChange = (newData) => {
    this.setState({ upstreams: newData });
  };

  handleCountChange = (newCount) => {
    this.setState({ recordCount: newCount });
  };

  handleDiscoveryValueChange = (value) => {
    this.setState({ selectedDiscoveryValue: value });
  };

  renderOperatorOptions = (operators, paramType) => {
    if (operators && operators instanceof Array) {
      let operatorsFil = operators.map((operate) => {
        return (
          <Option key={operate.dictValue} value={operate.dictValue}>
            {operate.dictName}
          </Option>
        );
      });
      if (paramType !== "uri") {
        operatorsFil = operatorsFil.filter((operate) => {
          return operate.key !== "pathPattern" ? operate : "";
        });
      }
      if (
        paramType !== "post" &&
        paramType !== "query" &&
        paramType !== "header" &&
        paramType !== "cookie"
      ) {
        operatorsFil = operatorsFil.filter((operate) => {
          return operate.key !== "isBlank" ? operate : "";
        });
      }
      if (
        paramType === "uri" ||
        paramType === "host" ||
        paramType === "ip" ||
        paramType === "cookie" ||
        paramType === "domain"
      ) {
        operatorsFil = operatorsFil.filter((operate) => {
          return operate.key !== "TimeBefore" && operate.key !== "TimeAfter"
            ? operate
            : "";
        });
      }
      if (paramType === "req_method") {
        operatorsFil = operatorsFil.filter((operate) => {
          return operate.key === "=" ? operate : "";
        });
      }
      return operatorsFil;
    }

    return "";
  };

  renderParamTypeOptions = (paramTypes = []) => {
    if (paramTypes && paramTypes instanceof Array) {
      return paramTypes.map((typeItem) => {
        const { dictValue, dictName } = typeItem;
        return (
          <Option key={dictValue} value={dictValue}>
            {dictName}
          </Option>
        );
      });
    }

    return "";
  };

  getParamValueInput = (item, index) => {
    if (item.operator === "TimeBefore" || item.operator === "TimeAfter") {
      let date = new Date();
      const defaultDay = date
        .getFullYear()
        .toString()
        .concat("-")
        .concat(date.getMonth() + 1)
        .concat("-")
        .concat(date.getDate());
      return (
        <Input.Group compact style={{ top: -2 }}>
          <DatePicker
            style={{ width: "51%" }}
            onChange={(e) => {
              let day = e
                ? e
                    .eraYear()
                    .toString()
                    .concat("-")
                    .concat(e.month() + 1)
                    .concat("-")
                    .concat(e.date())
                : defaultDay;
              this.conditionChange(
                index,
                "paramValue",
                `${formatDateString(day)} ${formatTimeString(item.paramValue)}`,
              );
            }}
            value={formatDate(item.paramValue)}
          />
          <TimePicker
            style={{ width: "49%" }}
            onChange={(e) => {
              let time = e
                ? ""
                    .concat(" ")
                    .concat(e.hours())
                    .concat(":")
                    .concat(e.minutes())
                    .concat(":")
                    .concat(e.seconds())
                : "";
              this.conditionChange(
                index,
                "paramValue",
                `${formatDateString(item.paramValue)} ${formatTimeString(time)}`,
              );
            }}
            value={formatTime(item.paramValue)}
          />
        </Input.Group>
      );
    } else {
      return (
        <Input
          allowClear
          onChange={(e) => {
            this.conditionChange(index, "paramValue", e.target.value);
          }}
          value={item.paramValue}
        />
      );
    }
  };

  renderBasicConfig = () => {
    let {
      form,
      name = "",
      platform,
      type = "",
      matchMode = "",
      continued = true,
      loged = true,
      enabled = true,
      matchRestful = false,
      sort,
    } = this.props;

    const {
      selectorConditions,
      selectValue,
      operatorDics,
      matchModeDics,
      paramTypeDics,
      visible,
    } = this.state;

    type = `${type.toString()}` || "1";
    let { selectorTypeEnums } = platform;
    const { getFieldDecorator } = form;
    return (
      <>
        <Item
          label={getIntlContent("SHENYU.PLUGIN.SELECTOR.LIST.COLUMN.NAME")}
          {...formItemLayout}
        >
          {getFieldDecorator("name", {
            rules: [
              {
                required: true,
                message: getIntlContent("SHENYU.COMMON.INPUTNAME"),
              },
            ],
            initialValue: name,
          })(
            <Input
              allowClear
              placeholder={getIntlContent(
                "SHENYU.PLUGIN.SELECTOR.LIST.COLUMN.NAME",
              )}
              addonAfter={
                <Button
                  size="small"
                  type="link"
                  onClick={() => {
                    this.setState({ visible: true });
                  }}
                >
                  {getIntlContent("SHENYU.SELECTOR.COPY")}
                </Button>
              }
            />,
          )}
        </Item>
        <SelectorCopy
          visible={visible}
          onOk={this.handleCopyData}
          onCancel={() => {
            this.setState({ visible: false });
          }}
        />
        <Item label={getIntlContent("SHENYU.COMMON.TYPE")} {...formItemLayout}>
          {getFieldDecorator("type", {
            rules: [
              {
                required: true,
                message: getIntlContent("SHENYU.COMMON.INPUTTYPE"),
              },
            ],
            initialValue: type,
          })(
            <Select
              placeholder={getIntlContent("SHENYU.COMMON.TYPE")}
              onChange={(value) => this.getSelectValue(value)}
            >
              {selectorTypeEnums.map((item) => {
                return (
                  <Option key={item.code} value={item.code.toString()}>
                    {getIntlContent(
                      `SHENYU.COMMON.SELECTOR.TYPE.${item.name.toUpperCase()}`,
                      item.name,
                    )}
                  </Option>
                );
              })}
            </Select>,
          )}
        </Item>
        {selectValue !== "0" && (
          <>
            <Item
              label={getIntlContent("SHENYU.COMMON.MATCHTYPE")}
              {...formItemLayout}
            >
              {getFieldDecorator("matchMode", {
                rules: [
                  {
                    required: true,
                    message: getIntlContent("SHENYU.COMMON.INPUTMATCHTYPE"),
                  },
                ],
                initialValue: `${matchMode}`,
              })(
                <Select placeholder={getIntlContent("SHENYU.COMMON.MATCHTYPE")}>
                  {matchModeDics &&
                    matchModeDics.map((item) => {
                      return (
                        <Option key={item.dictValue} value={item.dictValue}>
                          {item.dictName}
                        </Option>
                      );
                    })}
                </Select>,
              )}
            </Item>
            <div className={styles.condition}>
              <Item
                label={getIntlContent("SHENYU.COMMON.CONDITION")}
                required
                {...formItemLayout}
              >
                {selectorConditions.map((item, index) => {
                  return (
                    <Row key={index} gutter={8}>
                      <Col span={5}>
                        <Select
                          onChange={(value) => {
                            this.conditionChange(index, "paramType", value);
                          }}
                          value={item.paramType}
                        >
                          {this.renderParamTypeOptions(paramTypeDics)}
                        </Select>
                      </Col>
                      <Col
                        span={4}
                        style={{
                          display: this.state[`paramTypeValueEn${index}`]
                            ? "none"
                            : "block",
                        }}
                      >
                        <Input
                          allowClear
                          onChange={(e) => {
                            this.conditionChange(
                              index,
                              "paramName",
                              e.target.value,
                            );
                          }}
                          placeholder={item.paramName}
                        />
                      </Col>
                      <Col span={4}>
                        <Select
                          onChange={(value) => {
                            this.conditionChange(index, "operator", value);
                          }}
                          value={item.operator}
                        >
                          {this.renderOperatorOptions(
                            operatorDics,
                            item.paramType,
                          )}
                        </Select>
                      </Col>

                      <Col
                        span={7}
                        style={{
                          display:
                            item.operator === "isBlank" ? "none" : "block",
                        }}
                      >
                        <Tooltip title={item.paramValue}>
                          {this.getParamValueInput(item, index)}
                        </Tooltip>
                      </Col>
                      <Col span={4}>
                        <Button
                          type="danger"
                          onClick={() => {
                            this.handleDelete(index);
                          }}
                        >
                          {getIntlContent("SHENYU.COMMON.DELETE.NAME")}
                        </Button>
                      </Col>
                    </Row>
                  );
                })}
              </Item>
              <Item label={" "} colon={false} {...formItemLayout}>
                <Button
                  className={styles.addButton}
                  onClick={this.handleAdd}
                  type="primary"
                >
                  {getIntlContent("SHENYU.COMMON.ADD")}{" "}
                  {getIntlContent("SHENYU.COMMON.CONDITION")}
                </Button>
              </Item>
            </div>
          </>
        )}
        {this.renderPluginHandler()}
        <Item
          label={getIntlContent("SHENYU.SELECTOR.EXEORDER")}
          {...formItemLayout}
        >
          {getFieldDecorator("sort", {
            initialValue: sort,
            rules: [
              {
                required: true,
                message: getIntlContent("SHENYU.SELECTOR.INPUTNUMBER"),
              },
              {
                pattern: /^([1-9][0-9]{0,2}|1000)$/,
                message: getIntlContent("SHENYU.SELECTOR.INPUTNUMBER"),
              },
            ],
          })(
            <Input
              allowClear
              placeholder={getIntlContent("SHENYU.SELECTOR.INPUTORDER")}
            />,
          )}
        </Item>
        <Item label={" "} colon={false} {...formItemLayout}>
          <div className={styles.layout}>
            <Item
              {...formCheckLayout}
              label={getIntlContent("SHENYU.SELECTOR.CONTINUE")}
            >
              {getFieldDecorator("continued", {
                initialValue: continued,
                valuePropName: "checked",
                rules: [{ required: true }],
              })(<Switch />)}
            </Item>
            <Item
              style={{ margin: "0 30px" }}
              {...formCheckLayout}
              label={getIntlContent("SHENYU.SELECTOR.PRINTLOG")}
            >
              {getFieldDecorator("loged", {
                initialValue: loged,
                valuePropName: "checked",
                rules: [{ required: true }],
              })(<Switch />)}
            </Item>
            <Item
              {...formCheckLayout}
              label={getIntlContent("SHENYU.SELECTOR.WHETHEROPEN")}
            >
              {getFieldDecorator("enabled", {
                initialValue: enabled,
                valuePropName: "checked",
                rules: [{ required: true }],
              })(<Switch />)}
            </Item>
            <Item
              style={{ margin: "0 30px" }}
              {...formCheckLayout}
              label={getIntlContent("SHENYU.SELECTOR.MATCHRESTFUL")}
            >
              {getFieldDecorator("matchRestful", {
                initialValue: matchRestful,
                valuePropName: "checked",
                rules: [{ required: true }],
              })(<Switch />)}
            </Item>
          </div>
        </Item>
      </>
    );
  };

  renderDiscoveryConfig = () => {
    const { form, isAdd = true, discoveryConfig = {} } = this.props;
    const {
      discoveryModeDics,
      upstreams,
      recordCount,
      discoveryHandler,
      defaultValueList,
      configPropsJson,
      selectedDiscoveryValue,
    } = this.state;
    const { getFieldDecorator } = form;
    return (
      <>
        <Item
          label={getIntlContent("SHENYU.DISCOVERY.CONFIGURATION.TYPE")}
          {...formItemLayout}
        >
          {getFieldDecorator("selectedDiscoveryType", {
            rules: [
              {
                required: true,
                message: getIntlContent(
                  "SHENYU.DISCOVERY.CONFIGURATION.TYPE.INPUT",
                ),
              },
            ],
            initialValue:
              discoveryConfig.discoveryType !== ""
                ? discoveryConfig.discoveryType
                : "local",
          })(
            <Select
              placeholder={getIntlContent(
                "SHENYU.DISCOVERY.CONFIGURATION.TYPE.INPUT",
              )}
              disabled={!isAdd}
              onChange={(value) => {
                this.handleDiscoveryValueChange(value);
                let configProps = discoveryModeDics.filter(
                  (item) => item.dictName === value,
                );
                let propsEntries = JSON.parse(
                  configProps[0]?.dictValue || "{}",
                );
                this.setState({ configPropsJson: propsEntries });
              }}
            >
              {this.handleOptions()}
            </Select>,
          )}
        </Item>

        {selectedDiscoveryValue !== "local" ? (
          <>
            <Item
              label={getIntlContent("SHENYU.DISCOVERY.SELECTOR.LISTENERNODE")}
              {...formItemLayout}
            >
              {getFieldDecorator("listenerNode", {
                rules: [
                  {
                    required: true,
                    message: getIntlContent(
                      "SHENYU.DISCOVERY.SELECTOR.LISTENERNODE.INPUT",
                    ),
                  },
                ],
                initialValue: discoveryConfig.listenerNode,
              })(
                <Input
                  allowClear
                  disabled={!isAdd}
                  placeholder={getIntlContent(
                    "SHENYU.DISCOVERY.SELECTOR.LISTENERNODE.INPUT",
                  )}
                />,
              )}
            </Item>

            {discoveryHandler !== null &&
              Array.isArray(discoveryHandler) &&
              discoveryHandler.length !== 0 && (
                <Item
                  label={getIntlContent("SHENYU.DISCOVERY.SELECTOR.HANDLER")}
                  {...formItemLayout}
                >
                  <div
                    className={styles.handleWrap}
                    style={{
                      display: "flex",
                    }}
                  >
                    <div
                      style={{
                        display: "flex",
                        justifyContent: "space-between",
                        flexDirection: "row",
                      }}
                    >
                      <ul
                        className={classnames({
                          [styles.handleUl]: true,
                          [styles.springUl]: true,
                        })}
                        style={{ width: "100%" }}
                      >
                        {(() => {
                          let item = discoveryHandler[0];
                          let checkRule = item.checkRule;
                          let required = item.required === "1";
                          let rules = [];
                          if (required) {
                            rules.push({
                              required: { required },
                              message:
                                getIntlContent("SHENYU.COMMON.PLEASEINPUT") +
                                item.label,
                            });
                          }
                          if (checkRule) {
                            rules.push({
                              // eslint-disable-next-line no-eval
                              pattern: eval(checkRule),
                              message: `${getIntlContent(
                                "SHENYU.PLUGIN.RULE.INVALID",
                              )}:(${checkRule})`,
                            });
                          }
                          if (defaultValueList != null) {
                            return defaultValueList.map((value, index) => (
                              <li key={index}>
                                <Item>
                                  {getFieldDecorator(value, {
                                    initialValue:
                                      isAdd === true
                                        ? findKeyByValue(
                                            discoveryConfig.handler,
                                            value,
                                          )
                                        : findKeyByValue(
                                            JSON.parse(discoveryConfig.handler),
                                            value,
                                          ),
                                    rules,
                                  })(
                                    <Input
                                      allowClear
                                      disabled={!isAdd}
                                      addonAfter={
                                        <div style={{ width: "50px" }}>
                                          {value}
                                        </div>
                                      }
                                      placeholder={`Your ${value}`}
                                      key={value}
                                    />,
                                  )}
                                </Item>
                              </li>
                            ));
                          }
                        })()}
                      </ul>
                    </div>
                  </div>
                </Item>
              )}

            <Item
              label={getIntlContent(
                "SHENYU.DISCOVERY.CONFIGURATION.SERVERLIST",
              )}
              {...formItemLayout}
            >
              {getFieldDecorator("serverList", {
                rules: [
                  {
                    required: true,
                    message: getIntlContent(
                      "SHENYU.DISCOVERY.CONFIGURATION.SERVERLIST.INPUT",
                    ),
                  },
                ],
                initialValue: discoveryConfig.serverList,
              })(
                <Input
                  allowClear
                  disabled={!isAdd}
                  placeholder={getIntlContent(
                    "SHENYU.DISCOVERY.CONFIGURATION.SERVERLIST.INPUT",
                  )}
                />,
              )}
            </Item>

            {Object.keys(configPropsJson).length > 0 && (
              <div
                style={{
                  marginLeft: "60px",
                  marginTop: "15px",
                  marginBottom: "15px",
                  fontWeight: "500",
                }}
              >
                {getIntlContent("SHENYU.DISCOVERY.CONFIGURATION.PROPS")}
                <span style={{ marginLeft: "2px", fontWeight: "500" }}>:</span>
              </div>
            )}

            <div
              style={{
                marginLeft: "40px",
                marginRight: "35px",
                display: "flex",
                alignItems: "baseline",
              }}
            >
              <div style={{ marginLeft: "8px", width: "100%" }}>
                <Row gutter={[16, 4]} justify="center">
                  {Object.entries(configPropsJson).map(([key, value]) => (
                    <Col span={12} key={key}>
                      <Item>
                        {getFieldDecorator(key, {
                          initialValue: value,
                        })(
                          <Input
                            allowClear
                            disabled={!isAdd}
                            placeholder={isAdd ? `Enter ${key}` : ""}
                            addonBefore={key}
                            style={{ width: "100%" }}
                          />,
                        )}
                      </Item>
                    </Col>
                  ))}
                </Row>
              </div>
            </div>

            {isAdd !== true ? (
              <>
                <Divider>
                  {getIntlContent("SHENYU.DISCOVERY.SELECTOR.UPSTREAM")}
                </Divider>
                <EditableFormTable
                  wrappedComponentRef={this.editableFormTableRef}
                  isLocal={false}
                  dataSource={upstreams}
                  recordCount={recordCount}
                  onTableChange={this.handleTableChange}
                  onCountChange={this.handleCountChange}
                />
                {/* <Table dataSource={upstreams} columns={columns} />; */}
              </>
            ) : null}
          </>
        ) : (
          <>
            <Divider>
              {getIntlContent("SHENYU.DISCOVERY.SELECTOR.UPSTREAM")}
            </Divider>
            <EditableFormTable
              wrappedComponentRef={this.editableFormTableRef}
              isLocal={true}
              dataSource={upstreams}
              recordCount={recordCount}
              onTableChange={this.handleTableChange}
              onCountChange={this.handleCountChange}
            />
          </>
        )}
      </>
    );
  };

  render() {
    const { onCancel, isDiscovery, isAdd = true } = this.props;
    const operations = (
      <Button
        type="primary"
        icon="import"
        onClick={() => {
          this.setState({ showDiscoveryImportModal: true });
        }}
        disabled={!isAdd}
      >
        {getIntlContent("SHENYU.DISCOVERY.SELECTOR.CONFIG.IMPORT")}
      </Button>
    );
    return (
      <Modal
        width="1100px"
        centered
        title={this.props.modalTitle || getIntlContent("SHENYU.SELECTOR.NAME")}
        // visible here defaults to true, because the visibility of modal is determined by the popup attribute in index.js
        visible
        okText={getIntlContent("SHENYU.COMMON.SURE")}
        cancelText={getIntlContent("SHENYU.COMMON.CALCEL")}
        onOk={this.handleSubmit}
        onCancel={onCancel}
      >
        <Form onSubmit={this.handleSubmit} className="login-form">
          {
            // divide, grpc, websocket plugin
            isDiscovery ? (
              <Tabs
                defaultActiveKey="1"
                size="small"
                tabBarExtraContent={operations}
              >
                <TabPane
                  tab={getIntlContent("SHENYU.DISCOVERY.SELECTOR.CONFIG.BASIC")}
                  key="1"
                >
                  {this.renderBasicConfig()}
                </TabPane>
                <TabPane
                  tab={getIntlContent(
                    "SHENYU.DISCOVERY.SELECTOR.CONFIG.DISCOVERY",
                  )}
                  key="2"
                >
                  {this.renderDiscoveryConfig()}
                  <DiscoveryImportModal
                    pluginName={this.props.pluginName}
                    disabled={!isAdd}
                    visible={this.state.showDiscoveryImportModal}
                    onOk={this.handleImportDiscoveryConfig}
                    onCancel={() => {
                      this.setState({ showDiscoveryImportModal: false });
                    }}
                  />
                </TabPane>
              </Tabs>
            ) : (
              this.renderBasicConfig()
            )
          }
        </Form>
      </Modal>
    );
  }
}

export default Form.create()(AddModal);
