<script setup lang="ts">
import { ref, watch, computed, h } from 'vue';
import { Select, Divider, Row } from 'ant-design-vue';
import { ChevronLeft, ChevronRight } from '@vben/icons';
import { postIoTplatformThingModelInfoPageAsync } from '#/api-client';
import { $t } from '#/locales';
import { useDebounceFn } from '@vueuse/core';

interface Props {
  value?: string;
  typeCode?: string | number | null;
  filedType?: string | null;
  ioTPlatform?: number | string | null;
  ioTPlatformProductId?: string | null;
  placeholder?: string;
  disabled?: boolean;
  allowClear?: boolean;
  onResolve?: (item: any | null) => void;
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: $t('common.pleaseSelect') + $t('abp.thingModelInfos.StandardFieldName'),
  disabled: false,
  allowClear: true,
});

const emit = defineEmits<{
  'update:value': [string | undefined];
  change: [string | undefined];
  'item-change': [any | null];
}>();

const VNodes = (props: any) => {
  return props.vnodes;
};

const options = ref<any[]>([]);
const total = ref(0);
const loading = ref<boolean>(false);
const query = ref({
  pageIndex: 1,
  pageSize: 10,
  filter: '',
});

const maxPage = computed(() => Math.ceil((total.value || 0) / query.value.pageSize) || 1);

const fetchData = async () => {
  // 需要平台和产品ID才能获取数据
  if (!props.ioTPlatform || !props.ioTPlatformProductId) {
    options.value = [];
    total.value = 0;
    return;
  }
  loading.value = true;
  try {
    const requestBody: any = {
      pageIndex: query.value.pageIndex,
      pageSize: query.value.pageSize,
      ...(query.value.filter && { searchKeyWords: query.value.filter }),
      ...(props.ioTPlatform && {
        ioTPlatform:
          typeof props.ioTPlatform === 'string'
            ? Number.parseInt(props.ioTPlatform)
            : props.ioTPlatform,
      }),
      ...(props.ioTPlatformProductId && {
        ioTPlatformProductId: String(props.ioTPlatformProductId),
      }),
      ...(props.filedType && { filedType: String(props.filedType) }),
      ...(props.typeCode && !props.filedType && { filedType: String(props.typeCode) }),
    };
    
    const { data } = await postIoTplatformThingModelInfoPageAsync({
      body: requestBody,
    });
    const items = Array.isArray(data?.items) ? data!.items : [];
    const mappedItems = items.map((item: any) => ({
      label: `${item.standardFieldDisplayName || item.ioTPlatformRawFieldName || item.id || ''}`,
      value: item.id || '',
      ...item,
    }));

    // 如果有当前值但不在当前页的选项中，需要添加当前值到选项中
    if (props.value && props.value.trim() !== '' && !mappedItems.find(item => item.value === props.value)) {
      // 如果当前值不在选项中，添加一个占位项
      mappedItems.unshift({
        label: `当前值: ${props.value}`,
        value: props.value,
        displayText: props.value,
        code: props.value,
      });
    }

    options.value = mappedItems;
    total.value = (data as any)?.totalCount || 0;
  } catch (err) {
    console.error('获取标准物模型编码失败:', err);
  } finally {
    loading.value = false;
  }
};

const changePage = (next: number) => {
  if (next === 1) {
    if (query.value.pageIndex >= maxPage.value) return;
    query.value.pageIndex += 1;
  } else {
    if (query.value.pageIndex <= 1) return;
    query.value.pageIndex -= 1;
  }
  fetchData();
};

const onSearch = useDebounceFn((kw: string) => {
  query.value.pageIndex = 1;
  query.value.filter = kw;
  fetchData();
}, 400);

const onChange = (val?: string) => {
  emit('update:value', val);
  emit('change', val);
  if (val) {
    const found = options.value.find((o) => o.value === val) || null;
    emit('item-change', found);
    props.onResolve && props.onResolve(found);
  } else {
    emit('item-change', null);
    props.onResolve && props.onResolve(null);
  }
};

watch(
  () => [props.filedType, props.typeCode, props.ioTPlatform, props.ioTPlatformProductId],
  () => {
    // reset when filedType/typeCode/platform/product changes
    query.value.pageIndex = 1;
    query.value.filter = '';
    options.value = [];
    total.value = 0;
    // 只要有平台和产品ID就可以获取数据，filedType/typeCode 是可选的
    if (props.ioTPlatform && props.ioTPlatformProductId) {
      fetchData();
    }
  },
  { immediate: true },
);

// 监听初始值变化，确保编辑时能正确显示
watch(
  () => props.value,
  (newValue) => {
    if (newValue && newValue.trim() !== '' && props.ioTPlatform && props.ioTPlatformProductId && !options.value.find(item => item.value === newValue)) {
      // 如果有值但不在当前选项中，重新获取数据
      fetchData();
    }
  },
  { immediate: true },
);

</script>

<template>
  <Select
    :value="value"
    :showSearch="true"
    :filter-option="false"
    :options="options"
    :placeholder="placeholder"
    :disabled="disabled"
    :allowClear="allowClear"
    :loading="loading"
    @search="onSearch"
    @change="onChange"
  >
      <template #dropdownRender="{ menuNode: menu }">
        <v-nodes :vnodes="menu" />
        <Divider style="margin: 4px 0" />
        <div @mousedown="(e) => e.preventDefault()">
          <Row type="flex" justify="space-around" align="middle">
            <ChevronLeft @click="changePage(0)" :class="{ 'text-gray-400': query.pageIndex <= 1 }"
              style="cursor: pointer; width: 16px; height: 16px;" />
            <div>{{ `${query.pageIndex}/${maxPage}` }}</div>
            <ChevronRight @click="changePage(1)" :class="{ 'text-gray-400': query.pageIndex >= maxPage }"
              style="cursor: pointer; width: 16px; height: 16px;" />
          </Row>
        </div>
      </template>
    </Select>
</template>

<style lang="less" scoped>
.text-gray-400 {
  color: #9ca3af;
  cursor: not-allowed !important;
}
</style>
