<template>
  <div class="product-selector">
    <!-- 表单包装模式 -->
    <el-form-item v-if="formItem" :label="label" :prop="prop" :rules="rules" :required="required">
      <div class="product-selector-content">
        <el-select v-model="selectedProductId" filterable remote reserve-keyword :placeholder="placeholder"
          :remote-method="remoteMethod" :loading="showLoading" :clearable="clearable" :disabled="disabled" :size="size"
          @change="handleProductChange" @visible-change="onVisibleChange" style="width: 100%">
          <el-option v-for="item in productList" :key="item.id" :label="item.name" :value="item.id">
            <div class="product-option">
              <div class="product-name">{{ item.name }}</div>
              <div class="product-key">产品标识: {{ item.productKey }}</div>
            </div>
          </el-option>
        </el-select>

        <!-- 精确搜索按钮 -->
        <el-button type="primary" :icon="Search" circle :size="size" @click="openSearchDialog" class="search-btn"
          :disabled="disabled" />
      </div>
    </el-form-item>

    <!-- 非表单模式 -->
    <div v-else class="product-selector-content">
      <el-select v-model="selectedProductId" filterable remote reserve-keyword :placeholder="placeholder"
        :remote-method="remoteMethod" :loading="showLoading" :clearable="clearable" :disabled="disabled" :size="size"
        @change="handleProductChange" @visible-change="onVisibleChange" style="width: 100%">
        <el-option v-for="item in productList" :key="item.id" :label="item.name" :value="item.id">
          <div class="product-option">
            <div class="product-name">{{ item.name }}</div>
            <div class="product-key">产品标识: {{ item.productKey }}</div>
          </div>
        </el-option>
      </el-select>

      <!-- 精确搜索按钮 -->
      <el-button type="primary" :icon="Search" circle :size="size" @click="openSearchDialog" class="search-btn"
        :disabled="disabled" />
    </div>

    <!-- 搜索弹窗 -->
    <Dialog v-model="searchVisible" title="产品搜索" width="800px">
      <div class="search-form">
        <el-form :inline="true" :model="searchParams" class="search-form-inline">
          <el-form-item label="产品名称">
            <el-input v-model="searchParams.name" placeholder="请输入产品名称" clearable @keyup.enter="handleSearch" />
          </el-form-item>
          <el-form-item label="产品标识">
            <el-input v-model="searchParams.productKey" placeholder="请输入产品标识" clearable @keyup.enter="handleSearch" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleSearch" :loading="searchLoading">
              <Icon icon="ep:search" class="mr-5px" />
              搜索
            </el-button>
            <el-button @click="resetSearch">重置</el-button>
          </el-form-item>
        </el-form>
      </div>

      <el-table :data="searchResults" :loading="searchLoading" @row-click="selectProduct" style="cursor: pointer"
        highlight-current-row>
        <el-table-column label="产品名称" prop="name" min-width="150" />
        <el-table-column label="产品标识" prop="productKey" min-width="120" />
        <el-table-column label="产品分类" prop="categoryName" width="120" />
        <el-table-column label="设备类型" width="100">
          <template #default="{ row }">
            <el-tag :type="getDeviceTypeTag(row.deviceType)">
              {{ getDeviceTypeLabel(row.deviceType) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="状态" width="80">
          <template #default="{ row }">
            <el-tag :type="row.status === 1 ? 'success' : 'danger'">
              {{ row.status === 1 ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80">
          <template #default="{ row }">
            <el-button link type="primary" @click="selectProduct(row)">
              选择
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <Pagination :total="searchTotal" v-model:page="searchPage" v-model:limit="searchPageSize"
        @pagination="handleSearch" class="mt-4" />
    </Dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch, computed } from 'vue'
import { Search } from '@element-plus/icons-vue'
import { ProductApi, type ProductVO } from '@/api/iot/product/product'

interface Props {
  modelValue?: ProductVO | null
  placeholder?: string
  clearable?: boolean
  disabled?: boolean
  size?: 'large' | 'default' | 'small'
  // 表单相关
  formItem?: boolean
  label?: string
  prop?: string
  required?: boolean
  rules?: any[]
}

interface Emits {
  (e: 'update:modelValue', value: ProductVO | null): void
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: '默认加载十条产品，输入产品名称进行搜索',
  clearable: true,
  disabled: false,
  size: 'default',
  formItem: false,
  label: '选择产品',
  prop: 'productId',
  required: false,
  rules: () => []
})
const emit = defineEmits<Emits>()

const selectedProduct = ref<ProductVO | null>(props.modelValue || null)
const selectedProductId = ref<number | undefined>(props.modelValue?.id || undefined)
const productList = ref<ProductVO[]>([])
const loading = ref(false)

// 搜索弹窗相关
const searchVisible = ref(false)
const searchLoading = ref(false)
const searchResults = ref<ProductVO[]>([])
const searchTotal = ref(0)
const searchPage = ref(1)
const searchPageSize = ref(10)

const searchParams = reactive({
  name: '',
  productKey: ''
})

// 仅当无数据且处于加载中时展示 loading，避免“先有数据又闪空”
const showLoading = computed(() => loading.value && productList.value.length === 0)

// 远程搜索：防抖 + 竞态保护
let remoteDebounceTimer: number | undefined
let remoteRequestSeq = 0
const lastQuery = ref<string>('')
const remoteMethod = (query: string) => {
  if (remoteDebounceTimer) {
    window.clearTimeout(remoteDebounceTimer)
  }
  remoteDebounceTimer = window.setTimeout(async () => {
    lastQuery.value = query
    const seq = ++remoteRequestSeq
    loading.value = true
    try {
      const response = await ProductApi.getProductPage({
        pageNo: '1',
        pageSize: '10',
        name: query || undefined // 没有查询条件返回默认数据
      })
      // 忽略过期响应
      if (seq !== remoteRequestSeq) return
      productList.value = response.list || []

      // 覆盖后确保选中项仍存在
      if (selectedProductId.value && !productList.value.find(p => p.id === selectedProductId.value)) {
        if (selectedProduct.value) {
          productList.value = [selectedProduct.value, ...productList.value]
        } else {
          await ensureSelectedProductOption()
        }
      }
    } catch (error) {
      // 仅在未被新请求覆盖时处理错误和状态
      if (seq === remoteRequestSeq) {
        console.error('搜索产品失败:', error)
        // 不清空旧数据，避免体验闪空
      }
    } finally {
      if (seq === remoteRequestSeq) {
        loading.value = false
      }
    }
  }, 300)
}

// 下拉可见性变化：
// - 打开时：若存在上次查询关键字则优先使用；否则没有数据时加载默认 10 条
// - 关闭时：清除防抖定时器，避免误触发
const onVisibleChange = (visible: boolean) => {
  if (visible) {
    // Element Plus remote 模式下，只有输入变化会触发 remoteMethod。
    // 这里在打开时，若有上次查询关键字则优先按其加载；否则若尚无数据，加载默认 10 条。
    if (lastQuery.value && lastQuery.value.trim() !== '') {
      remoteMethod(lastQuery.value)
    } else if (!productList.value || productList.value.length === 0) {
      remoteMethod('')
    }
  } else {
    if (remoteDebounceTimer) {
      window.clearTimeout(remoteDebounceTimer)
      remoteDebounceTimer = undefined
    }
  }
}

// 打开搜索弹窗
const openSearchDialog = () => {
  searchVisible.value = true
  handleSearch()
}

// 搜索方法
const handleSearch = async () => {
  searchLoading.value = true
  try {
    const response = await ProductApi.getProductPage({
      pageNo: searchPage.value.toString(),
      pageSize: searchPageSize.value.toString(),
      name: searchParams.name,
      productKey: searchParams.productKey
    })
    searchResults.value = response.list || []
    searchTotal.value = response.total || 0
  } catch (error) {
    console.error('搜索产品失败:', error)
    searchResults.value = []
    searchTotal.value = 0
  } finally {
    searchLoading.value = false
  }
}

// 重置搜索
const resetSearch = () => {
  searchParams.name = ''
  searchParams.productKey = ''
  searchPage.value = 1
  handleSearch()
}

// 加载初始数据
const loadInitialData = async () => {
  loading.value = true
  try {
    const response = await ProductApi.getProductPage({
      pageNo: '1',
      pageSize: '10'
    })
    productList.value = response.list || []
    // 覆盖后确保选中项仍存在
    if (selectedProductId.value && !productList.value.find(p => p.id === selectedProductId.value)) {
      if (selectedProduct.value) {
        productList.value = [selectedProduct.value, ...productList.value]
      } else {
        await ensureSelectedProductOption()
      }
    }
  } catch (error) {
    console.error('加载初始产品数据失败:', error)
    productList.value = []
  } finally {
    loading.value = false
  }
}

// 确保选中产品存在于下拉选项中；若缺少名称则按 ID 拉取详情补齐（带去重加载保护）
const ensuringProductIds = new Set<number>()
const ensureSelectedProductOption = async () => {
  const productId = selectedProductId.value
  if (!productId) return
  if (ensuringProductIds.has(productId)) return

  const existingIndex = productList.value.findIndex(p => p.id === productId)
  const existing = existingIndex >= 0 ? productList.value[existingIndex] : undefined

  // 如果已有且有名称，则无需处理
  if (existing && existing.name) return

  try {
    ensuringProductIds.add(productId)
    const detail = await ProductApi.getProduct(productId)
    if (detail) {
      selectedProduct.value = detail
      if (existingIndex === -1) {
        productList.value = [detail, ...productList.value]
      } else {
        productList.value[existingIndex] = detail
        productList.value = [...productList.value]
      }
    }
  } catch (error) {
    console.error('加载产品详情失败:', error)
  } finally {
    ensuringProductIds.delete(productId)
  }
}

// 选择产品
const selectProduct = (product: ProductVO) => {
  selectedProduct.value = product
  selectedProductId.value = product.id
  // 确保产品在productList中，这样下拉框能正确显示名称
  if (!productList.value.find(p => p.id === product.id)) {
    productList.value = [product, ...productList.value]
  }
  emit('update:modelValue', product)
  searchVisible.value = false
}

// 处理产品变化
const handleProductChange = (productId: number | undefined) => {
  // 先从当前产品列表中查找
  let product = productList.value.find(p => p.id === productId)

  // 如果没找到，从搜索结果中查找
  if (!product) {
    product = searchResults.value.find(p => p.id === productId)
  }

  selectedProduct.value = product || null
  emit('update:modelValue', product || null)
}

// 获取设备类型标签
const getDeviceTypeTag = (type: number) => {
  switch (type) {
    case 0:
      return 'primary'
    case 1:
      return 'success'
    case 2:
      return 'warning'
    default:
      return 'info'
  }
}

// 获取设备类型标签文本
const getDeviceTypeLabel = (type: number) => {
  switch (type) {
    case 0:
      return '直连设备'
    case 1:
      return '网关子设备'
    case 2:
      return '网关设备'
    default:
      return '未知'
  }
}

// 监听modelValue变化，自动更新selectedProductId
watch(() => props.modelValue, (newProduct) => {
  if (newProduct) {
    selectedProduct.value = newProduct
    selectedProductId.value = newProduct.id
    // 将选中产品插入到选项中（若不存在），或用更完整的信息更新
    const idx = productList.value.findIndex(p => p.id === newProduct.id)
    if (idx === -1) {
      productList.value = [newProduct, ...productList.value]
    } else {
      productList.value[idx] = { ...productList.value[idx], ...newProduct }
      productList.value = [...productList.value]
    }
    // 若缺少名称等信息，按 ID 拉取详情补齐
    if (!newProduct.name) {
      ensureSelectedProductOption()
    }
  } else {
    selectedProduct.value = null
    selectedProductId.value = undefined
  }
}, { immediate: true })

// 监听选中 ID 变化，保证始终有对应的选项用于显示名称
watch(selectedProductId, async (newId) => {
  if (newId == null) return
  const exist = productList.value.find(p => p.id === newId)
  if (!exist) {
    await ensureSelectedProductOption()
  }
})

onMounted(() => {
  if (props.modelValue) {
    selectedProduct.value = props.modelValue
    selectedProductId.value = props.modelValue.id
    // 确保产品列表包含当前选中的产品
    const exists = productList.value.find(p => p.id === props.modelValue!.id)
    if (!exists) {
      productList.value = [props.modelValue, ...productList.value]
    }
    // 若没有名称，补拉详情
    if (!props.modelValue.name) {
      ensureSelectedProductOption()
    }
  } else {
    // 如果没有预设值，加载初始数据
    loadInitialData()
  }
})
</script>

<style scoped>
.product-selector {
  width: 100%;
}

.product-selector-content {
  display: flex;
  align-items: center;
  gap: 8px;
}

.search-btn {
  flex-shrink: 0;
}

.product-option {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.product-name {
  font-weight: 500;
  color: #303133;
}

.product-key {
  font-size: 12px;
  color: #909399;
}

.search-form {
  margin-bottom: 16px;
}

.search-form-inline {
  margin-bottom: 0;
}

.mt-4 {
  margin-top: 16px;
}

.mr-5px {
  margin-right: 5px;
}
</style>
