<template>
  <q-form ref="myForm" class="my-form row fit">
    <div
      :class="['item', item.col || 'col-12']"
      v-for="(item, index) in state.config"
      :key="index"
    >
      <template v-if="item.solt">
        <div class="form-item-solt fit">
          <slot :name="item.solt"></slot>
        </div>
      </template>
      <template v-else-if="item.type === 'password'">
        <div class="item-content">
          <div class="label-title" :class="{ 'text-required': item.required }">
            {{ item.label }}
          </div>
          <q-input
            :type="item.isPwd ? 'password' : 'text'"
            v-model="formValue[item.fild]"
            v-bind="item.bind"
            :dense="
              item.bind.dense === undefined ? props.dense : item.bind.dense
            "
            :disable="
              item.bind.disable === undefined
                ? props.disable
                : item.bind.disable
            "
            :readonly="
              item.bind.readonly === undefined
                ? props.readonly
                : item.bind.readonly
            "
          >
            <template v-slot:append>
              <q-icon
                :name="item.isPwd ? 'visibility_off' : 'visibility'"
                class="cursor-pointer"
                @click="item.isPwd = !item.isPwd"
              />
            </template>
          </q-input>
        </div>
      </template>
      <template v-else-if="item.type === 'date'">
        <div class="item-content">
          <div class="label-title" :class="{ 'text-required': item.required }">
            {{ item.label }}
          </div>
          <date-time-pick
            :dense="
              item.bind.dense === undefined ? props.dense : item.bind.dense
            "
            :disable="
              item.bind.disable === undefined
                ? props.disable
                : item.bind.disable
            "
            :readonly="
              item.bind.readonly === undefined
                ? props.readonly
                : item.bind.readonly
            "
            format24h
            v-model="formValue[item.fild]"
            :config="item.bind"
            :label="item.label"
            :label-required="item.required"
          />
        </div>
      </template>
      <template v-else-if="item.type === 'time'">
        <div class="item-content">
          <div class="label-title" :class="{ 'text-required': item.required }">
            {{ item.label }}
          </div>
          <time-pick
            format24h
            v-model="formValue[item.fild]"
            :config="item.bind"
            :dense="
              item.bind.dense === undefined ? props.dense : item.bind.dense
            "
            :disable="
              item.bind.disable === undefined
                ? props.disable
                : item.bind.disable
            "
            :readonly="
              item.bind.readonly === undefined
                ? props.readonly
                : item.bind.readonly
            "
          />
        </div>
      </template>
      <template v-else-if="item.type === 'dateMultiple'">
        <div class="item-content">
          <div class="label-title" :class="{ 'text-required': item.required }">
            {{ item.label }}
          </div>
          <date-multiple
            v-model="formValue[item.fild]"
            :config="item.bind"
            :dense="
              item.bind.dense === undefined ? props.dense : item.bind.dense
            "
            :disable="
              item.bind.disable === undefined
                ? props.disable
                : item.bind.disable
            "
            :readonly="
              item.bind.readonly === undefined
                ? props.readonly
                : item.bind.readonly
            "
          />
        </div>
      </template>
      <template v-else-if="item.type === 'dateRange'">
        <div class="item-content">
          <div class="label-title" :class="{ 'text-required': item.required }">
            {{ item.label }}
          </div>
          <date-range
            v-model="formValue[item.fild]"
            :config="item.bind"
            :dense="
              item.bind.dense === undefined ? props.dense : item.bind.dense
            "
            :disable="
              item.bind.disable === undefined
                ? props.disable
                : item.bind.disable
            "
            :readonly="
              item.bind.readonly === undefined
                ? props.readonly
                : item.bind.readonly
            "
          />
        </div>
      </template>
      <template v-else-if="item.type === 'color'">
        <div class="item-content">
          <div class="label-title" :class="{ 'text-required': item.required }">
            {{ item.label }}
          </div>
          <color-pick
            v-model="formValue[item.fild]"
            :config="item.bind"
            :dense="
              item.bind.dense === undefined ? props.dense : item.bind.dense
            "
            :disable="
              item.bind.disable === undefined
                ? props.disable
                : item.bind.disable
            "
            :readonly="
              item.bind.readonly === undefined
                ? props.readonly
                : item.bind.readonly
            "
          />
        </div>
      </template>
      <template v-else>
        <div class="item-content">
          <div class="label-title" :class="{ 'text-required': item.required }">
            {{ item.label }}
          </div>
          <q-input
            v-if="item.type !== 'select'"
            :type="item.type"
            v-model="formValue[item.fild]"
            v-bind="item.bind"
            :dense="
              item.bind.dense === undefined ? props.dense : item.bind.dense
            "
            :disable="
              item.bind.disable === undefined
                ? props.disable
                : item.bind.disable
            "
            :readonly="
              item.bind.readonly === undefined
                ? props.readonly
                : item.bind.readonly
            "
          />
          <q-select
            v-if="item.type === 'select'"
            v-bind="item.bind"
            v-model="formValue[item.fild]"
            :dense="
              item.bind.dense === undefined ? props.dense : item.bind.dense
            "
            :disable="
              item.bind.disable === undefined
                ? props.disable
                : item.bind.disable
            "
            :readonly="
              item.bind.readonly === undefined
                ? props.readonly
                : item.bind.readonly
            "
          />
        </div>
      </template>
    </div>
  </q-form>
</template>
<script lang="ts" setup>
import { onMounted, reactive, ref, watch } from 'vue';
import DateTimePick from './DateTimePick.vue';
import TimePick from './TimePick.vue';
import DateMultiple from './DateMultiple.vue';
import DateRange from './DateRange.vue';
import ColorPick from './ColorPick.vue';
import { cloneDeep, isObjEqual } from 'src/common/utils';

interface Props {
  config: any;
  modelValue: any;
  disable?: boolean;
  readonly?: boolean;
  dense?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
  config: () => {
    return {};
  },
  modelValue: () => {
    return {};
  },
  disable: false,
  readonly: false,
  dense: false,
});

defineExpose({
  validate,
  reset,
});

const emit = defineEmits<{
  (e: 'update:modelValue', value: any): void;
}>();

const myForm = ref<any>(null);

const state = reactive({
  config: cloneDeep(props.config),
});
const formValue = ref<any>(cloneDeep(props.modelValue));

watch(
  () => props.config,
  (val) => {
    state.config = cloneDeep(val);
  },
  {
    deep: true,
  }
);

watch(
  () => props.modelValue,
  (val: any) => {
    if (!isObjEqual(val, formValue.value)) {
      formValue.value = val;
    }
  },
  {
    deep: true,
  }
);

watch(
  formValue.value,
  (val) => {
    emit('update:modelValue', val);
  },
  { deep: true }
);

onMounted(() => {
  //
});

async function validate() {
  return await myForm.value.validate().then((success: any) => {
    if (success) {
      return true;
    } else {
      return false;
    }
  });
}

function reset() {
  myForm.value.resetValidation();
}
</script>

<style lang="scss" scoped>
.item {
  padding: $padding-sm;
}
.item-content {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
}
.label-title {
  height: 22px;
  font-size: 14px;
  line-height: 22px;
  color: $gray-text;
  margin-bottom: 2px;
  display: inline-block;
}
</style>