import schema from 'async-validator'
import { collectDepends, validateDepends } from './dependValidator'
/**
 * @description : 校验所有需要校验的文本域
 * @param {Object} fields: 需要校验的文本域对象 {key: value, key2: value}
 * @param {Object} descriptor: 校验规则，含需要校验的文本域的对象.文本域的校验规则可以是一个数组
 * 定义需要校验的字段和校验规则，详情可参考
 * https://github.com/yiminghe/async-validator
 * const descriptor = {
 *   code: [{ type: 'string', required: true, message: '请输入编码' }, { min: 6, max: 8, message: '编码长度不得小于6、大于8' }],
 *   name: [{ type: 'string', required: true, message: '请输入名称' },{ min: 6, max: 8, message: '编码长度不得小于6、大于8' }],
 *   sortNo: { type: 'string', required: true, message: '请输入顺序' },
 *   busTypeId: { type: 'string', required: true, message: '请选择业务类型' },
 *   url: { type: 'string', required: true, message: '请输入路径' }
 * }
 * @param {Function} formData: 整个表单数据，用于依赖校验时使用
 * @returns {Array}: 返回一个长度为2的数组，第一个为boolean值，代表是否验证通过。第二个是错误消息状态，错误消息状态如下
 * {
 *    code: {state: 'error', message: '编码不能重复'}
 *    name: {state: 'success', message: ''}
 * }
 */
export function fieldValidator(fields, descriptor, formData) {
	return async function validate() {
		// 为了避免每次都校验所有字段，下面添加筛选逻辑，只筛选出fields参数中包含的字段，即fields和descriptor的并集
		let obj = {}
		let result = {}
		let depend
		for (let [key, value] of Object.entries(fields)) {
			if (!descriptor[key]) continue
			obj[key] = descriptor[key]
			result[key] = { state: 'success', message: '' }
			depend = collectDepends(key, descriptor[key])
		}
		let res = await validator(fields, obj)
		if (formData) {
			res = await validateDepends(res, fields, formData)
		}
		result = { ...result, ...res }
		return [!Object.values(res).some((item) => item.state==="error"), result]
		// return [Object.keys(res).length === 0, result]
	}()
}

/**
 * @description 规矩校验器
 * @param {Object} source: 文本域对象
 * @param {Object} descriptor: 校验规则
 * @returns {Object} 返回一个对象 {name: {state: 'error', message: ''}}
 */
async function validator(source, descriptor) {
	let checker = new schema(descriptor)
	let result = {}
	await checker.validate(source, { firstFields: true})
		.then(() => {
			// 验证成功
			// return result
		})
		.catch(({ errors, fields }) => {
			if (errors) {
				// 校验失败的处理, 目前只返回第一条错误信息，如果需要返回多条错误信息，可在此修改
				for (let [key, value] of Object.entries(fields)) {
					result[key] = { ...value[0], state: 'error' }
				}
				return result
			}
		})
	return result
}