// components/dynamicForm/index.js
import formatTime from './utils/formatTime';

Component({
  /**
   * 组件的属性列表
   */
  properties: {
    formData: Array,
    showSubmitBtn: {
      type: Boolean,
      value: true
    },
    toSubmit: Number
  },
  //监听数据变化, 当toSubmit 值变化时, 代表父组件点击提交案例事件
  observers: {
    'toSubmit': function (e) {
      if (e) {
        this.formSubmit();
      }
    },
    'formData': function () {
      this.formInit();
    }
  },
  /**
   * 组件的初始数据
   */
  data: {
    pickerMap: {},
    fileMap: {},
    inputMap: {}
  },
  lifetimes: {
    attached: function () {
      this.formInit();
    },
    moved: function () { },
    detached: function () { },
  },
  pageLifetimes: {
    // 组件所在页面的生命周期函数
    show: function () { },
    hide: function () { },
    resize: function () { },
  },
  /**
   * 组件的方法列表
   */
  methods: {
    //表单初始化
    formInit() {

      const pickerMap = {}, fileMap = {}, inputMap = {}, dateMap = {};//存储各表单变化后的值,表单id为索引
      const pickers = [], files = [], inputs = [], datePickers = [];
      this.data.formData.forEach(val => {
        switch (val.type) {
          case 'picker':
            pickers.push(val);
            break;
          case 'file':
            files.push(val);
            break;
          case 'input':
          case 'textarea':
            inputs.push(val);
            break;
          case 'date':
            datePickers.push(val);
            break;
          default:
            break;
        }
      });
      pickers.forEach(val => {
        pickerMap[val.id] = {
          original: val,
          hasChoose: val.defaultIdx != 'undefined',
          error:null,
          idx: val.defaultIdx || 0
        };
      });
      files.forEach(val => {
        fileMap[val.id] = {
          original: val,
          error: null,
          list: val.fileList
        };
      });
      inputs.forEach(val => {
        inputMap[val.id] = {
          original: val,
          value: val.defaultValue || '',
          placeholder: val.placeholder,
          error: null,
          rules: val.rules ? val.rules.map(val => {
            val.regular = new RegExp(val.regular);
            return val;
          }) : []
        };
      });
      datePickers.forEach(val => {
        dateMap[val.id] = {
          original: val,
          config: val.config,
          completeTime: val.completeTime,
          show: false,
          hasChoose: !!val.config.initStartTime,
          error: null,
          startDate: val.config.initStartTime || formatTime(),
          endDate: val.config.initEndTime || formatTime()
        };
        if (!val.completeTime){
          dateMap[val.id].startDate = dateMap[val.id].startDate.split(' ')[0];
          dateMap[val.id].endDate = dateMap[val.id].endDate.split(' ')[0];
        }
      });
      this.setData({
        pickers,
        inputs,
        datePickers,
        files,
        pickerMap,
        inputMap,
        fileMap,
        dateMap
      });
    },
    //提交表单
    formSubmit() {
      let formData = {};
      const { pickerMap, inputMap, dateMap, fileMap } = this.data;
      for (let i in this.data) { //获取表单数据后缀为Map
        if (i.match(/Map$/)) {
          formData = Object.assign({}, formData, this.data[i]);
        }
      }
      let hasError = false;
      for (let i in formData) {//循环验证所有表单数据规则
        let info = formData[i];
        if (info.original.type === 'input' || info.original.type === 'textarea') {
          if (!info.value){
            if (info.original.isRequired){
              info.error = info.original.lable + '不可为空';
              hasError = true;
            }
          } else if (info.rules){
            for (let val of info.rules) {
              if (!info.value.match(val.regular)) {
                info.error = val.tips || '格式有误';
                hasError = true;
                break;
              }
            }
          }
          this.setData({
            [`inputMap.${i}`]: info
          });
        } else if (info.original.type === 'file') {
          if (info.list.length === 0 && info.original.isRequired) {
            let error = '请选择文件';
            if (info.original.accept === 'video') {
              error = '请选择视频';
            } else if (info.original.accept === 'image') {
              error = '请选择图片';
            }
            info.error = error;
            hasError = true;
            this.setData({
              [`fileMap.${i}`]: info
            });
          }
        } else if (info.original.type === 'picker' || info.original.type === 'date'){
          if (!info.hasChoose && info.original.isRequired){
            info.error = '请选择' + info.original.lable;
            hasError = true;
            this.setData({
              [`${info.original.type}Map.${i}`]: info
            });
          }
        }
      }
      if (hasError) {
        wx.showToast({
          title: '表单填写有误',
          icon: 'none'
        });
        return;
      }
      this.triggerEvent('dynamicFormSubmit', formData);
      console.log(formData);

    },
    //更新数据劫持
    updateData(key,val){
      this.setData({
        [key]: val
      });
      this.triggerEvent('dynamicFormChange', { key, val});
    },
    //显示选择器
    datePickerShow(e) {
      if (e.target.dataset.disabled) {
        return;
      }
      this.setData({
        [`dateMap.${e.target.dataset.id}.show`]: true
      });
    },
    //隐藏时间选择器
    datePickerHide(id) {
      if (typeof id === 'object') {
        id = id.target.id;
      }
      this.setData({
        [`dateMap.${id}.show`]: false
      });
    },
    //设置选择器时间
    setPickerTime(e) {
      const {dateMap} = this.data;
      const { startTime, endTime } = e.detail;
      const date = dateMap[e.target.id];
      if (!date.hasChoose){
        date.hasChoose = true;
        date.error = null;
      }
      date.show = false;
      date.startDate = date.completeTime ? startTime :startTime.split(' ')[0];
      date.endDate = date.completeTime ?endTime :endTime.split(' ')[0];
      this.updateData(`dateMap.${e.target.id}`,date);
    },
    //输入框
    onInput(e) {
      const { value } = e.detail;
      const info = this.data.inputMap[e.target.id] || {};
      if (!info) {
        return;
      }
      info.value = e.detail.value;
      info.error = null;
      if (info.rules && info.value) {
        for (let val of info.rules) {
          if (!info.value.match(val.regular)) {
            info.error = val.tips || '格式有误';
            break;
          }
        }
      }
      this.updateData(`inputMap.${e.target.id}`, info);
    },
    //picker选择
    onPickerChange(e) {
      const { id } = e.target;
      const picker = this.data.pickerMap[id];
      if(!picker.hasChoose){
        picker.hasChoose = true;
        picker.error = null;
      }
      picker.idx = e.detail.value;
      picker.data = this.data.pickers.filter(val => val.id === id)[0].range[e.detail.value];
      this.updateData(`pickerMap.${e.target.id}`, picker);
    },
    // 选择文件
    onFileRead(e) {
      console.log(e);
      for (let val of e.detail.file) {
        const size = this.data.fileMap[e.target.id].original.maxSize;
        if (val.size > size * 1024 * 1024) {
          wx.showToast({
            title: `请选择${size}MB以内的文件`,
            icon: 'none'
          });
          return;
        }
      }
      const files = this.data.fileMap[e.target.id];
      files.error = null;
      files.list = files.list.concat(e.detail.file);
      this.updateData(`fileMap.${e.target.id}`, files);
    },
    //删除文件
    onFileDelete(e) {
      console.log(e);
      const files = this.data.fileMap[e.target.id].list;
      files.splice(e.detail.index, 1);
      this.updateData(`fileMap.${e.target.id}.list`, files);
    }
  }
});
