import React from 'react';
import { Form, Input, Modal, Select } from '@arco-design/web-react';
import { useSelector } from 'react-redux';

const FormItem = Form.Item;

// 定义数据类型枚举
const dataTypeEnum = [
  'OBJECT',
  'JSON',
  'ARRAY',
  'BOOLEAN',
  'INTEGER',
  'DOUBLE',
  'STRING'
];

// 定义数组元素类型枚举
const arrayElementTypeEnum = [
  'STRING',
  'INTEGER',
  'DOUBLE',
  'BOOLEAN',
  'ARRAY',
  'JSON',
  'OBJECT'
];

// 默认值类型校验方法
const validateDefaultValue = (value, dataType, arrayType) => {
  // 如果没有值，则不进行校验
  if (value === undefined || value === null || value === '') {
    return true;
  }

  switch (dataType) {
    case 'STRING':
    case 'DATE':
    case 'DATETIME':
    case 'TIMESTAMP':
    case 'DATABASE':
      // 字符串类型 - 任何值都是有效的
      return true;

    case 'INTEGER':
      // 整数类型 - 必须是整数
      const intRegex = /^-?\d+$/;
      return intRegex.test(value);

    case 'DOUBLE':
      // 双精度浮点类型 - 必须是数字
      const doubleRegex = /^-?\d+(\.\d+)?$/;
      return doubleRegex.test(value);

    case 'BOOLEAN':
      // 布尔类型 - 必须是 true 或 false
      return value === 'true' || value === 'false' || value === true || value === false;

    case 'ARRAY':
      // 数组类型 - 尝试解析为JSON数组
      try {
        const parsed = JSON.parse(value);
        if (!Array.isArray(parsed)) {
          return false;
        }

        // 根据数组元素类型进行校验
        if (arrayType) {
          for (const item of parsed) {
            switch (arrayType) {
              case 'STRING':
              case 'DATE':
              case 'DATETIME':
              case 'TIMESTAMP':
                if (typeof item !== 'string') {
                  return false;
                }
                break;
              case 'INTEGER':
                if (!Number.isInteger(item)) {
                  return false;
                }
                break;
              case 'DOUBLE':
                if (typeof item !== 'number') {
                  return false;
                }
                break;
              case 'BOOLEAN':
                if (typeof item !== 'boolean') {
                  return false;
                }
                break;
            }
          }
        }
        return true;
      } catch (e) {
        return false;
      }

    case 'JSON':
      // JSON类型 - 必须是有效的JSON
      try {
        JSON.parse(value);
        return true;
      } catch (e) {
        return false;
      }

    case 'OBJECT':
      // 对象类型 - 必须是有效的JSON对象
      try {
        const parsed = JSON.parse(value);
        return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed);
      } catch (e) {
        return false;
      }

    default:
      // 其他类型暂时不做特殊校验
      return true;
  }
};

const AddGlobalVarModal = ({ visible, onOk, onChangeVisible, form }) => {
  const { info } = useSelector((state: any) => state.ideContainer);

  // 获取表单字段值
  const formData = Form.useWatch('dataType', form);
  const arrayTypeData = Form.useWatch('arrayType', form);

  return (
    <Modal
      title="添加环境变量"
      visible={visible}
      onOk={() => onOk()}
      onCancel={() => onChangeVisible(false)}
      autoFocus={false}
      focusLock={true}
      maskClosable={false}
    >
      <Form form={form} autoComplete="off">
        <FormItem
          field="name"
          label="变量名"
          required
          rules={[
            {
              validator(value, cb) {
                if (!value) {
                  return cb('请填写变量名');
                }

                return cb();
              }
            }
          ]}
        >
          <Input placeholder="请输入变量名" />
        </FormItem>
        <FormItem
          field="dataType"
          label="数据类型"
          required
          rules={[
            {
              validator(value, cb) {
                if (!value) {
                  return cb('请选择数据类型');
                }

                return cb();
              }
            }
          ]}
        >
          <Select placeholder="请选择数据类型">
            {dataTypeEnum.map(key => (
              <Select.Option key={key} value={key}>
                {key}
              </Select.Option>
            ))}
          </Select>
        </FormItem>
        {/* 只有在数据类型选择为ARRAY时才展示数组类型选项 */}
        {formData === 'ARRAY' && (
          <FormItem
            field="arrayType"
            label="数组类型"
            required
            rules={[
              {
                validator(value, cb) {
                  if (!value) {
                    return cb('请选择数组类型');
                  }

                  return cb();
                }
              }
            ]}
          >
            <Select placeholder="请选择数组类型">
              {arrayElementTypeEnum.map(key => (
                <Select.Option key={key} value={key}>
                  {key}
                </Select.Option>
              ))}
            </Select>
          </FormItem>
        )}
        <FormItem
          field="defaultValue"
          label="默认值"
          required
          rules={[
            {
              validator(value, cb) {
                if (!value) {
                  return cb('请填写默认值');
                }

                // 校验默认值类型
                if (!validateDefaultValue(value, formData, arrayTypeData)) {
                  // 根据数据类型返回不同的错误消息
                  switch (formData) {
                    case 'INTEGER':
                      return cb('默认值必须是整数');
                    case 'DOUBLE':
                      return cb('默认值必须是数字');
                    case 'BOOLEAN':
                      return cb('默认值必须是 true 或 false');
                    case 'ARRAY':
                      return cb('默认值必须是有效的JSON数组格式');
                    case 'JSON':
                      return cb('默认值必须是有效的JSON格式');
                    case 'OBJECT':
                      return cb('默认值必须是有效的格式');
                    default:
                      return cb('默认值格式不正确');
                  }
                }

                return cb();
              }
            }
          ]}
        >
          <Input placeholder="请输入默认值" />
        </FormItem>
      </Form>
    </Modal>
  );
};

export default AddGlobalVarModal;