<template>
  <div class="s-field items-start">
    <div v-for="(field,index) in fields">
      <!--<div
        class="s-field row no-wrap items-start"
        :class="{
          's-field-floating': childHasLabel(field),
          's-field-no-label': !field.label,
          's-field-with-error': hasError(field),
          's-field-dark': isDark(field)
        }"
      >-->
      <div
        class="s-field items-start"
        :class="{
          's-field-floating': childHasLabel(field),
          's-field-no-label': !field.label,
          's-field-with-error': hasError(field),
          's-field-dark': isDark(field)
        }"
      >
        <s-icon v-if="field.icon" :name="field.icon" class="s-field-icon s-field-margin"></s-icon>
        <s-icon v-else-if="fieldIcon" :name="fieldIcon" class="s-field-icon s-field-margin"></s-icon>
        <div v-else-if="field.insetIcon" class="s-field-icon"></div>
        <div v-else class="s-field-icon"></div>
        <!--<div class="row col">-->
        <div>
          <!--<div
            v-if="hasLabel(field) && (showLabel === true || field.showLabel === true)"
            class="s-field-label col-xs-12  s-field-margin"
            :class="`col-sm-${labelWidth(field)}`"
          >
            <div class="s-field-label-inner row items-center">
              <span v-if="field.label" v-html="field.label"></span>
              <slot name="label"></slot>
            </div>
          </div>-->
          <!--<div class="s-field-content col-xs-12 col-sm">-->
          <div class="s-field-content col-sm-6">
            <!--<slot></slot>-->
            <div v-if="field.type === undefined || field.type.toLowerCase() === 'text'" class="form-group" v-bind:class="{ 'form-group--error': Object($v.model[field.model]).$error }">
              <s-input v-model="model[field.model]" :suffix="field.suffix" :prefix="field.prefix" 
                :disable="field.disable" :placeholder="field.placeholder" :float-label="field.floatlabel" :stack-label="field.floatlabel" @input="$v.model[field.model].$touch()"
                @focus="$event.target.select()"/>
            </div>
            <div v-else-if="field.type.toLowerCase() === 'textarea'" class="form-group" v-bind:class="{ 'form-group--error': Object($v.model[field.model]).$error }">
              <s-input v-model="model[field.model]" type="textarea" :suffix="field.suffix" :disable="field.disable" :prefix="field.prefix" 
                :placeholder="field.placeholder" :float-label="field.floatlabel" @input="$v.model[field.model].$touch()" 
                @focus="$event.target.select()" />
            </div>
            <div v-else-if="field.type.toLowerCase() === 'password'" class="form-group" v-bind:class="{ 'form-group--error': Object($v.model[field.model]).$error }">
              <s-input type="password" v-model="model[field.model]" :disable="field.disable" 
                :placeholder="field.placeholder" :float-label="field.floatlabel" @input="$v.model[field.model].$touch()" 
                @focus="$event.target.select()" />
            </div>
            <div v-else-if="field.type.toLowerCase() === 'number'" class="form-group" v-bind:class="{ 'form-group--error': Object($v.model[field.model]).$error }">
              <s-input type="number" v-model="model[field.model]" :placeholder="field.placeholder" :float-label="field.floatlabel" 
              @input="$v.model[field.model].$touch()" @focus="$event.target.select()" />
            </div>
            <div v-else-if="field.type.toLowerCase() === 'date' || field.type.toLowerCase() === 'datetime' || field.type.toLowerCase() === 'time'">
              <q-datetime type="date" v-model="model[field.model]" :float-label="field.floatlabel" 
                :min="field.range.min" :max="field.range.max" :default-selection="field.defaultSelection" @input="$v.model[field.model].$touch()" />
            </div>
            <div v-else-if="field.type.toLowerCase() === 'date-range'">
              <s-datetime-range inverted color="amber" type="date" v-model="model[field.model]" :min="field.range.min" :max="field.range.max" />
            </div>
            <div v-else-if="field.type.toLowerCase() === 'select'">
              <s-autocomplete v-model="model[field.model]" @search="search" :id="field.model" 
                :min-characters="field.minCharacters === undefined ? 0 : field.minCharacters"
                :max-characters="field.maxCharacters === undefined ? 6 : field.maxCharacters"
                :allowOther="field.allowOther"
                @selected="selected" :delay="0">
                <q-search v-model="model[field.model]" @input="$v.model[field.model].$touch()"></q-search>
              </s-autocomplete>
            </div>
            <div v-else-if="field.type.toLowerCase() === 'numeric'">
              <q-numeric v-model="model[field.model]" class="full-width" :min="field.range.min" :max="field.range.max" 
              @input="$v.model[field.model].$touch()">ewqe
              </q-numeric>
            </div>
            <div v-else-if="field.type === 'toggle'">
              <q-toggle class="orange" v-model="model[field.model]" v-bind:value="setCheckValue(model[field.model])" 
              @input="checkValue(model[field.model])"></q-toggle>
            </div>
            <div v-else-if="field.type === 'radioSelect'">
              <q-select type="radio" v-model="model[field.model]" :options="field.options" class="full-width"></q-select>
            </div>
            <div v-else-if="field.type === 'checkSelect'">
              <q-select type="checkbox" v-model="model[field.model]" :options="field.options" class="full-width"></q-select>
            </div>

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

  </div>
</template>

<style scoped src="../bootstrape/css/bootstrap.css">
</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: ''
    },
    showLabel: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      input: {}
    }
  },
  created () {
  },
  computed: {
  },
  provide () {
    return {
      __field: this
    }
  },
  methods: {
    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, () => {
      })
    },
    __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: {
    model2: {
      handler: function (val, oldVal) {
        // this.model = this.model2
      }
    }
  }
}
</script>
