import Schema from 'async-validator'
import { executeExpression } from "./relationshipLogic";

/* 
  是否验证规则
  1. match: 查看 relationship logic 规则
  {type: 'string', max: 10, min: 5, match: []}
*/
const EXECUTE = "match";

export default class Validator {

    _validator = null; // 验证器

    _relationshipLogic = []; // 关联逻辑cache  [ {name: '', key: '', match: []} ]

    constructor(descriptor) {
        ParseRules.call(this, descriptor);
    }

    validate(source, options) {
        let _source = { ...source };
        if (Array.isArray(this._relationshipLogic)) {
            this._relationshipLogic.forEach(tt => {
                if (executeExpression(tt[EXECUTE], source)) {
                    Reflect.set(_source, tt.name, source[tt.key]);
                } else if (tt.required) {
                    Reflect.set(_source, tt.name, 'dasdassad');
                }
            });
        }
        if (!options) options = { suppressWarning: true };
        return new Promise((resolve, reject) => {
            this._validator.validate(_source, options)
                .then(res => resolve(res))
                .catch((err) => {
                    let m = {};
                    this._relationshipLogic.forEach(tt => {
                        m[tt.name] = tt.key;
                    });
                    err.errors.forEach(tt => {
                        if (Reflect.has(m, tt.field)) tt.field = m[tt.field];
                    });
                    Object.keys(err.fields).forEach(k => {
                        if (Reflect.has(m, k)) {
                            Reflect.set(err.fields, m[k], err.fields[k])
                            Reflect.deleteProperty(err.fields, k);
                        }
                    });
                    reject(err);
                })
        });
    }

}

/* 私有方法 */
function ParseRules(descriptor) {
    let des = {};
    let r1 = [];
    let r2 = [];
    Object.keys(descriptor).forEach(k => {
        if (Array.isArray(descriptor[k])) {
            descriptor[k].forEach(tt => {
                if (tt[EXECUTE]) { r2.push(tt); }
                else { r1.push(tt); }
            });
        } else if (typeof descriptor[k] === 'object') {
            if (descriptor[k][EXECUTE]) { r2.push(descriptor[k]); }
            else { r1.push(descriptor[k]); }
        }
        if (r1.length > 0) Reflect.set(des, k, r1);
        if (r2.length > 0) {
            let name = null;
            r2.forEach(tt => {
                name = '_logic' + Math.floor(Math.random() * 1000);
                this._relationshipLogic.push({
                    name: name,
                    key: k,
                    required: tt.required,
                    [EXECUTE]: tt[EXECUTE]
                });
                Reflect.set(des, name, tt);
            });
        }
        r1 = [];
        r2 = [];
    });
    console.log('des',des)
    this._validator = new Schema(des);
}

