<template>
  <div>
    <a-input
      :class="[style && Object.keys(style).length > 0 ? 'customStyle' : '']"
      :style="{ width: width }"
      v-model:value="popupValue"
      :placeholder="placeholder"
      :addonBefore="addonBefore"
      :addonAfter="addonAfter"
      :disabled="disabled"
      :bordered="bordered"
      autoComplete="off"
      :size="size"
      allowClear
      @click="showDialog"
      @change="handleChange"
    >
      <template #prefix v-if="prefix">
        <Icon :icon="prefix" />
      </template>
      <template #suffix v-if="suffix">
        <Icon :icon="suffix" />
      </template>
    </a-input>
    <FormItemRest>
      <MultipleSelect
        ref="MultipleSelectRef"
        v-model:multipleDialog="multipleDialog"
        :popupType="popupType"
        :dataSourceOptions="dataSourceOptions"
        :params="params"
        v-model:value="defaultVal"
        v-model:popupValue="popupValue"
        :labelField="labelField"
        :valueField="valueField"
        :datasourceType="datasourceType"
        :dicOptions="dicOptions"
        :apiConfig="apiConfig"
        v-model:selectedDataSource="selectedDataSourceVal"
        :mainKey="mainKey"
        :subTableIndex="index"
        :pageSize="pageSize"
        :assoTitle="assoTitle"
        :api="api"
        :outputParams="outputParams"
        @get-list="getList"
        @submit="handleSubmit"
      />
    </FormItemRest>
  </div>
</template>
<script lang="ts" setup>
  import { ref, watch, nextTick, inject, onMounted, computed } from 'vue';
  import { Form } from 'ant-design-vue';
  import { Icon } from '/@/components/Icon';
  import MultipleSelect from './components/MultipleSelect.vue';
  import { camelCaseString, isValidJSON } from '/@/utils/event/design';

  const props = defineProps({
    defaultSelect: { type: String },
    popupType: { type: String },
    value: { type: String },
    labelField: { type: String, default: 'label' },
    valueField: { type: String, default: 'value' },
    placeholder: { type: String },
    addonBefore: { type: String },
    addonAfter: { type: String },
    prefix: { type: String },
    suffix: { type: String },
    disabled: { type: Boolean },
    params: { type: [Array, Object, String, Number] },
    dataSourceOptions: { type: Array },
    dicOptions: { type: Array },
    //数据来源 默认为空  如果不为空 则参数 api
    datasourceType: String,
    apiConfig: { type: Object },
    bordered: {
      type: Boolean,
      default: true,
    },
    mainKey: String,
    index: Number,
    size: String,
    //填表按钮绑定使用
    prestrainField: String,
    pageSize: { type: Number, default: 10 },
    assoTitle: { type: String },
    api: {
      type: Function,
      default: null,
    },
    outputParams: {
      type: Array,
    },
    style: Object,
    width: String,
  });
  const FormItemRest = Form.ItemRest;
  const formModel = inject<any>('formModel', null);
  const isCamelCase = inject<boolean>('isCamelCase', false);
  const multipleDialog = ref<boolean>(false);
  const popupValue = ref('');
  const defaultVal = ref<string | undefined>('');
  const selectedDataSourceVal = ref<any[]>([]);
  const MultipleSelectRef = ref();
  const dataSourceList = ref<string[]>([]);
  const isAdd = ref(false);

  const emit = defineEmits(['update:value', 'change']);

  watch(
    () => props.value,
    () => {
      nextTick(async () => {
        if (props.value && MultipleSelectRef.value && dataSourceList.value.length <= 0) {
          await MultipleSelectRef.value.getDatasourceList();
        }
        await getSubDatasourceList();
        if (props.defaultSelect && props.value === props.defaultSelect) {
          setFormModel();
        }
      });
    },
    {
      immediate: true,
    },
  );

  const getList = (list) => {
    dataSourceList.value = list;
  };

  const showDialog = () => {
    multipleDialog.value = true;
    MultipleSelectRef.value?.setSelected(selectedDataSourceVal.value);
  };

  const handleSubmit = (saveValue) => {
    isAdd.value = true;
    emit('update:value', saveValue);
    emit('change');
  };

  const getSubDatasourceList = async () => {
    defaultVal.value = props.value;
    selectedDataSourceVal.value = [];
    popupValue.value = '';
    // if (isAdd.value) return;

    let showValueArr: string[] = [];

    const selectedArr = props.value ? props.value.split(',') : [];
    if (dataSourceList.value.length > 0)
      for (let i = 0; i < dataSourceList.value.length; i++) {
        let item = dataSourceList.value[i];
        for (let j = 0; j < selectedArr.length; j++) {
          let selected = selectedArr[j];
          if (item[props.valueField] == selected) {
            selectedDataSourceVal.value.push(item);
          }
        }
      }

    showValueArr = selectedDataSourceVal.value.map((item: any) => {
      return item[props.labelField];
    });
    popupValue.value = showValueArr.length ? showValueArr.join(',') : props.value!;
  };

  const handleChange = (e) => {
    if (!e.target.value) {
      emit('update:value', e.target.value);
      emit('change');
      MultipleSelectRef.value.setFormModel(true);
    }
  };
  onMounted(async () => {
    if (props.datasourceType === 'api') {
      props.apiConfig?.apiParams?.forEach((params) => {
        params.tableInfo?.forEach((o) => {
          if (o.bindType == 'data') {
            let val = isValidJSON(o.value);
            let field = '';
            if (val && val.bindTable) {
              let table = !isCamelCase
                ? val.bindTable + 'List'
                : camelCaseString(val.bindTable + '_List');
              field = !isCamelCase ? val.bindField : camelCaseString(val.bindField);
              formModel &&
                formModel[table!][props.index || 0] &&
                formModel[table!][props.index || 0][field];
            } else if (val && val.bindField) {
              field = !isCamelCase ? val.bindField : camelCaseString(val.bindField);
              formModel && formModel[field];
            }
          }
        });
      });
      // getSubDatasourceList();
      await MultipleSelectRef.value?.getDatasourceList();
    }
  });
  const setFormModel = (isNull?) => {
    if (props.popupType === 'associate') {
      let assoConfig;
      if (props.api && props.outputParams) assoConfig = props.outputParams;

      switch (props.datasourceType) {
        case 'datasource':
          assoConfig = props.dataSourceOptions;
          break;
        case 'dic':
          assoConfig = props.dicOptions;
          break;
        case 'api':
          assoConfig = props.apiConfig?.outputParams;
          break;
      }
      if (!formModel) return;

      assoConfig?.map((item: any) => {
        if (item.bindField) {
          let value = '';
          if (selectedDataSourceVal.value.length) {
            value = selectedDataSourceVal.value![0][item.name];
          } else if (popupValue.value) {
            const selected = dataSourceList.value.find(
              (x) => x[props.prestrainField!] === props.value,
            );
            if (selected) {
              value = selected[item.name];
            }
          }
          let bindField = !isCamelCase ? item.bindField : camelCaseString(item.bindField);
          let bindTable = '';
          if (item.bindTable) {
            bindTable = !isCamelCase
              ? item.bindTable + 'List'!
              : camelCaseString(item.bindTable + '_List')!;
          }
          let val = isNull ? '' : value;
          if (props.mainKey) {
            if (!item.bindTable) {
              formModel[bindField!] = val;
            } else {
              formModel[props.mainKey][props.index!][bindField!] = val;
            }
          } else {
            if (item.bindTable) {
              formModel[bindTable][0][bindField!] = val;
            } else {
              formModel[bindField!] = val;
            }
          }
        }
      });
    }
  };

  const color = computed(() => {
    return props.style?.color;
  });
  const backgroundcolor = computed(() => {
    return props.style
      ? props.style['background-color'] || (props.disabled ? '#f5f5f5' : '#fff')
      : '#fff';
  });
  const border = computed(() => {
    return props.style?.border || '1px solid #d9d9d9';
  });
  const fontsize = computed(() => {
    return props.style ? props.style['font-size'] : '14px';
  });
  const fontstyle = computed(() => {
    return props.style ? props.style['font-style'] : 'normal';
  });
  const customwidth = computed(() => {
    return props.style?.width;
  });
  const height = computed(() => {
    return props.style?.height || '32px';
  });
  const textalign = computed(() => {
    return props.style ? props.style['text-align'] : 'left';
  });
</script>
<style scoped lang="less">
  .customStyle {
    width: v-bind(customwidth);
    background-color: v-bind(backgroundcolor);
    height: v-bind(height);
    border: v-bind(border) !important;

    :deep(.ant-input-wrapper) {
      width: inherit;
    }

    :deep(.ant-input) {
      font-size: v-bind(fontsize);
      font-style: v-bind(fontstyle);
      color: v-bind(color);
      text-align: v-bind(textalign);
      background-color: inherit;
    }
  }
</style>
