<template>
  <div id="field">
    <div v-if="field.type !== 'expand'" v-for="(field,index) in filterField"
      :style="formgroup(field)"
       :class="{'s-field-floating': childHasLabel(field),
        's-field-no-label': !field.label,
        's-field-with-error': hasError(field),
        's-field-dark': isDark(field),'form-group': (field.newline && showLabel !== true),'form-group-label': (field.newline && showLabel === true)}">
      <div v-if="field2.type !== 'expand' && field2.display !== false" v-for="(field2,index2) in getFieldLoop(field)" class="row no-wrap main-content">
        <div class="row no-wrap">
          <s-icon v-if="field2.icon" :size="iconSize" :name="field2.icon" class="s-field-margin"></s-icon>
          <s-icon v-else-if="fieldIcon" :size="iconSize" :name="fieldIcon" class="s-field-margin"></s-icon>
          <div v-else-if="field2.insetIcon" class="s-field-icon s-field-margin"></div>
          <!--<div v-else class="s-field-icon s-field-margin"></div>-->
          <div v-if="hasLabel(field2) && (showLabel === true || field2.showLabel === true)" class="like-table">
            <label>
              {{field2.label}}
            </label>
          </div>
        </div>
        <div class="s-field-content fieldgroup">
          <!--<slot></slot>-->
          <div v-if="field2.type === undefined || field2.type.toLowerCase() === 'text'" :class="inputcontrol" v-bind:class="{ 'form-group--error': Object($v.model[field2.model]).$error }">
            <s-input v-model="model[field2.model]" :suffix="field2.suffix" :prefix="field2.prefix"
              :disable="field2.disable" :placeholder="field2.placeholder" :float-label="field2.floatlabel" :stack-label="field2.floatlabel" @input="$v.model[field2.model].$touch()"
              @focus="$event.target.select()"/>
          </div>
          <div v-if="field2.type.toLowerCase() === 'label'" :class="inputcontrol">
            <span>{{model[field2.model]}}</span>
          </div>
          <div v-else-if="field2.type.toLowerCase() === 'textarea'" :class="inputcontrol" v-bind:class="{ 'form-group--error': Object($v.model[field2.model]).$error }">
            <s-input v-model="model[field2.model]" type="textarea" :suffix="field2.suffix" :disable="field2.disable" :prefix="field2.prefix" 
              :placeholder="field2.placeholder" :float-label="field2.floatlabel" :stack-label="field2.floatlabel" @input="$v.model[field2.model].$touch()" 
              @focus="$event.target.select()" />
          </div> 
          <div v-else-if="field2.type.toLowerCase() === 'password'" :class="inputcontrol" v-bind:class="{ 'form-group--error': Object($v.model[field2.model]).$error }">
            <s-input type="password" v-model="model[field2.model]" :disable="field2.disable" 
              :placeholder="field2.placeholder" :float-label="field2.floatlabel" :stack-label="field2.floatlabel" @input="$v.model[field2.model].$touch()" 
              @focus="$event.target.select()" />
          </div>
          <div v-else-if="field2.type.toLowerCase() === 'number'" :class="inputcontrol" v-bind:class="{ 'form-group--error': Object($v.model[field2.model]).$error }">
            <s-input type="number" v-model="model[field2.model]" :placeholder="field2.placeholder" :float-label="field2.floatlabel" 
            @input="$v.model[field2.model].$touch()" :stack-label="field2.floatlabel" @focus="$event.target.select()" />
          </div>
          <div v-else-if="field2.type.toLowerCase() === 'date' || field2.type.toLowerCase() === 'datetime' || field2.type.toLowerCase() === 'time'"
             :class="inputcontrol">
            <s-input-frame class="s-input" :stack-label="field2.floatlabel" :float-label="field2.floatlabel" >
              <q-datetime :type="field2.type.toLowerCase()" v-model="model[field2.model]"
                :min="field2.range.min" :max="field2.range.max" :default-selection="field2.defaultSelection" @input="$v.model[field2.model].$touch()" />
            </s-input-frame>
          </div>
          <div v-else-if="field2.type.toLowerCase() === 'date-range'" :class="inputcontrol">
            <s-input-frame class="s-input" :stack-label="field2.floatlabel" :float-label="field2.floatlabel" >
              <s-datetime-range :color="field2.color" 
                type="date" v-model="model[field2.model]" :min="field2.range.min" :max="field2.range.max"
                :default-from="field2.defaultSelectionFrom" :default-to="field2.defaultSelectionTo"/>
            </s-input-frame>
          </div>
          <div v-else-if="field2.type.toLowerCase() === 'datetime-range'" :class="inputcontrol">
            <s-input-frame class="s-input" :stack-label="field2.floatlabel" :float-label="field2.floatlabel" >
              <s-datetime-range :color="field2.color" 
                type="datetime" v-model="model[field2.model]" :min="field2.range.min" :max="field2.range.max"
                :default-from="field2.defaultSelectionFrom" :default-to="field2.defaultSelectionTo"/>
            </s-input-frame>
          </div>
          <div v-else-if="field2.type.toLowerCase() === 'time-range'" :class="inputcontrol">
            <s-input-frame class="s-input" :stack-label="field2.floatlabel" :float-label="field2.floatlabel" >
              <s-datetime-range :color="field2.color" 
                type="time" v-model="model[field2.model]" :min="field2.range.min" :max="field2.range.max"
                :default-from="field2.defaultSelectionFrom" :default-to="field2.defaultSelectionTo"/>
            </s-input-frame>
          </div>
          <div v-else-if="field2.type.toLowerCase() === 'select'" :class="inputcontrol">
              <s-autocomplete v-model="model[field2.model]" @search="search" :id="field2.model" 
                :min-characters="field2.minCharacters === undefined ? 0 : field2.minCharacters"
                :max-characters="field2.maxCharacters === undefined ? 6 : field2.maxCharacters"
                :allowOther="field2.allowOther"
                @selected="selected" :delay="0">
                <s-input-frame class="s-input" :stack-label="field2.floatlabel" :float-label="field2.floatlabel" >
                  <q-search v-model="model[field2.model]" @input="$v.model[field2.model].$touch()"></q-search>
                </s-input-frame>
              </s-autocomplete>
          </div>
          <div v-else-if="field2.type.toLowerCase() === 'chips'" :class="inputcontrol" v-bind:class="{ 'form-group--error': Object($v.model[field2.model]).$error }">
            <s-chips style="text-align:left" group textfield v-model="model[field2.model]" :value="model[field2.model]" :keys="keys" 
              :disable="field2.disable" :readonly="readonly" :search="search" 
              @search="search" @input="input" :id="field2.model">
            </s-chips>
          </div> 
          <div v-else-if="field2.type.toLowerCase() === 'numeric'" :class="inputcontrol">
            <s-input-frame class="s-input" :stack-label="field2.floatlabel" :float-label="field2.floatlabel" >
              <q-numeric v-model="model[field2.model]" :min="field2.range.min" :max="field2.range.max" 
                @input="$v.model[field2.model].$touch()">
              </q-numeric>
            </s-input-frame>
          </div>
          <div v-else-if="field2.type === 'toggle'" :class="inputcontrol">
            <s-input-frame class="s-input" :stack-label="field2.floatlabel" :float-label="field2.floatlabel" >
              <q-toggle class="orange" :disable="field2.disable" v-model="model[field2.model]" v-bind:value="setCheckValue(model[field2.model])" 
                @input="checkValue(model[field2.model])"></q-toggle>
            </s-input-frame>
          </div>
          <div v-else-if="field2.type === 'radioSelect'" :class="inputcontrol">
            <s-input-frame class="s-input" :stack-label="field2.floatlabel" :float-label="field2.floatlabel" >
              <q-select type="radio" :disable="field2.disable" v-model="model[field2.model]" :options="field2.options"></q-select>
            </s-input-frame>
          </div>
          <div v-else-if="field2.type === 'checkSelect'" :class="inputcontrol">
            <s-input-frame class="s-input" :stack-label="field2.floatlabel" :float-label="field2.floatlabel" >
              <q-select type="checkbox" :disable="field2.disable" v-model="model[field2.model]" :options="field2.options"></q-select>
            </s-input-frame>
          </div>
          <div v-else-if="field2.type.toLowerCase() === 'knob'" :class="inputcontrol">
            <s-knob v-model="model[field2.model]" :disable="field2.disable" :min="field2.range.min" :max="field2.range.max" 

              @change="knobChange" ></s-knob>
          </div>
          <div v-else-if="field2.type.toLowerCase() === 'rating'" :class="inputcontrol">
            <s-rating v-model="model[field2.model]" :color="field2.color"
              :disable="field2.disable" :readonly="field2.readonly"
              :icon="field2.ratingIcon"
              :size="field2.size === undefined ? '3em': field2.size"
              :max="field2.range.max" />
          </div>
          <div v-else-if="field2.type.toLowerCase() === 'slider'" :class="inputcontrol">
            <s-slider v-model="model[field2.model]" :min="field2.range.min" :max="field2.range.max" 
            :step="field2.range.step" :decimals="field2.range.decimals"
            :label="field2.sliderLabel" :snap="field2.snap" :square="field2.square"
            >
            </s-slider>
          </div>

          <span class="form-group__message" style="color:red;font-weight:bold" v-if="Object($v.model[field2.model]).required !==undefined && !Object($v.model[field2.model]).required">{{field2.label}}為必填欄位</span>
          <span class="form-group__message warning" style="color:red;font-weight:bold" v-if="Object($v.model[field2.model]).minLength !==undefined && !Object($v.model[field2.model]).minLength">{{field2.label}}長度至少需 {{Object($v.model[field2.model]).$params.minLength.min}} 字.</span>
          <span class="form-group__message warning" style="color:red;font-weight:bold" v-if="Object($v.model[field2.model]).between !==undefined && !Object($v.model[field2.model]).between">{{field2.label}}需介於</span>
          <span class="form-group__message warning" style="color:red;font-weight:bold" v-if="Object($v.model[field2.model]).alpha !==undefined && !Object($v.model[field2.model]).alpha">{{field2.label}}須為英文字母</span>
          <span class="form-group__message warning" style="color:red;font-weight:bold" v-if="Object($v.model[field2.model]).alphaNum !==undefined && !Object($v.model[field2.model]).alphaNum">{{field2.label}}須為英文字母或數字</span>
          <span class="form-group__message warning" style="color:red;font-weight:bold" v-if="Object($v.model[field2.model]).numeric !==undefined && !Object($v.model[field2.model]).numeric">{{field2.label}}須為數字</span>
          <span class="form-group__message warning" style="color:red;font-weight:bold" v-if="Object($v.model[field2.model]).email !==undefined && !Object($v.model[field2.model]).email">{{field2.label}}須為email格式</span>
          <span class="form-group__message warning" style="color:red;font-weight:bold" v-if="Object($v.model[field2.model]).url !==undefined && !Object($v.model[field2.model]).url">{{field2.label}}須為url格式</span>
          <span class="form-group__message warning" style="color:red;font-weight:bold" v-if="Object($v.model[field2.model]).sameAs !==undefined && !Object($v.model[field2.model]).sameAs">{{field2.label}}需與{{Object($v.model[field2.model]).$params.sameAs.eq}}相同</span>
          <div v-if="hasBottom(field2)" :class="{'s-field-no-input': hasNoInput(field2)}" class="s-field-bottom row no-wrap">
            <div v-if="hasError(field2) && field2.errorLabel" class="s-field-error col" v-html="errorLabel(field2)"></div>
            <div v-else-if="field2.helper" class="s-field-helper col" v-html="field2.helper"></div>
            <div v-else class="col"></div>
            <div v-if="counter(field2)" class="s-field-counter col-auto">{{ counter(field2) }}</div>
          </div>
        </div>
      </div>
    </div>
  </div>

</template>

<!--<style scoped src="../bootstrape/css/bootstrap.css"></style>-->

<style scoped>
  html,
  body {
    height: 100%;
    padding: 0;
    margin: 0;
    font-family: Arial, Helvetica, sans-serif;
  }
  textarea {
    font-family: Arial, Helvetica, sans-serif;
  }
  
  .main-content {
    padding: 20px;
    width: 500px;
  }
  
  @media (max-width: 768px) {
    .main-content {
      padding: 20px 8px;
    }
  }

  .change-line {
    display:inline
  }

  /* form specific formatting */
  /* .form-group {
    display: flex;
    flex-direction: row;
  } */
  
  .form-group label {
    flex: none;
    display: block;
    width: 125px;
    font-weight: bold;
    font-size: 1em;
  }
  .form-group label.right-inline {
    text-align: right;  
    padding-right: 8px;
    padding-left: 10px;
    width: auto;
  }
  
  .form-group .input-control {
    flex: 1 1 auto;
    display: block;
    /* margin-bottom: 10px; */
    margin-right: 8px;
    padding: 4px;
    margin-top: 12px;
  }

  /* form specific formatting that with label show */
  /* .form-group-label {
    display: flex;
    flex-direction: row;
  } */
  
  .form-group-label label {
    flex: none;
    display: block;
    width: 125px;
    font-weight: bold;
    font-size: 1em;
    position: relative;
    top:50%;
    transform:translateY(-50%);
  }

  i {
    position: relative;
    top:75%;
    transform:translateY(-50%);
  }

  .form-group-label label.right-inline {
    text-align: right;  
    padding-right: 8px;
    padding-left: 10px;
    width: auto;
  }
  
  .form-group-label .input-control {
    flex: 1 1 auto;
    display: block;
    /* margin-bottom: 10px; */
    margin-right: 8px;
    padding: 4px;
    margin-top: 12px;
  }

  .fieldgroup {
    min-width: 360px
  }

  .fieldgroupLabel {
    min-width: 500px
  }
  
  button {
    padding: 5px 15px;
    margin: 5px;
    min-width: 100px
  }
  
  @media (max-width: 768px) {
    /* .form-group {
      flex-direction: column;
    } */
    /* .form-group .input-control {
      margin-top: 2px;
    } */
    .form-group label.right-inline {
      text-align: left;  
      padding-right: 0;
      padding-left: 0;   
    }
  }

  @media (max-width: 1280px) {
    /* .form-group-label {
      flex-direction: column;
    } */
    /* .form-group-label .input-control {
      margin-top: 2px;
    } */
    .form-group-label label.right-inline {
      text-align: left;  
      padding-right: 0;
      padding-left: 0;   
    }
  }
</style>

<script>
import Vue from 'vue'
import { QIcon } from '../icon'
import Vuelidate from 'vuelidate'
import { required, minLength, maxLength, between, alpha, alphaNum, numeric, email, sameAs, url } from 'vuelidate/lib/validators'
// import moment from 'moment'
Vue.use(Vuelidate)

export default {
  name: 's-fieldGenerate',
  components: {
    QIcon
  },
  props: {
    model: {
      type: Object,
      default: {}
    },
    fields: {
      type: Array,
      default: []
    },
    reference: {
      type: String,
      default: ''
    },
    fieldIcon: {
      type: String,
      default: ''
    },
    colspan: {
      type: Number,
      default: 1
    },
    showLabel: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      // input: {},
      dataIndex: 0,
      fieldLoop: [],
      iconSize: '16',
      keys: [],
      disable: false,
      readonly: false,
      windowWidth: 0,
      windowHeight: 0
    }
  },
  created () {
    this.updatetodo()
  },
  computed: {
    filterField () {
      return this.fields.filter(function (item, index, arr) {
        // return item.newline === true || index === arr.length - 1
        return item.newline === true
      })
    }
  },
  provide () {
    return {
      __field: this
    }
  },
  mounted () {
    this.$nextTick(function () {
      window.addEventListener('resize', this.getWindowWidth)
      window.addEventListener('resize', this.getWindowHeight)
      this.getWindowWidth()
      this.getWindowHeight()
    })
  },
  beforeDestroy () {
    window.removeEventListener('resize', this.getWindowWidth)
    window.removeEventListener('resize', this.getWindowHeight)
  },
  updated () {
  },
  methods: {
    getWindowWidth (event) {
      // this.windowWidth = document.documentElement.clientWidth
      this.windowWidth = document.getElementById('field').clientWidth
    },
    getWindowHeight (event) {
      // this.windowHeight = document.documentElement.clientHeight
      this.windowHeight = document.getElementById('field').clientHeight
    },
    inputcontrol () {
      if (this.windowWidth <= 512) {
        return {
          flex: '1 1 auto',
          display: 'block',
          'margin-right': '8px',
          padding: '4px',
          'margin-top': '2px'
        }
      }
      else {
        return {
          flex: '1 1 auto',
          display: 'block',
          'margin-right': '8px',
          padding: '4px',
          'margin-top': '12px'
        }
      }
    },
    formgroup (field) {
      if (field.newline && this.showLabel !== true) {
        if (this.windowWidth <= 512) {
          return {
            display: 'flex',
            'flex-direction': 'column'
          }
        }
        else {
          return {
            display: 'flex',
            'flex-direction': 'row'
          }
        }
      }
      else if (field.newline && this.showLabel === true) {
        if (this.windowWidth <= 768) {
          return {
            display: 'flex',
            'flex-direction': 'column'
          }
        }
        else {
          return {
            display: 'flex',
            'flex-direction': 'row'
          }
        }
      }
    },
    input (value, keys) {
    },
    updatetodo () {
      var dataIndex = 0
      if (this.colspan === undefined) {
        this.colspan = 2
      }
      this.fields.forEach(
        (field, index) => {
          if (field.range === undefined) {
            field.range = {}
          }

          field.key = index
          if (index === 0) {
            dataIndex = 0
          }
          if (field.colspan === undefined) {
            field.colspan = 1
          }

          if (dataIndex + field.colspan > this.colspan || dataIndex === 0 || field.newline === true) {
            field.newline = true
          }
          else {
            field.newline = false
          }
          dataIndex = dataIndex + field.colspan
          dataIndex = dataIndex % this.colspan
        }
      )
    },
    getFieldLoop (field) {
      var key = field.key
      var list = []

      var flag = false
      var flag2 = false
      // console.log(field)
      this.fields.forEach(
        (value, index) => {
          if (value.key === key) {
            flag = true
          }
          if (flag === true && flag2 === false) {
            if (value.newline === false || value.key === key) {
              list.push(value)
            }
            else if (value.newline === true) {
              flag2 = true
            }
          }
        }
      )
      return list
    },
    checkValue (val) {
      var val2 = false
      if (val === true || val === 1) {
        val2 = true
      }
      else {
        val2 = false
      }
      return val2
    },
    setCheckValue (val) {
      var val2 = false
      if (val === true || val === 1) {
        val2 = false
      }
      else {
        val2 = true
      }
      return val2
    },
    hasError (field) {
      if (field.input !== undefined) {
        return field.input.error || field.error
      }
      else {
        return false
      }
    },
    hasBottom (field) {
      return (field.hasError && field.errorLabel) || field.helper || field.count
    },
    hasLabel (field) {
      return field.label || ['label', 'full'].includes(field.inset)
    },
    childHasLabel (field) {
      if (field.input !== undefined) {
        return field.input.floatLabel || field.input.stackLabel
      }
      else {
        return false
      }
    },
    isDark (field) {
      if (field.input !== undefined) {
        return field.input.dark || field.dark
      }
      else {
        return false
      }
    },
    insetIcon (field) {
      return ['icon', 'full'].includes(field.inset)
    },
    hasNoInput (field) {
      if (field.input !== undefined) {
        return !field.input.$options || field.input.__needsBottom
      }
      else {
        return false
      }
    },
    counter (field) {
      if (field.count) {
        if (field.input !== undefined) {
          const length = field.input.length || '0'
          return Number.isInteger(field.count)
            ? `${length} / ${field.count}`
            : length
        }
        else {
          return 0
        }
      }
    },
    labelWidth (field) {
      if (field.labelWidth === undefined || field.labelWidth.labelWidth === undefined) {
        return 5
      }
      else if (field.labelWidth > 12) {
        return 12
      }
      else if (field.labelWidth < 5) {
        return 5
      }
      else if (typeof field.labelWidth !== 'number') {
        return 5
      }
      else {
        return field.labelWidth
      }
    },
    input2 (val) {
      // console.log(this.model.status)
    },
    beforeSearch (model) {
      this.searchid = model
    },
    search (terms, done, id) {
      this.$emit('search', terms, done, id, this.reference, () => {
      })
    },
    selected (item) {
      this.$emit('selected', item, this.model, () => {
      })
    },
    knobChange (val) {
    },
    __registerInput (vm, needsBottom) {
      vm.__needsBottom = needsBottom
      this.input = vm
    },
    __unregisterInput () {
      this.input = {}
    }
  },
  validations () {
    var object = []
    this.fields.forEach(
      (value, index) => {
        var Bruce = Object.create(null)
        if (value.validations !== undefined) {
          if (value.validations.required === true) {
            Bruce.required = required
          }
          if (value.validations.minLength !== undefined && value.validations.minLength !== '') {
            Bruce.minLength = minLength(value.validations.minLength)
          }
          if (value.validations.maxLength !== undefined && value.validations.maxLength !== '') {
            Bruce.maxLength = maxLength(value.validations.maxLength)
          }
          if (value.validations.between !== undefined && value.validations.between !== '') {
            var res = value.validations.between.split(',')
            if (res.length > 1) {
              Bruce.between = between(res[0], res[1])
            }
          }
          if (value.validations.alpha === true) {
            Bruce.alpha = alpha
          }
          if (value.validations.alphaNum === true) {
            Bruce.alphaNum = alphaNum
          }
          if (value.validations.numeric === true) {
            Bruce.numeric = numeric
          }
          if (value.validations.email === true) {
            Bruce.email = email
          }
          if (value.validations.url === true) {
            Bruce.url = url
          }
          if (value.validations.sameAs !== undefined && value.validations.sameAs !== '') {
            Bruce.sameAs = sameAs(value.validations.sameAs)
          }
        }
        object[value.model] = Bruce
      }
    )
    // var json = JSON.parse(JSON.stringify({ row: this.convertToText(object) }))
    const rules = {}
    var json = { model: Object.assign(rules, object) }
    return json
  },
  watch: {
    fields: {
      handler: function (val, oldVal) {
        this.updatetodo()
      },
      deep: true
    }
  }
}
</script>
