/* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect, useCallback, useState } from 'react';
import { Select, Input, Form } from '@easyv/antd';
import ConfirmModal from 'components/ConfirmModal';
import ApiForm from './ApiForm';
import CsvForm from './CsvForm';
import ApiGatewayForm from './ApiGatewayForm';
import SqlForm from './SqlForm';
import OracelForm from './OracelForm';
import DB2Form from './DB2Form';
import DTableAPI from './DTableAPI';
import { sourceOptions } from 'constants/config';
import debounce from 'lodash/debounce';
import { objectValueTrim } from 'utils/utils';
import styles from './SourceEditModal.less';
import toString from 'lodash/toString';
import { useAuth } from 'components/easyUse';
import EasyvTooltip from 'components/EasyvTooltip';
import { useSelector } from 'react-redux';
import { RootState } from 'models';
import { redirectToUpgrade } from 'utils/utils';
import PersonalModal from '@/components/PersonalModal';
import SocketForm from './SocketForm';
import message from '@/components/message';

const formItemLayout = {
  labelCol: {
    sm: { span: 4 },
  },
};
const FormItem = Form.Item;
const Option = Select.Option;

interface IProps {
  visible: boolean;
  loading: boolean;
  defaultType?: string;
  data: {
    id?: number;
    type?: string;
    encode?: string;
    filePath?: string;
    database?: string;
    host?: string;
    user?: string;
    password?: string;
    port?: number | string;
  };
  onCancel: () => void;
  onOk: (x) => void;
}

function SourceEditModal({ visible, loading, data, defaultType, onCancel, onOk }: IProps) {
  // const [type, setType] = useState(data.type || defaultType || 'csv');
  const [form] = Form.useForm();
  const { validateFields, setFieldsValue, resetFields } = form;

  const { checkAuth } = useAuth();
  const user = useSelector((state: RootState) => state.user);
  const [modelVisible, setModelVisible] = useState(false);
  const [isPassedTest,setPassedTest] = useState(false);

  const isEdit = data?.id && data?.password === undefined; 


  useEffect(() => {
    if (visible && form) {
      // INFO 注意这里的端口由于前端表单中时number服务端存的string，需要在存在port时进行转换成number
      setFieldsValue({ port: data.port ? Number(data.port) : data?.port });
    }

    if (visible && defaultType) {
      setFieldsValue({ type: defaultType });
    }

    // 数据源值关闭重置
    if (!visible && form) {
      resetFields();
    }
  }, [visible]);

  const handleTypeChange = useCallback(
    (value) => {
      form.resetFields();
      form.setFieldsValue({ type: value });
    },
    [data, form],
  );

  const clearPassword = (password) => {
    return password === '******' ? false : true;
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    validateFields().then((values) => {
      if (['db2', 'damengdb'].includes(values.type) && values.database !== data.database ) {
        if (!isPassedTest) {
          message.error('请通过测试后再保存');
          return false;
        }
      }
      const { password, ...val } = values;
      if (clearPassword(password)) {
        val['password'] = password;
      }
      if (val.port) {
        val.port = toString(val.port); //服务端只接受string
      }
      onOk(objectValueTrim(val));
    });
  };

  const onPassword = (e) => {
    if (isEdit) {
      const v = e.target.value.trim();
      form.setFieldsValue({ password: !clearPassword(v) ? '' : !v ? '******' : v });
    }
  };

  const optionList = sourceOptions.map((d) => {
    if (checkAuth('csvSourceOptions') && d.value !== 'csv' && d.value !== 'dtableapi') {
      // ge ren ban
      return {
        ...d,
        disabled: true,
      };
    }
    return d;
  });

  function versionUpdate() {
    if (user.userInfo.skuId === 7) {
      setModelVisible(true);
      onCancel();
    } else {
      user.userInfo.skuId && redirectToUpgrade(user.userInfo.skuId, 'saas_advanced');
    }
  }

  const initialValues = {
    ...data,
    password: isEdit ? '******' : '',
    type: data.type || defaultType || 'csv',
    encode: data.encode || 'auto',
  }
  
  return (
    <div>
      <ConfirmModal
        width={550}
        theme="black"
        visible={visible}
        confirmLoading={loading}
        title={`${data.id ? '编辑' : '创建'}数据源`}
        footer={true}
        onCancel={onCancel}
        onOk={debounce(handleSubmit, 100)}
        destroyOnClose={true}>
        <div className={styles.formContainer}>
          <Form
            {...formItemLayout}
            layout="horizontal"
            id="easy-source-form"
            style={{ position: 'relative' }}
            form={form}
            className={styles.fromWrapper}
            autoComplete="off"
            initialValues={initialValues}>
            <FormItem
              label="类型"
              name="type"
              rules={[{ required: true, message: '请选择数据源' }]}>
              <Select
                dropdownClassName={styles.selectStyle}
                disabled={!!data.type}
                placeholder="请选择数据源"
                style={{ width: '100%' }}
                onChange={handleTypeChange}
                getPopupContainer={() =>
                  document.getElementById('easy-source-form') as HTMLElement
                }>
                {optionList.map((item) => (
                  <Option disabled={item.disabled} key={item.value} value={item.value}>
                    <div className={styles.optionBox}>
                      {item.disabled ? (
                        <span style={{ color: 'rgba(180, 183, 193, 0.5)' }}>{item.name}</span>
                      ) : (
                        <span>{item.name}</span>
                      )}
                      <EasyvTooltip
                        placement="top"
                        title={
                          <>
                            点击升级为高级版或尊
                            <br />
                            享版可使用此选项配置
                          </>
                        }>
                        {item.disabled && (
                          <span className={styles.updateModale} onClick={versionUpdate}>
                            升级可用
                          </span>
                        )}
                      </EasyvTooltip>
                    </div>
                  </Option>
                ))}
              </Select>
            </FormItem>
            <FormItem
              label="数据源名称"
              name="name"
              rules={[
                { required: true, message: '请输入数据源名称!', whitespace: true },
                { max: 16, message: '名称不能超过16个字符' },
              ]}>
              <Input placeholder="请输入数据源名称" />
            </FormItem>
            <FormItem
              label="描述"
              name="description"
              rules={[{ max: 32, message: '不能超过32个字符' }]}>
              <Input.TextArea
                placeholder="请输入数据源描述"
                autoSize={{ minRows: 4, maxRows: 4 }}
              />
            </FormItem>

            <Form.Item
              noStyle
              shouldUpdate={(prevValues, currentValues) => prevValues.type !== currentValues.type}>
              {({ getFieldValue }) => {
                const type = getFieldValue('type');
                switch (type) {
                  case 'api':
                    return <ApiForm />;
                  case 'apiGateway':
                  case 'dtInsight':
                    return <ApiGatewayForm />;
                  case 'mysql':
                  case 'mssql':
                  case 'postgresql':
                  case 'clickhouse':
                    return <SqlForm isEdit={isEdit} type={type} value={data} onPassword={onPassword} />;
                  case 'oracle':
                    return <OracelForm  isEdit={isEdit} value={data} onPassword={onPassword} />;
                  case 'dtableapi':
                    return <DTableAPI />;
                  case 'damengdb':
                  case 'db2':
                    return <DB2Form isEdit={isEdit} setPassedTest={setPassedTest} type={type} value={data} onPassword={onPassword} />;
                  case 'mqtt':
                  case 'ws':
                    return <SocketForm />;
                  case 'csv':
                  default:
                    return <CsvForm value={data} setFieldsValue={setFieldsValue} />;
                }
              }}
            </Form.Item>
          </Form>
        </div>
      </ConfirmModal>
      <PersonalModal visible={modelVisible} changeVisible={setModelVisible}></PersonalModal>
    </div>
  );
}

export default SourceEditModal;
