<script setup lang="ts">
import type { SelectValue } from 'ant-design-vue/es/select';

import type { PropType } from 'vue';

import { computed, ref, unref, watch } from 'vue';

import { useVbenModal } from '@vben/common-ui';
import { cn } from '@vben/utils';

import { useVModel } from '@vueuse/core';
import { Input } from 'ant-design-vue';

import { TableApi } from '#/api';
import { Icon } from '#/components/icon';

import FormQuery from './api-popup/api-popup-modal-ignore.vue';

const props = defineProps({
  value: {
    type: [String, Number, Array] as PropType<SelectValue>,
    default: undefined,
  },
  placeholder: {
    type: String as PropType<string>,
    default: '请选择',
  },
  api: {
    type: String as PropType<string>,
    default: '',
  },
  fieldNames: {
    type: Object as PropType<{ label: string; options: any; value: string }>,
    default: () => ({ label: 'label', value: 'value', options: null }),
  },
  multiple: {
    type: Boolean as PropType<boolean>,
    default: false,
  },
});

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

const [FormQueryModal, formQueryApi] = useVbenModal({
  connectedComponent: FormQuery,
});
const isFirstLoad = ref(true);

const modelValue = useVModel(props, 'value', emit, {
  defaultValue: props.value,
  passive: true,
});

const options = ref<Record<string, any>[]>([]);

const displays = computed(() => {
  return unref(options).map((item: any) => item.label);
});

const handleSelect = () => {
  formQueryApi.setData({
    multiple: props.multiple,
    baseData: { name: props.placeholder, code: props.api },
  });
  formQueryApi.open();
};

const handleSuccess = (successData: any) => {
  const { fieldNames } = props;
  const { data, type } = successData;

  let selected = props.multiple
    ? data.map((item: any) => ({
        label: item[fieldNames.label],
        value: item[fieldNames.value],
      }))
    : [{ label: data[fieldNames.label], value: data[fieldNames.value] }];
  if (type === 'append') {
    selected = [unref(options), ...selected];
  }
  options.value = [...new Set(selected)] as Record<string, any>[];

  const value = unref(options)
    .map((item: any) => item.value)
    .join(',');
  // console.log('handleSuccess', options.value, fieldNames, value);

  if (modelValue.value !== value) {
    emit('update:value', value);
  }
};

const fetch = async () => {
  const { value, fieldNames } = props;
  const data = await TableApi.postExecute({
    code: props.api,
    pageIndex: 1,
    pageSize: 1000,
    formData: { _ids: value, _key: fieldNames.value },
  });
  if (data.items) {
    options.value = data.items.map((item: any) => ({
      label: item[fieldNames.label],
      value: item[fieldNames.value],
    }));
  }
  isFirstLoad.value = false;
};

watch(
  () => props.value,
  (value) => {
    if (value) {
      unref(isFirstLoad) && fetch();
    }
  },
  { deep: true },
);
</script>

<template>
  <div class="bc-popup w-full">
    <FormQueryModal :close-on-click-modal="false" @success="handleSuccess" />
    <div
      :class="
        cn(
          'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 border-border relative z-[1000] max-h-96 min-w-32 overflow-hidden rounded-md border',
        )
      "
      class="bc-popup-selector"
    >
      <div
        :class="
          cn(
            'p-1',
            'h-[--radix-select-trigger-height] w-full min-w-[--radix-select-trigger-width]',
          )
        "
        class="bc-popup-selector-overflow"
      >
        <div class="flex flex-1 items-center justify-between">
          <div cclass="flex-1 mr-3">
            <div
              v-for="(item, index) in displays"
              :key="index"
              class="bc-popup-selector-item"
            >
              <div class="bc-popup-selector-item-content">{{ item }}</div>
            </div>
            <div
              v-if="displays.length === 0"
              class="bc-popup-selector-placeholder text-muted-foreground"
              style="opacity: 0.5"
            >
              {{ placeholder }}
            </div>
            <div
              class="bc-popup-selector-item"
              style="width: 0; height: 0; opacity: 0"
            >
              <div style="width: 4px">
                <Input v-model="modelValue" style="height: 0" />
              </div>
            </div>
          </div>
          <div @click="handleSelect">
            <Icon
              class="icon-more bc-popup-selector-btn size-5"
              icon="ic:twotone-more-horiz"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="less" scoped>
.bc-popup {
  margin: 0;
  padding: 0;
  cursor: pointer;

  &-selector {
    &-overflow {
      position: relative;
      display: flex;
      flex: auto;
      max-width: 100%;
      padding: 4px 11px;
    }

    &-item {
      border: 1px solid hsl(var(--border));
      border-radius: 4px;
      display: flex;
      align-items: center;
      padding: 0 8px;
      background: hsl(var(--input-background));

      &-content {
        display: inline-block;
        margin-inline-end: 4px;
        overflow: hidden;
        white-space: pre;
        text-overflow: ellipsis;
      }
    }

    &-btn {
      color: hsl(var(--border));
    }
  }
}
</style>
