<template>
  <v-form ref="form" v-model="valid" class="login-form" @submit.prevent>
    <div>
      <v-row dense no-gutters class="justify-space-between">
        <template v-for="(item, index) in props.items.options">
          <slot :name="item.prevSlot"></slot>
          <v-col :key="item.key" v-if="!item.hide" :cols="item.col || '12'" class="position">
            <template v-if="item.slotTitle">
              <div :class="item.class" :style="item.slotTitleStyle">{{ item.slotTitle }}</div>
            </template>
            <div class="d-flex" :class="item.flexStyle || 'flex-row'">
              <v-text-field
                v-if="['text', 'password', 'number'].includes(item.type)"
                :type="item.type"
                v-model="item.value"
                :rules="item.rules"
                :disabled="item.disabled"
                :density="item.dense || 'compact'"
                :color="item.color"
                :label="item.label"
                :placeholder="item.placeholder || item.label"
                variant="outlined"
                :width="item.width"
                :autofocus="item.autofocus"
                :class="item.class"
                :suffix="item.suffix"
                :append-inner-icon="item.appendIcon"
                :clearable="item.clearable"
                :readonly="item.readonly"
                :prepend-inner-icon="item.prependInnerIcon"
                hide-spin-buttons
                @wheel="$event => handleWheel($event, item)"
                @keyup.enter="item.keyupEnterNative && item.keyupEnterNative(index)"
                @click="item.click && item.click(index)"
                @click:append-inner="item.clickAppendInner"
                @change="handleChange(item)"
              />
              <v-autocomplete
                v-if="item.type === 'autocomplete'"
                :rules="item.rules"
                v-model="item.value"
                :attach="!item.noAttach"
                :loading="item.loading"
                :label="item.label"
                :placeholder="item.placeholder || item.label"
                :items="item.items"
                :item-text="item.itemText || 'label'"
                :item-value="item.itemValue || 'value'"
                variant="outlined"
                :density="item.dense || 'compact'"
                :disabled="item.disabled"
                :multiple="item.multiple"
                :clearable="item.clearable"
                :search="item.searchInput"
                :hide-no-data="item.hideNoData"
                :no-data-text="item.noDataText || 'No data available'"
                :hide-selected="item.hideSelected"
                @change="handleChange(item)"
              >
                <template v-if="item.slotAppendItem" v-slot:append-item>
                  <slot :name="item.slotAppendItem" :item="item"></slot>
                </template>
                <template v-if="item.prependItem" #prepend-item>
                  <slot :name="item.prependItem" :item="item"></slot>
                </template>
              </v-autocomplete>
              <!-- autocomplete2 多选纸片样式 -->
              <v-autocomplete
                v-if="item.type === 'autocomplete2'"
                v-model="item.value"
                :rules="item.rules"
                :attach="!item.noAttach"
                :loading="item.loading"
                :label="item.label"
                :placeholder="item.placeholder || item.label"
                :items="item.canCreate ? [inputUpdateValue, ...item.items].filter(Boolean) : item.items"
                :item-text="item.itemText || 'label'"
                :item-value="item.itemValue || 'value'"
                variant="outlined"
                :density="item.dense || 'compact'"
                :multiple="item.multiple"
                :clearable="item.clearable"
                :search-input="item.searchInput"
                :hide-no-data="item.hideNoData"
                :hide-selected="item.hideSelected"
                :readonly="item.readonly"
                @change="handleChange(item)"
                @update:search-input="$event => item.canCreate ? inputUpdateValue = $event : inputUpdateAutocomplete($event)"
                :hide-details="!item.showDetails"
                deletable-chips
                cache-items
                small-chips
              ></v-autocomplete>
              <v-combobox
                v-if="item.type === 'combobox'"
                :rules="item.rules"
                v-model="item.value"
                :attach="true"
                :label="item.label"
                :placeholder="item.placeholder || item.label"
                :items="item.items"
                :item-text="item.itemText || 'label'"
                :item-value="item.itemValue || 'value'"
                variant="outlined"
                :density="item.dense || 'compact'"
                :clearable="item.clearable"
                :disabled="item.disabled"
                @change="handleChange(item)"
              >
                <template v-if="item.hasIcon" v-slot:selection="data">
                  <v-icon color="blue darken-2">{{ data.item.label }}</v-icon>
                </template>
                <!-- <template v-if="item.hasIcon" v-slot:item="data">
                  <v-list-item-avatar>
                    <v-icon>{{ data.item.label }}</v-icon>
                  </v-list-item-avatar>
                  <v-list-item-content>
                    {{ data.item.label }}
                  </v-list-item-content>
                </template> -->
              </v-combobox>
              <v-textarea
                v-if="item.type === 'textarea'"
                :rules="item.rules"
                v-model="item.value"
                :label="item.label"
                :placeholder="item.placeholder || item.label"
                :no-resize="!item.resize"
                variant="outlined"
                :density="item.dense || 'compact'"
                :rows="item.rows || 3"
                :disabled="item.disabled"
                @change="handleChange(item)"
              ></v-textarea>
              <v-radio-group
                v-if="item.type === 'ifRadio'"
                v-model="item.value"
                :disabled="item.disabled"
                mandatory
                row
                @change="handleChange(item)"
              >
                <template v-slot:label>
                  <div :style="`width: ${item.width || 120}px;`">{{ item.label }}</div>
                </template>
                <v-radio
                  v-for="radio in item.items"
                  :key="`${item.key}_radio_${radio.label}`"
                  :readonly="radio.readonly"
                  :label="radio.label"
                  :value="radio.value"
                  class="mr-8"
                ></v-radio>
              </v-radio-group>
              <template v-if="item.type === 'checkbox'">
                <div style="width: 120px;" class="mt-4 label text-left">{{ item.label }}</div>
                <div :style="item.style">
                  <v-checkbox
                    v-model="item.value"
                    v-for="k in item.items"
                    :key="k.key"
                    :label="k.label"
                    :color="item.color"
                    :value="k.value"
                    :readonly="k.readonly"
                    hide-details
                    :multiple="true"
                    class="mr-3"
                  ></v-checkbox>
                </div>
              </template>
              <v-file-input
                v-if="item.type === 'upload'"
                :prepend-icon="item.prependIcon || ''"
                :append-icon="item.appendIcon"
                :append-outer-icon="item.appendOuterIcon"
                :show-size="item.showSize"
                variant="outlined"
                :density="item.dense || 'compact'"
                v-model="item.value"
                :placeholder="item.placeholder || item.label"
                :hint="item.hint"
                :rules="item.rules"
                :label="item.label"
                :persistent-hint="item.persistentHint"
                :loading= "item.loading"
                :disabled="item.disabled"
                :multiple="item.multiple"
                :success="item.success"
                :error="item.error"
                :accept="item.accept || '.xlsx, .xls, .csv, .pdf, .txt, .doc'"
                @change="handleChange(item)"
              >
                <template v-if="item.selfAppend" #append>
                  <slot :name="item.selfAppend" :data="item.value"></slot>
                </template>
              </v-file-input>
              <v-color-picker
                v-if="item.type === 'colorPicker'"
                class="mb-5"
                v-model="item.value"
                :elevation="item.elevation || 5"
                :dot-size="item.dotSize || 25"
                :show-swatches="item.showSwatches || false"
                swatches-max-height="200"
                :mode="item.mode || 'hexa'"
                :hide-mode-switch="true"
                @input="item.change"
              />
              <template v-if="item.type === 'switch'">
                <span v-if="item.describe"> {{ item.describe }} </span>
                <span class="ml-2" v-if="item.trueLabel"> {{ item.trueLabel }}</span>
                <v-switch
                  dense hide-details class="mt-0 ml-2 pa-0"
                  v-model="item.value"
                  :label="item.label"
                  :disabled="item.disabled || false"
                  :color="item.color || 'primary'"
                  :true-value="(item.trueValue !== undefined) ? item.trueValue : true"
                  :false-value="(item.falseValue !== undefined) ? item.falseValue : false"
                ></v-switch>
                <span v-if="item.falseLabel"> {{ item.falseLabel }} </span>
              </template>
              <template v-if="item.type === 'date'">
                <div class="d-flex" style="margin-bottom: 22px;">
                  <span class="label d-flex align-center" :style="`width: ${item.width || 120}px;`">{{ item.label }}</span>
                  <!-- <date-picker
                    :is-valid="isValid"
                    :option="{ ...item.option, disabled: item.disabled }"
                    v-model="item.value"
                    :style="item.style"
                    @change="item.value = $event; handleChange(item); handleCheck(item)"></date-picker> -->
                </div>
              </template>
              <template v-if="item.slotName">
                  <slot :name="item.slotName" :item="item"></slot>
              </template>
            </div>
          </v-col>
        </template>
      </v-row>
    </div>
    <slot></slot>
  </v-form>
</template>

<script setup>
// import DatePicker from '@/components/Form/datePicker.vue'
import { ref, defineEmits  } from 'vue'
defineOptions({ name: 'form-index' })
const props = defineProps({items: Object})
const inputUpdateValue = ref('')
const form = ref()
const valid = ref(false)
const isValid = ref(true)
const emit = defineEmits(['inputUpdateAutocomplete', 'change'])

const handleWheel = (event, item) => {
  if (item.type !== 'number') return
  event.preventDefault()
  if (event.deltaY > 0) {
    item.value--
  } else {
    item.value++
  }
  handleChange(item)
}

const handleCheck = (e) => {
  if (e.type !== 'date' || e.hide || !e.rules) return
  const rules = e.rules[0]
  const check = rules(e.value)
  if (typeof check === 'string') {
    e.option.error = true
    e.option.errorMsg = check
    return
  }
  e.option.error = false
  e.option.errorMsg = null
}

const validateTime = () => {
  isValid.value = true
  props.items.options.forEach((e) => {
    if (e.type !== 'date' || e.hide || !e.rules) return
    const rules = e.rules[0]
    const check = rules(e.value)
    if (typeof check === 'string') {
      isValid.value = false
      e.option.error = true
      e.option.errorMsg = check
    } else {
      e.option.error = false
      e.option.errorMsg = null
    }
  })
  return isValid.value
}

const validate = () => {
  const form = form.value.validate()
  const time = validateTime()
  return form && time
}

const inputUpdateAutocomplete = (val) => {
  emit('inputUpdateAutocomplete', val)
}

const resetValidation = () => {
  form.value.resetValidation()
}
const reset = () => {
  form.value.reset()
}
const handleChange = (item) => {
  if (item.type === 'date' && item.value) item.option.validate = false
  if (item?.change) item.change(item.value, item)
  emit('change', false)
}
</script>

<style lang="scss" scoped>
.position {
  position: relative;
}
.label {
  font-size: 14px;
  color: rgba(0, 0, 0, .6);
}
</style>
