import React from 'react';
import { ValidatorPosition } from '@/type/validator-position';
import dayjs from 'dayjs';
import {
  getFormExprNameByPosition,
  symbolMap,
  timeMillisecondMap,
  timeUnitList,
  timeUnitList2,
  timeUnitMap,
  __dataSource__,
} from '../util/expr-const';
import CheckboxSetter from '../setter/checkbox-setter';
import ExprSetter from '../setter/expr-setter';
import { getJSExpressionPrototype } from './common-style';
import {
  getItemDefaultProps,
  getItemListByPosition,
  getItemPrototypeListByPosition,
} from '../util/util';

const { ActionSetter } = window.VisualEngineUtils || {};

export const compareList = [
  {
    label: '不能超过',
    value: '<=',
  },
  {
    label: '不能小于',
    value: '>=',
  },
];
const compareMap: any = {};
compareList.forEach((item) => {
  const { label, value } = item || {};
  compareMap[value] = label;
});

const required = {
  title: '必填',
  value: 'required',
  position: [
    ValidatorPosition.filter,
    ValidatorPosition.form,
    ValidatorPosition.formDialog,
    ValidatorPosition.cnArrayTable,
  ],
  getDefaultProps: () => {
    return {
      required: true,
    };
  },
};
const phone = {
  title: '手机号',
  value: 'phone',
  position: [
    ValidatorPosition.filter,
    ValidatorPosition.form,
    ValidatorPosition.formDialog,
    ValidatorPosition.cnArrayTable,
  ],
  getDefaultProps: () => {
    return {
      format: 'phone',
    };
  },
};

const email = {
  title: '邮箱',
  value: 'email',
  position: [
    ValidatorPosition.filter,
    ValidatorPosition.form,
    ValidatorPosition.formDialog,
    ValidatorPosition.cnArrayTable,
  ],
  getDefaultProps: () => {
    return {
      format: 'email',
    };
  },
};

const number = {
  title: '数字(包含小数)',
  value: 'number',
  position: [
    ValidatorPosition.filter,
    ValidatorPosition.form,
    ValidatorPosition.formDialog,
    ValidatorPosition.cnArrayTable,
  ],
  getDefaultProps: () => {
    return {
      format: 'number',
    };
  },
};
const integer = {
  title: '整数',
  value: 'integer',
  position: [
    ValidatorPosition.filter,
    ValidatorPosition.form,
    ValidatorPosition.formDialog,
    ValidatorPosition.cnArrayTable,
  ],
  getDefaultProps: () => {
    return {
      format: 'integer',
    };
  },
};
const idcard = {
  title: '身份证',
  value: 'idcard',
  position: [
    ValidatorPosition.filter,
    ValidatorPosition.form,
    ValidatorPosition.formDialog,
    ValidatorPosition.cnArrayTable,
  ],
  getDefaultProps: () => {
    return {
      format: 'idcard',
    };
  },
};
const zh = {
  title: '中文',
  value: 'zh',
  position: [
    ValidatorPosition.filter,
    ValidatorPosition.form,
    ValidatorPosition.formDialog,
    ValidatorPosition.cnArrayTable,
  ],
  getDefaultProps: () => {
    return {
      format: 'zh',
    };
  },
};
const pattern = {
  title: '正则表达式',
  value: 'pattern',
  position: [
    ValidatorPosition.filter,
    ValidatorPosition.form,
    ValidatorPosition.formDialog,
    ValidatorPosition.cnArrayTable,
  ],
  configure: [
    {
      name: 'pattern',
      title: '正则表达式',
      display: 'inline',
      setter: 'StringSetter',
      // supportVariable: true,
    },
  ],
};

const maxItems = {
  title: '最大条目数（可编辑表格适用）',
  value: 'maxItems',
  position: [ValidatorPosition.form, ValidatorPosition.formDialog],
  configure: [
    {
      name: 'maxItems',
      title: '最大条目数',
      display: 'inline',
      setter: 'NumberSetter',
      // supportVariable: true,
    },
  ],
};
const minItems = {
  title: '最小条目数（可编辑表格适用）',
  value: 'minItems',
  position: [ValidatorPosition.form, ValidatorPosition.formDialog],
  configure: [
    {
      name: 'minItems',
      title: '最小条目数',
      display: 'inline',
      setter: 'NumberSetter',
      // supportVariable: true,
    },
  ],
};

const custom = {
  title: '自定义校验',
  value: 'custom',
  position: [
    ValidatorPosition.filter,
    ValidatorPosition.form,
    ValidatorPosition.formDialog,
    ValidatorPosition.cnArrayTable,
  ],
  getDefaultProps: () => {
    return {};
  },
  getPrototypeList: (position) => {
    let defaultCode = `/**
* validator
* 用法请参考formily
*
* @param value 当前值
* @param rules 当前校验规则
* @param context 当前上下文
*/
function validator(value, rules, context, state) {
  // // message: 用户配置的错误提示信息
  // const { message } = rules;
  // //field: 当前字段；  form: 当前表单实例
  // const { field, form } = context;
  // // 查询其他字段的值
  // const otherFieldValue = field.query('name').value()
  // //如果return了值，那就表示校验不通过；如果没有return值，表示校验通过
  // return message || "校验不通过";
}`;
    if ([ValidatorPosition.cnArrayTable].includes(position)) {
      defaultCode = `/**
* validator
* 用法请参考formily
*
* @param value 当前值
* @param rules 当前校验规则
* @param context 当前上下文
*/
function validator(value, rules, context) {
  // // message: 用户配置的错误提示信息
  // const { message } = rules;
  // // field: 当前字段；  form: 当前表单实例
  // const { field, form } = context;
  // // 当前行的index
  // const index = field?.path?.segments?.[1];
  // // 查询当前行其他字段的值，xxx代表可编辑表格的字段编码，yyy代表表格某列的字段编码
  // const otherFieldValue = field.query(\`xxx.$\{index}.yyy\`).value()
  // // 查询其他字段的值
  // const otherFieldValue = field.query('name').value()
  // //如果return了值，那就表示校验不通过；如果没有return值，表示校验通过
  // return message || "校验不通过";
}`;
    }
    if ([ValidatorPosition.filter].includes(position)) {
      defaultCode = `/**
* validator
*
* @param rule 校验规则
* @param value 当前输入框的值
* @param callback 校验不通过时调用
*/
function validator(rule, value, callback) {
  // if(value !== 'xxx') {
  //   callback('校验不通过的错误信息')
  // }
  // // 校验通过时调用
  // callback()
}`;
    }
    return [
      {
        name: 'validator',
        title: '自定义校验',
        display: 'inline',
        setter: (
          <ActionSetter
            supportTypes={['page']}
            defaultCode={defaultCode}
            defaultActionName='validator'
          />
        ),
        // supportVariable: true,
      },
    ];
  },
};

const dateInterval = {
  title: '起止时间间隔校验',
  value: 'dateInterval',
  position: [ValidatorPosition.filter],
  showInFilterComponentList: ['RangePicker'],
  configure: [
    {
      name: 'compare',
      title: '起止间隔',
      display: 'inline',
      setter: {
        componentName: 'SelectSetter',
        props: {
          options: compareList,
        },
      },
    },
    {
      name: 'num',
      title: '数量',
      display: 'inline',
      setter: 'NumberSetter',
    },
    {
      name: 'unit',
      title: '单位',
      display: 'inline',
      setter: {
        componentName: 'SelectSetter',
        props: {
          options: [...timeUnitList2, ...timeUnitList],
        },
      },
    },
  ],
  action: (config) => {
    const { position, validateItemConfig } = config || {};
    if ([ValidatorPosition.filter].includes(position)) {
      const { name, message, options } = validateItemConfig;
      const { compare, num, unit } = options || {};
      if (name && unit && compare && typeof num === 'number') {
        return {
          validator: (rule, value, cb) => {
            if (Array.isArray(value)) {
              const start = value[0];
              const end = value[1];
              if (start && end) {
                const isDay = timeUnitList.find((item) => item.value === unit);
                const func = symbolMap[compare];
                if (isDay) {
                  const startDay = dayjs(start).startOf(unit);
                  const endDay = dayjs(end).startOf(unit);
                  const diff = endDay.diff(startDay, unit);
                  if (typeof func === 'function') {
                    const result = func(diff, num);
                    if (typeof result === 'boolean') {
                      if (result !== true) {
                        cb(
                          message ||
                            `间隔时间 ${
                              compareMap[compare] || compare
                            } ${num} ${timeUnitMap[unit] || unit}`,
                        );
                        return;
                      }
                    }
                  }
                } else {
                  const startTime = dayjs(start).valueOf();
                  const endTime = dayjs(end).valueOf();
                  if (typeof func === 'function') {
                    const diff = endTime - startTime;
                    const result = func(diff, num * timeMillisecondMap[unit]);
                    if (typeof result === 'boolean') {
                      if (result !== true) {
                        cb(
                          message ||
                            `间隔时间 ${
                              compareMap[compare] || compare
                            } ${num} ${timeUnitMap[unit] || unit}`,
                        );
                        return;
                      }
                    }
                  }
                }
              }
            }
            cb();
          },
        };
      }
    }
  },
};

export const componentMap = {
  required,
  phone,
  email,
  idcard,
  integer,
  number,
  zh,
  pattern,
  maxItems,
  minItems,
  custom,
  dateInterval,
};

export function createValidatorSetters(config = {}) {
  const { position } = config;
  const prototypeList = getItemPrototypeListByPosition({
    position,
    primaryKey: 'name',
    componentMap,
  });

  const configure = [];
  if (prototypeList?.length > 0) {
    configure.push({
      name: 'options',
      display: 'plain',
      title: '请完善校验的配置',
      setter: {
        componentName: 'ObjectSetter',
        props: {
          config: {
            items: [...prototypeList],
          },
        },
      },
    });
  } else {
    return [];
  }
  return [
    {
      name: 'rules',
      title: '配置字段的校验格式',
      display: 'accordion',
      collapsed: true,
      className: 'cn-array-setter-validator',
      setter: {
        componentName: 'ArraySetter',
        props: {
          mode: 'list',
          itemSetter: {
            componentName: 'ObjectSetter',
            initialValue: {
              // todo
              active: true,
            },
            props: {
              config: {
                items: [
                  {
                    name: 'name',
                    display: 'inline',
                    title: '校验格式',
                    isRequired: true,
                    setter: {
                      componentName: 'SelectSetter',
                      props: (field) => {
                        const parentComponentConfig =
                          field?.parent?.parent?.parent?.getValue?.();
                        const componentName =
                          parentComponentConfig?.componentName;
                        const validatorList = getItemListByPosition({
                          position,
                          componentMap,
                          extraQueryParams: {
                            showInFilterComponentList: componentName,
                          },
                        });
                        return {
                          options: validatorList,
                        };
                      },
                    },
                    extraProps: {
                      setValue(target, value) {
                        const defaultProps = getItemDefaultProps(
                          componentMap,
                          position,
                          value,
                        );
                        if (
                          defaultProps &&
                          Object.keys(defaultProps)?.length > 0
                        ) {
                          target?.parent?.setPropValue?.(
                            'options',
                            defaultProps,
                          );
                        } else {
                          target?.parent?.setPropValue?.('options', {});
                        }
                      },
                    },
                  },
                  {
                    name: 'message',
                    display: 'inline',
                    title: '错误提示',
                    isRequired: true,
                    setter: {
                      componentName: 'CnI18nSetter',
                      props: {
                        placeholder: '错误提示文案',
                      },
                    },
                  },
                  {
                    name: 'active',
                    display: 'inline',
                    className: 'cn-array-setter-validator-active',
                    title: '启用',
                    // setter: <CheckboxSetter />,
                    setter: {
                      componentName: 'MixedSetter',
                      props: {
                        setters: [
                          {
                            componentName: <CheckboxSetter />,
                            title: '启用/禁用',
                          },
                          {
                            componentName: (
                              <ExprSetter
                                configList={[
                                  {
                                    dataKey: 'config',
                                    labelKey: 'label',
                                    valueKey: 'name',
                                    groupName: '表单字段',
                                    groupExprName: getFormExprNameByPosition(
                                      {},
                                    ),
                                    needSecondParam: false,
                                  },
                                  {
                                    groupName: '其他数据',
                                    groupExprName: __dataSource__,
                                    needSecondParam: true,
                                  },
                                ]}
                              />
                            ),
                            title: '简单表达式',
                          },
                          getJSExpressionPrototype({ type: 'form' }),
                        ],
                      },
                    },
                  },
                  {
                    name: 'triggerType',
                    display: 'inline',
                    title: '触发时机',
                    // isRequired:true,
                    setter: {
                      componentName: 'SelectSetter',
                      props: {
                        options: [
                          {
                            label: '输入时',
                            value: 'onInput',
                          },
                          {
                            label: '获得焦点时',
                            value: 'onFocus',
                          },
                          {
                            label: '失去焦点时',
                            value: 'onBlur',
                          },
                        ],
                      },
                    },
                  },
                  ...configure,
                ],
              },
            },
          },
        },
      },
    },
  ];
}
