<template>
    <van-form class='formModel' :class='{clear:clear,search:search,readonly: readonly}' @submit='submitFormate' v-model='formModel' :scroll-to-error='true' :validate-first='true' v-if='isMobile == "mobile"&&loading'>
        <van-cell-group inset>
            <template v-for='(item,index) in data'>
                <div class='form' v-if='!item.isHide'  :key='index'>
                    <span class='require' v-if='item.rule&&item.rule.indexOf("notNull") != -1'>*</span>
                    <component :is='item.type' :data='item' v-model='formModel[item.id]' :validator='item.rule&&validator(item)'></component>
                </div>
            </template>
        </van-cell-group>
        <div class='submit-bg'>
            <van-button round block native-type='submit'>
                {{submitName}}
            </van-button>
        </div>
    </van-form>
    <el-form class='formModelpc' :inline='inline||search' :class='{ clear: clear || search, readonly: !!readonly, search: search }' ref='formRef' :model='formModel' :rules='rules' :label-position='labelPosition' :label-width='labelWidth' status-icon v-else-if='loading'>
        <div class='bg'>
            <template v-for='(item,index) in data' >
                <el-form-item v-if='!item.isHide' class='form' :class='{append:item.prepend||item.appendIcon||item.prependIcon||item.append}' :label='item.hideName?"":item.name' :label-width='item.labelWidth'  :key='index'>
                    <component class='formItem' :is='item.type' :data='item' :_p="parent"  :key='index' ></component>
                </el-form-item>
            </template>
            <slot name='default'></slot>
        </div>
        <slot name='submit' v-if="showSubmit&&!readonly">
            <div class='submit' v-if='clear||search'>
                <el-button class='btn' :type="submitType" v-if='onCancel' :plain='!submitType' @click='cancel()'>{{cancelName}}</el-button>
                <el-button class='btn' :type="submitType"  :plain='!submitType' @click='submit()' :loading='submitLoading'>{{submitName}}</el-button>
            </div>
            <div class='submit-bg' v-else>
                <el-button  round block v-if='onCancel' @click='cancel()'>
                    {{cancelName}}
                </el-button>
                <el-button round block @click='submit(formRef)' :loading='submitLoading'>
                    {{submitName}}
                </el-button>
            </div>
        </slot>
    </el-form>
</template>

<script>
import validate from './validate'
import {
    letter,
    isMobile,
    setDefaultAnswer,
    fromEntries,
    entries
} from './utils'
export default {
    components: {
        ...require(`./components` + isMobile)
    },
    props: {
        data: {
            type: Array,
            require: false,
            default () {
                return [{
                    'id': '1',
                    'type': 'input-text',
                    'rule': 'notNull',
                    'name': '您目前的体重？',
                    'note': '【温馨提示。。。】',
                    'isHide': true,
                    'placeholder': '(kg)'
                }]
            }
        },
        submitType:{
            type:String,
            require: false,
        },
        onSubmit: {
            type: Function,
            require: false,
        },
        onCancel: {
            type: Function,
            require: false,
        },
        values: {
            type: Object,
            default () {
                return {}
            }
        },
        clear: {
            type: Boolean,
            default () {
                return true
            }
        },
        inline: {
            type: Boolean,
            require: false,
        },
        labelPosition: {
            type: String,
            default () {
                return 'top'
            }
        },
        labelWidth: {
            type: String,
            default () {
                return '20%'
            }
        },
        loading: {
            type: Boolean,
            default () {
                return true
            }
        },
        submitLoading: {
            type: Boolean,
             default () {
                return undefined
            }
        },
        search: {
            type: Boolean,
            default () {
                return false
            }
        },
        cancelName: {
            type: String,
            default () {
                return '取消'
            }
        },
        submitName: {
            type: String,
            default () {
                return this.search ? '搜索' : this.clear ? '确定' : '提交'
            }
        },
        showWordLimit:{
            type: Boolean,
            default () {
                return true
            }
        },
        showSubmit:{
            type: Boolean,
            default () {
                return true
            }
        },
        readonly:{
            type: Boolean,
            default () {
                return false
            }
        }
    },
    watch:{
        values:{
            handler(newVal){
                console.info(newVal)
                this.formModel = fromEntries(this.newData.filter(a => a.id).map(a => {
                    return [a.id, a.value || newVal[a.id]];
                }))
            },
            deep: true
        }
    },
    data() {
        let {
            values:newValues,
            data:newData,
            submitLoading:newSubmitLoading
        } = this;
        if (!!0 && !newValues.birthday) {
            newValues = setDefaultAnswer(newData);
        }
        return {
            newValues,
            newData,
            isMobile,
            newSubmitLoading,
            formModel:fromEntries(newData.filter(a => a.id).map(a => [a.id, a.value || newValues?newValues[a.id]:null])),
            rules:{
                ...fromEntries(newData.map(a => [a.id, ((item) => {
                    let rules = [];
                    if (item.rule) {
                        const v_rules = item.rule.split(',');
                        for (let i = 0; i < v_rules.length; i++) {
                            rules.push({
                                required: !!v_rules.find(a => a === 'notNull'),
                                name: item.name,
                                trigger: 'change',
                                validator: (rule, value, callback) => {
                                    let error = validate[v_rules[i]](a, value);
                                    callback(error ? new Error(error) : undefined)
                                }
                            });
                        }
                    }
                    return rules;
                })(a)]))
            },
            parent:this
        }
    },
    methods:{
        submit(){
            this.$refs.formRef.validate((valid, fields) => {
                if (valid) {
                    this.submitFormate(this.formModel);
                } else {
                    console.log('error submit!', fields)
                }
                return true
            })
        },
        cancel(){
            if (this.onCancel) {
                this.onCancel();
            }
        },
        submitFormate(values) {
            const newValue = fromEntries(entries(values).filter(a => a[0] != 'undefined'&&a[1] != 'undefined'&&a[1] != undefined).reduce((prev,a) => {
                let key = a[0], value = typeof a[1] === 'number' && isFinite(a[1])?a[1]:a[1].constructor === Object ? JSON.parse(JSON.stringify(a[1])) : a[1].constructor === Array ?a[1]:a[1];
                if(key.indexOf(".") !== -1){
                    let keys =  key.split("."),newValue = {};
                    key = keys[0];
                    newValue[keys[1]] = value;
                    value = newValue
                    let prevIndex, prevValue;
                    prev.map((_a,index) => {
                        if(_a[0] == key){
                            prevValue = _a[1];
                            prevIndex = index;
                        }
                    });
                    if(prevValue){
                        prev[prevIndex] = [key,{
                            ...prevValue,
                            ...value
                        }]
                    }else{
                        prev.push([key,value])  
                    }
                }else{
                    prev.push([key,value])  
                }
                return prev
            },[]));
            if (this.onSubmit) {
                if(this.newSubmitLoading === undefined){
                    this.newSubmitLoading = true;
                }
                let _submit;
                try{
                    _submit = this.onSubmit(newValue, entries(newValue).map(a => {
                        return {
                            'id': a[0],
                            'option': ((id, value) => {
                                const {
                                    answer
                                } = this.newData.find(b => b.id == id) || {};
                                if (answer) {
                                    let option = 'A';
                                    answer.map((a, key) => {
                                        if (a.name == value) {
                                            option = letter[key];
                                        }
                                    })
                                    return option;
                                }
                            })(a[0], a[1]),
                            'answerStr': a[1]
                        }
                    }))
                    if(_submit instanceof Promise){
                        _submit.finally(() => {
                            this.newSubmitLoading = false;
                        })
                    }else if(this.submitLoading === undefined){
                        setTimeout(() => {
                            this.newSubmitLoading = false;
                        },1000)
                    }
                }catch{
                    this.newSubmitLoading = false;
                }
            }
        },
        validator(item){
            if (!item.rule) return
            const v_rules = item.rule.split(',');
            return (val) => {
                let message = null;
                for (let i = 0; i < v_rules.length; i++) {
                    let msg = validate[v_rules[i]](item, val);
                    if (msg) {
                        message = msg;
                        break;
                    }
                }
                return message;
            }
        }
    }

}
</script>

<style lang='less' scoped>
.formModelpc {
    width: calc(100% - 0px);
    background: url(./images/bg.png);
    background-size: 100%;
    height:calc(100% - 40px);
    overflow: auto;
    --van-cell-group-inset-padding: 0 10px;
    --van-cell-group-inset-border-radius: 16px 16px 0 0;
    padding: 20px 0;
    color: #000;
    display: block;
    &.readonly{
        :deep(.el-input.is-disabled .el-input__inner),
        :deep(.el-input__wrapper), 
        :deep(.el-textarea.is-disabled .el-textarea__inner),
        :deep(.el-input-number.is-disabled .el-input-number__decrease, .el-input-number.is-disabled .el-input-number__increase)
        {
            background:transparent;
            border: none;
            cursor: auto;
            text-align: left;
        }
        :deep(.el-input-number .el-input__inner){
            padding:5px 15px;
        }
        :deep(.el-input-number__decrease),:deep(.el-input-number__increase){
            display: none;
        }
    }
    &.el-form--inline {
        width: auto;
        .bg {
            display: flex;
            flex-wrap: wrap;

            .el-form-item {
                margin-bottom: 0;
              
            }
        }
    }

    &.clear {
        --van-cell-group-inset-padding: 0;
        --van-cell-group-inset-border-radius: 0;
        background: unset;

        .bg {
            padding: 0;

            .form {
                &::after {
                    content: unset;
                }
            }
        }

        .submit {
            display: flex;
            margin:  auto 0;
            justify-content: center;
            align-items: flex-end;
            height: 40px;
        }
    }

    &.search {
        padding: 0;
        margin:10px 0;
        height:auto;
        display: flex;
        background:none;
        .submit {
            justify-content: start;
            align-items: center;
            // height:calc(var(--el-input-height, 32px) - 0px);
        }
        :deep(.el-input__wrapper){
            width:150px;
        }
        .bg {
            width:auto;
        }
    }

    .bg {
        margin: var(--van-cell-group-inset-padding);
        border-radius: var(--van-cell-group-inset-border-radius);
        overflow: hidden;
        padding: 20px;
        width:calc(100% - 60px);
        .form {
            position: relative;
            &.append{
                /deep/ .el-form-item__content{
                    margin: 0!important;
                    line-height: 36px!important;
                }
            }
            &::after {
                content: '';
                width: 100%;
                height: 0.05rem;
                position: absolute;
                bottom: -20px;
                left: 0;
            }

            &:nth-last-of-type(1) {
                &::after {
                    content: unset;
                }
            }

            :deep(.formItem) {
                display: flex;
                width:100%;
            }
        }

    }

    .submit {
        height: 20px;
        margin-left: 20px;
        :deep(.el-button){
            padding-top:0;
            padding-bottom:0;
            height:100%;
        }
    }

    .submit-bg {
        width: calc(100% - 10px*2);
        height: 120px;
        background: url(./images/submit_bg.png) no-repeat;
        background-size: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 0 0 16px 16px;
        margin: 0 10px;

        button {
            width: 100px;
            height: 32px;
            line-height: 32px;
            border: none;
            border-radius: 16px;
            font-size: 14px;
            box-shadow: 0.1em 0.3em 1em 0em #6782c4;
            color: #85A1D6;
            font-weight: bold;
            outline: none;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #fff;
        }
    }
}

.formModel {
    width: 100%;
    background: url(./images/bg.png);
    background-size: 100%;
    height: 100%;
    overflow: auto;
    --van-cell-group-inset-padding: 0 10px;
    --van-cell-group-inset-border-radius: 16px 16px 0 0;
    padding: 20px 0px;

    :deep(.van-cell-group--inset) {
        padding: 0 20px;
    }

    .form {
        width: 100%;
        height: 100%;
        position: relative;

        &:last-of-type {
            :deep(.van-field__body) {
                &::after {
                    content: unset;
                }
            }
        }

        :deep(.van-field__body) {
            position: relative;
            padding: 0 0 12px 0px;

            &::after {
                content: '';
                width: 100%;
                height: 1px;
                background-image: linear-gradient(to right, #ccc 0%, #ccc 50%, transparent 50%);
                background-size: 8px 1px;
                background-repeat: repeat-x;
                position: absolute;
                bottom: 0;
                left: 0;
            }

        }

        :deep(.van-cell) {
            flex-direction: column;
            position: relative;

            .van-field__label {
                width: 100%;
                padding-bottom: 10px;
            }

            .van-cell__right-icon {
                position: absolute;
                right: 0;
                top: 45px;
            }
        }
 
        .require {
            position: absolute;
            left: 0px;
            top: 10px;
            color: #c70000;
            z-index: 1;
        }
    }

    .submit-bg {
        width: calc(100% - 10px*2);
        height: 120px;
        background: url(./images/submit_bg.png) no-repeat;
        background-size: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 0 0 16px 16px;
        margin: 0 10px;

        button {
            width: 100px;
            height: 32px;
            line-height: 32px;
            border: none;
            border-radius: 16px;
            font-size: 14px;
            box-shadow: 0.1em 0.3em 1em 0em #6782c4;
            color: #85A1D6;
            font-weight: bold;
            outline: none;
            background-color: #fff;
        }
    }

}
</style>
