<template>
  <n-select
    v-model:value="state.selectVal"
    :options="state.options"
    :disabled="disabled"
    :multiple="props.config.multiple"
    :clearable="clearable"
    :placeholder="placeholder"
    :filterable="true"
    :filter="filterFunc"
    @focus="handleFocus"
    @blur="handleBlur"
    @update:value="handleChange"
  />
</template>
<script setup>
import {
  reactive,
  onBeforeMount,
  watch,
  getCurrentInstance,
  computed,
  ref,
  onMounted,
} from "vue";

import { processError, processSuccess } from "@/utils/helper/message";
import { getParamsByObj } from "@/utils/helper/form";
const currentInstance = getCurrentInstance();
const { $request } = currentInstance.appContext.config.globalProperties;

const emit = defineEmits(["triggerChangeVal"]);
let props = defineProps({
  config: Object,
  fatherData: Object,
  defaultVal: [Number, String, Array, Boolean],
  clearable: {
    type: Boolean,
    default: () => true,
  },
  options: {
    type: Array,
    default: () => [],
  },
  disabled: {
    type: Boolean,
    default: () => false,
  },
  placeholder: {
    type: String,
    default: () => "",
  },
  size: {
    // middle large small
    type: String,
    default: () => "middle",
  },
  optionWithZero: {
    type: Boolean,
    default: () => false,
  },
  pageType: {
    type: String,
    default: () => "edit",
  },
  refreshCount: {
    type: Number,
    default: () => 0,
  },
  clearCount: {
    type: Number,
  },
});
const state = reactive({
  selectVal: null,
  options: [],
});
watch(
  () => props.defaultVal,
  () => {
    if (!props.optionWithZero && props.defaultVal === 0) {
      state.selectVal === null;
      return;
    }
    if (typeof props.defaultVal === "boolean") {
      state.selectVal = props.defaultVal ? 1 : 2;
      return;
    }
    state.selectVal = props.defaultVal;
  }
);
// 监听options变化,如果options变化，需要重新设置options
watch(
  () => props.options,
  () => {
    state.options = props.options;
  }
);
watch(
  () => props.refreshCount,
  () => {
    state.options = [];
    let config = props.config?.config?.optionConfig;
    if (config) {
      let url = config.url;
      let params = getParamsByObj({}, config.params, props.fatherData);
      if (config.type === "get") {
        $request.HTTP.components.getDataByParams(url, params).then(
          (res) => {
            if (res.status === 0 || res.status === 200) {
              let resData = config.resDataField
                ? res.data[config.resDataField]
                : res.data;
              if (Array.isArray(resData)) {
                resData.forEach((item) => {
                  item.label = item[config.labelField] || item.label;
                  item.value = item[config.valueField] || item.value;
                  if (item[config.labelSecondField]) {
                    item.label += `(${item[config.labelSecondField]})`;
                  }
                });
                state.options = resData;
              }
            } else {
              processError(res.msg || "获取数据失败");
            }
          },
          (err) => {
            processError(err.response.data.msg || "获取数据失败");
          }
        );
        return;
      }
      $request.HTTP.components.postDataByParams(url, params).then(
        (res) => {
          if (res.status === 0 || res.status === 200) {
            if (config.specialResDataField === "BatchTime") {
              if (Array.isArray(res.data.BatchTime)) {
                let arr = [];
                res.data.BatchTime.forEach((item) => {
                  arr.push({
                    label: item,
                    value: item,
                  });
                });
                state.options = arr;
              }
              return;
            }
            let resData = config.resDataField
              ? res.data[config.resDataField]
              : Array.isArray(res.data.Data)
              ? res.data.Data
              : res.data;
            if (Array.isArray(resData)) {
              resData.forEach((item) => {
                item.label = item[config.labelField] || item.label;
                item.value = item[config.valueField] || item.value;
                if (item[config.labelSecondField]) {
                  item.label += `(${item[config.labelSecondField]})`;
                }
              });
              state.options = resData;
            }
          } else {
            processError(res.msg || "获取数据失败");
          }
        },
        (err) => {
          processError(err.response.data.msg || "获取数据失败");
        }
      );
    } else if (props.config?.options) {
      state.options = props.config.options;
    }
  },
  { deep: true }
);
watch(
  () => props.clearCount,
  () => {
    state.selectVal = props.defaultVal;
  }
);
onBeforeMount(() => {
  let config = props.config?.config?.optionConfig;
  if (props.config?.config?.requestByRefresh) {
    return;
  }

  if (config) {
    let url = config.url;
    let params = getParamsByObj({}, config.params, props.fatherData);
    if (config.type === "get") {
      $request.HTTP.components.getDataByParams(url, params).then(
        (res) => {
          if (res.status === 0 || res.status === 200) {
            let resData = config.resDataField
              ? res.data[config.resDataField]
              : res.data;
            if (Array.isArray(resData)) {
              resData.forEach((item) => {
                item.label = item[config.labelField] || item.label;
                item.value = item[config.valueField] || item.value;
                if (item[config.labelSecondField]) {
                  item.label += `(${item[config.labelSecondField]})`;
                }
              });
              state.options = resData;
            }
          } else {
            processError(res.msg || "获取数据失败");
          }
        },
        (err) => {
          processError(err.response.data.msg || "获取数据失败");
        }
      );
      return;
    }
    $request.HTTP.components.postDataByParams(url, params).then(
      (res) => {
        if (res.status === 0 || res.status === 200) {
          if (config.specialResDataField === "BatchTime") {
            if (Array.isArray(res.data.BatchTime)) {
              let arr = [];
              res.data.BatchTime.forEach((item) => {
                arr.push({
                  label: item,
                  value: item,
                });
              });
              state.options = arr;
            }
            return;
          }

          let resData = config.resDataField
            ? res.data[config.resDataField]
            : Array.isArray(res.data.Data)
            ? res.data.Data
            : res.data;
          if (Array.isArray(resData)) {
            resData.forEach((item) => {
              item.label = item[config.labelField] || item.label;
              item.value = item[config.valueField] || item.value;
              if (item[config.labelSecondField]) {
                item.label += `(${item[config.labelSecondField]})`;
              }
            });
            state.options = resData;
          }
        } else {
          processError(res.msg || "获取数据失败");
        }
      },
      (err) => {
        processError(err.response.data.msg || "获取数据失败");
      }
    );
  } else if (props.config?.config?.options) {
    state.options = props.config?.config.options;
  } else if (props.options) {
    state.options = props.options;
  }
  if (!props.optionWithZero && props.defaultVal === 0) {
    state.selectVal === null;
    return;
  }
  // 框架select不支持boolean类型，所以需要转换一下 1 true 2 false 不用0，是因为0有特殊处理过
  if (typeof props.defaultVal === "boolean") {
    state.selectVal = props.defaultVal ? 1 : 2;
    state.options.forEach(
      (item) => (item.value = item.value === 1 || item.value === true ? 1 : 2)
    );
    return;
  }
  state.selectVal = props.defaultVal;
});
onMounted(() => {
  generateRandomId();
});
const handleChange = (value) => {
  if (props.config?.multiple) {
    return emit("triggerChangeVal", { val: value });
  }
  if (value === undefined || value === null) {
    emit("triggerChangeVal", {
      val: value,
      selectOpt: {
        label: "",
        value:
          Object.prototype.toString.call(props.defaultVal) ===
            "[object Number]" && props.optionWithZero
            ? 0
            : null,
      },
    });
    return;
  }
  let returnObj = JSON.parse(
    JSON.stringify(state.options.filter((item) => item.value === value)[0])
  );
  if (typeof props.defaultVal === "boolean") {
    returnObj.value = returnObj.value === 1 ? true : false;
  }
  emit("triggerChangeVal", { val: value, selectOpt: returnObj });
};

const handleBlur = () => {};

const handleFocus = () => {};
const getPopupContainer = () => {
  if (props.config?.config?.body) {
    return document.body;
  }
  return document.getElementById(randomId.value);
};
const filterFunc = (input, option) => {
  return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
const randomId = ref("");
const generateRandomId = () => {
  let characters =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  let randomIdValue = "";

  do {
    randomIdValue = "";

    for (let i = 0; i < 10; i++) {
      let randomIndex = Math.floor(Math.random() * characters.length);
      randomIdValue += characters.charAt(randomIndex);
    }
  } while (randomIdValue === randomId.value);

  randomId.value = randomIdValue;
};
</script>

<style lang="scss" scoped>
.ant-select-disabled.ant-select:not(.ant-select-customize-input)
  .ant-select-selector {
  color: #000 !important;
}
</style>
