<script setup lang="ts">
import { computed, ref } from 'vue';

import { ChevronLeft, ChevronRight } from '@vben/icons';

import { useDebounceFn } from '@vueuse/core';
import { Divider, Row, Select } from 'ant-design-vue';

import { postDeviceInfoPage } from '#/api-client';
import { $t } from '#/locales';

interface Props {
  value?: string;
  placeholder?: string;
  disabled?: boolean;
  allowClear?: boolean;
}

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

const emit = defineEmits<{
  change: [string];
  'device-change': [any]; // 添加设备信息变化事件
  'update:value': [string];
}>();

const VNodes = (_, { attrs }: any) => {
  return attrs.vnodes;
};

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

// 最大页码
const maxPage = computed(() => {
  return Math.ceil(total.value / query.value.pageSize);
});

/**
 * 获取设备列表数据
 */
const fetchData = async () => {
  loading.value = true;
  try {
    const { data } = await postDeviceInfoPage({
      body: {
        pageIndex: query.value.pageIndex,
        pageSize: query.value.pageSize,
        SearchKeyword: query.value.SearchKeyword,
      },
    });

    if (data?.items) {
      options.value = data.items.map((item) => ({
        label: `${item.deviceName || item.deviceAddress} (${item.deviceAddress})`,
        value: item.deviceAddress, // 使用设备地址作为值
        ...item, // 保留完整数据
      }));
      total.value = data.totalCount || 0;
    }
    loading.value = false;
  } catch (error) {
    console.error('获取设备列表失败:', error);
    loading.value = false;
  }
};

/**
 * 上下页
 * @param type 1: 下一页, 0: 上一页
 */
const changePage = (type: number) => {
  if (type === 1) {
    if (query.value.pageIndex >= maxPage.value) return;
    query.value.pageIndex += 1;
    fetchData();
  } else {
    if (query.value.pageIndex <= 1) return;
    query.value.pageIndex -= 1;
    fetchData();
  }
};

/**
 * 设备搜索
 */
const fetchDevice = useDebounceFn((value: string) => {
  query.value.pageIndex = 1;
  query.value.SearchKeyword = value;
  fetchData();
}, 500);

// 处理值变化
const handleValueChange = (value: string) => {
  emit('update:value', value);
  emit('change', value);

  // 发送选中的设备信息
  if (value) {
    const selectedDevice = options.value.find(
      (option) => option.value === value,
    );
    if (selectedDevice) {
      emit('device-change', selectedDevice);
    }
  } else {
    emit('device-change', null);
  }
};

// 初始化加载数据
fetchData();

// 暴露方法给父组件调用
defineExpose({
  getSelectedDevice: () => {
    if (props.value) {
      return options.value.find((option) => option.value === props.value);
    }
    return null;
  },
});
</script>

<template>
  <Select :value="value" :show-search="true" @search="fetchDevice" :options="options" :placeholder="placeholder"
    :filter-option="false" :disabled="disabled" :allow-clear="allowClear" :loading="loading"
    @change="handleValueChange">
    <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=" width: 16px; height: 16px;cursor: pointer" />
          <div>{{ `${query.pageIndex}/${maxPage}` }}</div>
          <ChevronRight @click="changePage(1)" :class="{ 'text-gray-400': query.pageIndex >= maxPage }"
            style=" width: 16px; height: 16px;cursor: pointer" />
        </Row>
      </div>
    </template>
  </Select>
</template>

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