<template>
  <div class="flex items-center">
    <a-input-group compact>
      <template v-if="props.params?.dictSort">
        <a-form-item class="select" :style="{ width: props.dictWidth + '%' }">
          <a-select
            v-model:value="dictValue"
            :options="dictData"
            @change="handleSelectChange"
            style="width: 100%"
          />
        </a-form-item>
        <a-form-item class="input" :style="{ width: 100 - props.dictWidth + '%' }">
          <a-input
            v-if="!props.isInputNum"
            v-model:value="inputValue"
            @change="handleInputChange"
            style="width: 100%"
            :maxLength="props.inputLength"
          />
          <a-input-number
            v-else
            v-model:value="inputValue"
            @change="handleInputChange"
            style="width: 100%"
            :min="props.numMin"
            :max="props.numMax"
          />
        </a-form-item>
      </template>
      <template v-else>
        <a-form-item class="input" :style="{ width: 100 - props.dictWidth + '%' }">
          <a-input
            v-if="!props.isInputNum"
            v-model:value="inputValue"
            @change="handleInputChange"
            style="width: 100%"
            :maxLength="props.inputLength"
          />
          <a-input-number
            v-else
            v-model:value="inputValue"
            @change="handleInputChange"
            style="width: 100%"
            :min="props.numMin"
            :max="props.numMax"
          />
        </a-form-item>
        <a-form-item class="select" :style="{ width: props.dictWidth + '%' }">
          <a-select
            v-model:value="dictValue"
            :options="dictData"
            @change="handleSelectChange"
            style="width: 100%"
          />
        </a-form-item>
      </template>
    </a-input-group>
  </div>
</template>

<script lang="ts">
  import { computed, defineComponent, watch, ref, onMounted, unref } from 'vue';
  import { propTypes } from '/@/utils/propTypes';
  import { useDebounceFn } from '@vueuse/core';
  import { isFunction } from '/@/utils/is';
  import { get } from 'lodash-es';

  export default defineComponent({
    name: 'ApiInputDict',
    props: {
      api: { type: Function as PropType<(arg?: Recordable) => Promise<Recordable>> },
      params: { type: Object },
      immediate: { type: Boolean, default: true },
      resultField: propTypes.string.def(''),
      placeholder: { type: String },
      dictWidth: { type: Number, default: 24 },
      isInputNum: { type: Boolean, default: false },
      numMax: { type: Number, default: 999 },
      numMin: { type: Number, default: 0 },
      inputLength: { type: Number, default: 100 },
    },
    emits: ['change'],
    setup(props, { attrs, emit }) {
      const dictData = ref([]);
      const getAttrs = computed(() => {
        return {
          ...(props.api ? { dictData: unref(dictData) } : {}),
          ...attrs,
        } as any;
      });
      const inputValue = ref('');
      const dictValue = ref('');
      const isFirstLoaded = ref<Boolean>(false);
      const loading = ref(false);
      watch(
        () => attrs.formValues,
        (v: any) => {
          // console.log('🚀 ~ file: ApiComplex.vue:102 ~ setup ~ v:', v);
          const field = v.field;
          const defaultValue = v?.model?.[field];
          dictValue.value = defaultValue?.dictValue;
          inputValue.value = defaultValue?.input;
        },
      );
      watch(
        () => props.params?.dictSort,
        v => {
          console.log('dictSort v', v);
        },
        { deep: true },
      );
      watch(
        () => props.params?.dictCode,
        () => {
          !unref(isFirstLoaded) && fetch();
        },
        { deep: true },
      );
      watch(
        () => props.immediate,
        v => {
          v && !isFirstLoaded.value && fetch();
        },
      );

      onMounted(() => {
        props.immediate && fetch();
      });

      async function fetch() {
        const api = props.api;
        if (!api || !isFunction(api)) return;
        dictData.value = [];
        try {
          loading.value = true;
          const res = await api(props.params);
          if (Array.isArray(res)) {
            dictData.value = res;
            dictValue.value = dictValue.value || dictData.value[0]['value'];
            return;
          }
          if (props.resultField) {
            dictData.value = get(res, props.resultField) || [];
            dictValue.value = dictValue.value || dictData.value[0]['value'];
          }
        } catch (error) {
          console.warn(error);
        } finally {
          loading.value = false;
        }
      }

      function emitChange() {
        debouncedFn();
      }

      // 防抖
      const debouncedFn = useDebounceFn(() => {
        const data = {
          input: inputValue.value,
          dictValue: dictValue.value,
          dictCode: props.params?.dictCode,
        };
        emit('change', data);
      }, 1000);

      // 复选改变
      function handleSelectChange(value) {
        console.log('🚀 ~ file: ApiInputDict.vue:137 ~ handleSelectChange ~ e:', value);
        dictValue.value = value;
        emitChange();
      }

      // 输入改变
      function handleInputChange(e) {
        console.log('🚀 ~ file: ApiInputDict.vue:161 ~ handleInputChange ~ e:', e);
        if (props.isInputNum) {
          inputValue.value = e;
        } else {
          inputValue.value = e.target.value || '';
        }
        emitChange();
      }

      return {
        getAttrs,
        loading,
        props,
        dictValue,
        inputValue,
        dictData,
        handleSelectChange,
        handleInputChange,
      };
    },
  });
</script>

<style lang="less" scoped>
  .fan-basic-form .ant-form-item {
    border: 0;
  }
</style>
