<template>
    <div  class="form-container" @keydown="onKeydown">
        <slot></slot>
    </div>
</template>

<script>
  import { computed } from 'vue';
  import { DomHandler, ObjectUtils ,DataHandler,RowStatus  } from 'primevue/utils';
  
export default {
    name: 'Form',
    emits: ['row-new-init','item-change'],

    props: {
       disabled:{
            type:Boolean,
            default:false
        },
        
        readonly:{
            type:Boolean,
            default:false
        },

        labelWidth: {
            type: [String, Number],
            default: '',
        },
        
        hideRequiredAsterisk: {
            type: Boolean,
            default: false,
        },
    },
    
    provide(){
        return {
            "Form": computed(()=>{
                return {
                     "setFocus": this.setFocus,
                     "primaryData": this.d_primaryData,
                     "onItemChange": this.onItemChange,
                     ...this.$props
                    }
            })
        }
     },
     
     data() {
        return {
            d_primaryData:null,
            d_modified:false
        }
    },

    methods: {
        getChildren() {
            return this.$slots.default ? this.$slots.default() : null;
        },

        recursiveGetChildren(children, results) {
            if (!results) {
                results = [];
            }

            if (children && children.length) {
                children.forEach((child) => {
                        if (child.type.name == 'FormItem') {
                           results.push(child);
                        }
                        else if (child.children && child.children instanceof Array) {
                            this.recursiveGetChildren(child.children, results);
                        }
                        else if(child.children && ( typeof child.children.default )==='function'){
                             this.recursiveGetChildren(child.children.default(), results);
                        }
                });
            }

            return results;
        },
        formItemProp(item, prop) {
            return ObjectUtils.getVNodeProp(item, prop);
        },

       setFocus(field){
           if(!field)
             return;

           setTimeout(() => {
                const itemEl = this.$el.querySelector(`[data-field=${field}`);

                if(itemEl){
                    // itemEl.scrollIntoView && itemEl.scrollIntoView({ block: 'nearest', inline: 'start' });
                    const focusableEl = DomHandler.getFirstFocusableElement(itemEl);

                    focusableEl && focusableEl.focus();
                }
            }, 50);
       },
      
       setData(newData){
           this.d_primaryData = (newData) ? DataHandler.Proxy(newData, 1, this._interalSetModified ) : null ;
           this.d_modified=false;
        },

       getData(){
            return this.d_primaryData ;
        },

       new(){
            let _items = this.items|| [] ;
            let rowData =(this.d_primaryData)? DataHandler.Initialize( this.d_primaryData,1 ,this._interalSetModified ) : {}  ;
            
            for (let i = 0; i <_items.length; i++) {
                const item = _items[i];
                const field= this.formItemProp(item, 'field') || '';
                const initial = this.formItemProp(item, 'initial')  ;
                const colType =  this.formItemProp(item, 'colType') || '';
                
                if (field) {
                    rowData[field] =(initial!==null && initial!==undefined && initial!=='' )? ObjectUtils.initailValue(initial, colType) : null ;
                }
            }

            if(!('rowId' in rowData) || !('originalData' in rowData)){
                rowData=DataHandler.Proxy(rowData,1, this._interalSetModified );
            }

            DomHandler.clearSelection();
            this.$emit('row-new-init', rowData);
            rowData['rowStatus'] = RowStatus.New;
            this.d_primaryData = rowData; 
            this.d_modified=false;

            return rowData;  // 返回新增行的数据，以便对新增行的数据进行赋值 
       }, 

       setItem(fieldName,value){
            this.d_primaryData[fieldName] = value;
        },

        getItem(fieldName){
            return this.d_primaryData[fieldName] ;
        },

        reset(){
            this.d_primaryData = null;
            this.d_modified=false;
        },

        resetUpdate(){
            if(!this.d_primaryData)
                return;

            this.d_primaryData.resetUpdate();
            this.d_modified=false;
        },
        isModified(){
            /*
           if(!this.d_primaryData)
                return false ;

           return (this.d_primaryData.rowStatus=== RowStatus.DataModified ||  this.d_primaryData.rowStatus=== RowStatus.NewModified) ? true:false;
           */
           
           return this.d_modified;
        },

       onKeydown(event){

         var target = event.target || event.srcElement;
         if( (target.nodeName ||'').toUpperCase()==='TEXTAREA')
            return;

         switch (event.code) {
            case 'Enter':
            case 'NumpadEnter':
               {
                const focusableEl = DomHandler.getNextFocusableElement(this.$el , target);

                if(focusableEl )
                {
                   event.preventDefault();
                   event.stopPropagation();
                   focusableEl.focus();
                }
               }

               break;
         }
       },
       onItemChange(event){
          this.$emit('item-change', event);
       },

       _interalSetModified(newData){
           this.d_modified=newData;
        },
    },
    computed:{
        items() {
            let children = this.getChildren();

            if (!children) {
                return;
            }

            return  this.recursiveGetChildren(children, []);
        },
    }
};
</script>

<style>
  
  .form-container{
      padding: 6px ;
   }

  .form-row{
     height: 30px;
     display: flex;
     flex-wrap: nowrap;
     align-items: center;
     margin-bottom: 8px;
   }
   
  .form-row:last-child{
        margin-bottom:  0;
   }

  .form-item{
     display: flex;
     align-items: center;
    
   }

  .form-item-label{
      padding: 0 0.5rem;
      color:#606266;
      text-align: right;
   }
   
 .required::before{
    content: "*";
    color:#db2828;
    margin-right: 4px;
  }

  .form-item-content{
      flex:1;
   }

  .form-item-suffix{
    padding-left: 0.5rem;
    color:#606266;
  }

  .form-item .p-inputtext{
    width:100%;
  }

</style>
