import _ from "lodash";
import {toValue} from 'vue'

export const createRegisterModelRules = function () {
    // 新用户注册，让model的属性与模板默认prop对齐可减少传值工作量
    const model = {
        mobile: '',
        smsCode: '',
        newPassword: '',
        newPwdRepeat: '',
        nickName: '',
        sex: '',
        location: '',
        examType: '',
        examMajor: ''
    }
    // 重写规则，如果model定义与模板prop吻合，一般不需要重写
    // allRules 在useRegisterInjection中
    const rules = {}
    // 因为要契合模板，所以model中定义的字段最好与模板中的prop相同，这样前端可以少做修改
    // 但有时API的接收定段并不与model相同，即在这里定义mapping
    // 待提交时使用`useModelMapping`进行转化即可
    const mapping = {
        mobile: 'username',
        smsCode: 'code',
        newPassword: 'password',
        newPwdRepeat: false, // delete when commit
        nickName: 'name'
    }
    return [model, rules, () => useModelMapping(model, mapping)]
}

export const createLoginModelRules = function () {
    const model = {
        username: '',
        password: ''
    }
    const rules = {}
    const mapping = {}
    return [model, rules, () => useModelMapping(model, mapping)]
}

export const createForgetPwdModelRules = function () {
    const model = {
        mobile: '',
        smsCode: '',
        newPassword: '',
        newPwdRepeat: ''
    }
    const rules = {}
    const mapping = {}
    return [model, rules, () => useModelMapping(model, mapping)]
}

export const createChangePhoneModelRules = function () {
    const model = {
        mobile: '',
        smsCode: ''
    }
    const rules = {}
    const mapping = {
        mobile: 'phonenumber',
        smsCode: 'code'
    }
    return [model, rules, () => useModelMapping(model, mapping)]
}

export const createBindPhoneModelRules = function () {
    const model = {
        mobile: '',
        smsCode: '',
        nickName: '',
        sex: '',
        location: '',
        schoolId: '',
        customSchoolName: '',
        customClassName: '',
        examType: '',
        examMajor: ''
    }
    const rules = {}
    const mapping = {
        mobile: 'username',
        smsCode: 'code',
        nickName: 'name'
    }
    return [model, rules, () => useModelMapping(model, mapping)]
}

export const createActivateCardModelRules = function () {
    // bind-profile, bind-card 通用
    const model = {
        username: '',
        password: '',
        gaokaoYear: '',
        location: '',
        schoolId: '',
        customSchoolName: '',
        customClassName: '',
        examType: '',
        examMajor: ''
    }
    const rules = {
        // 字段没有变，使用场景变了，描述名称需要重写
        username: [{required: true, message: '请输入会员卡卡号', trigger: 'error-change'}],
        password: [{required: true, message: '请输入会员卡密码', trigger: 'error-change'}]
    }
    const validateMapping = {
        username: 'username',
        password: 'password'
    }
    const bindMapping = {}
    return [
        model,
        rules,
        () => useModelMapping(model, validateMapping, true),
        () => useModelMapping(model, bindMapping)
    ]
}

export const createBasicInfoModelRules = function (modelRef) {
    // basicInfo中的model，是从currentUser拷贝的，不在这里定义, 这里只为保持一致的使用习惯
    const rules = {}
    const mapping = {
        nickName: 'name',
        location: 'location',
        sex: 'sex',
        customSchoolName: 'customSchoolName',
        customClassName: 'customClassName',
        examType: 'examType',
        examMajor: 'examMajor'
    }
    // strict: true, 因为baseInfo允许编辑的字段是有限的
    return [modelRef, rules, () => useModelMapping(toValue(modelRef), mapping, true)]
}

export const createChangePwdModelRules = function () {
    const model = {
        oldPassword: '',
        newPassword: '',
        newPwdRepeat: ''
    }
    const rules = {}
    const mapping = {newPwdRepeat: false}
    return [model, rules, () => useModelMapping(model, mapping)]
}

/*
* @description 字段转义（字段提取与重命名）
* @param {model} 来源
* @param {mapping} [key:来源自段,value:目标字段]
* @param {strict} 是否严格提取，false:未定义字段保留，true:未定义字段丢弃
* @returns 目标对象
* */
export const useModelMapping = function (model, mapping, strict = false) {
    const result = {}
    _.forIn(model, (v, k) => {
        if (_.has(mapping, k)) {
            const mapK = mapping[k]
            if (mapK) result[mapK] = v
            // empty mapK will ignore
        } else if (!strict) {
            result[k] = v
        }
    })
    return result
}