<template>
  <div class="select-icon-wrapper">
    <div class="select-icon-trigger" :style="customStyle" @click="showDialog = true">
      <slot v-if="$slots.default"></slot>
      <template v-else>
        <div v-if="props.name" class="select-icon-container">
          <icon :name="props.name" size="28px" :type="props.type" />
          <div class="icon-delete-overlay" @click.stop="handleDeleteIcon">
            <el-icon class="delete-icon">
              <Delete />
            </el-icon>
          </div>
        </div>
        <div v-else class="select-icon-default">
          <el-icon class="text-3xl">
            <Plus />
          </el-icon>
          <span class="mt-1 w-full text-center text-xs leading-5 truncate text-nowrap">{{ props.btnText }}</span>
        </div>
      </template>
    </div>
    <popup v-model="showDialog" title="选择图标" width="520px" draggable :show-footer="false">
      <el-input
        class="mb-2"
        v-model="searchKeyword"
        placeholder="请输入图标名称"
        clearable
        size="large"
        prefix-icon="Search"
      />
      <el-tabs v-model="activeTab">
        <el-tab-pane label="Element图标" name="element">
          <el-scrollbar>
            <div class="min-w-[472px]">
              <div class="grid grid-cols-8 content-start gap-2 min-h-[292px]">
                <OutlineBox
                  v-for="iconName in currentElementIcons"
                  :key="iconName"
                  :active="props.type === 1 && props.name === iconName"
                  hoverEffect="expand"
                  :style="{ width: '48px', height: '48px', padding: '12px 8px' }"
                  @click="handleSelectIcon(iconName, 1)"
                >
                  <div class="flex flex-col items-center justify-center min-w-0">
                    <icon :name="iconName" size="20px" />
                  </div>
                </OutlineBox>
              </div>
              <div class="mt-4 flex justify-center">
                <el-pagination
                  v-model:current-page="elementCurrentPage"
                  :page-size="pageSize"
                  :total="filteredElementIcons.length"
                  :pager-count="5"
                  layout="total, prev, pager, next"
                />
              </div>
            </div>
          </el-scrollbar>
        </el-tab-pane>
        <el-tab-pane label="本地图标" name="local">
          <el-scrollbar>
            <div class="min-w-[472px]">
              <div class="grid grid-cols-8 content-start gap-2 min-h-[292px]">
                <OutlineBox
                  v-for="iconName in currentLocalIcons"
                  :key="iconName"
                  :active="props.type === 2 && props.name === iconName"
                  hoverEffect="expand"
                  :style="{ width: '48px', height: '48px', padding: '12px 8px' }"
                  @click="handleSelectIcon(iconName, 2)"
                >
                  <div class="flex flex-col items-center justify-center min-w-0">
                    <icon :name="iconName" size="20px" :type="2" />
                  </div>
                </OutlineBox>
              </div>
              <div class="mt-4 flex justify-center">
                <el-pagination
                  v-model:current-page="localCurrentPage"
                  :page-size="pageSize"
                  :total="filteredLocalIcons.length"
                  layout="total, prev, pager, next"
                />
              </div>
            </div>
          </el-scrollbar>
        </el-tab-pane>
      </el-tabs>
    </popup>
  </div>
</template>

<script setup lang="ts">
import * as ElementPlusIcons from '@element-plus/icons-vue'
// @ts-ignore
import localIconsName from 'virtual:svg-icons-names'

// 定义组件属性
const props = withDefaults(
  defineProps<{
    // 图标类型 1=element图标 2=本地图标
    type?: number
    // 图标名称
    name?: string
    // 按钮文字
    btnText?: string
    // 组件宽度
    width?: string
    // 组件高度
    height?: string
    // 组件样式
    style?: Record<string, any>
  }>(),
  {
    type: 1,
    name: '',
    btnText: '选择图标',
    width: '72px',
    height: '72px',
    style: () => ({})
  }
)

// 组件事件
const emit = defineEmits<{
  (event: 'select', iconName: string, iconType: number): void
}>()

// 自定义样式
const customStyle = computed(() => {
  return {
    width: props.width,
    height: props.height,
    ...props.style
  }
})

// 状态管理
const showDialog = ref(false)
const activeTab = ref('element')
const searchKeyword = ref('')

// 分页配置
const pageSize = ref<number>(40)
const elementCurrentPage = ref<number>(1)
const localCurrentPage = ref<number>(1)

// 图标列表
const elementIcons = ref<string[]>(Object.keys(ElementPlusIcons))
const localIcons = ref<string[]>(localIconsName)

// 监听搜索关键词变化，重置页码
const handleSearchKeywordChange = () => {
  if (activeTab.value === 'element') {
    elementCurrentPage.value = 1
  } else {
    localCurrentPage.value = 1
  }
}

// 监听搜索关键词变化
watch(searchKeyword, handleSearchKeywordChange)

// 计算过滤后的图标列表
const filteredElementIcons = computed(() => {
  if (!searchKeyword.value) {
    return elementIcons.value
  }
  const keyword = searchKeyword.value.toLowerCase()
  return elementIcons.value.filter((iconName) => {
    return iconName.toLowerCase().includes(keyword)
  })
})
const filteredLocalIcons = computed(() => {
  if (!searchKeyword.value) {
    return localIcons.value
  }
  const keyword = searchKeyword.value.toLowerCase()
  return localIcons.value.filter((iconName) => {
    return iconName.toLowerCase().includes(keyword)
  })
})

// 计算当前页显示的图标
const currentElementIcons = computed(() => {
  const start = (elementCurrentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return filteredElementIcons.value.slice(start, end)
})
const currentLocalIcons = computed(() => {
  const start = (localCurrentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return filteredLocalIcons.value.slice(start, end)
})

// 选择图标
const handleSelectIcon = (name: string, type: 1 | 2) => {
  emit('select', name, type)
  showDialog.value = false
}
// 删除图标
const handleDeleteIcon = () => {
  emit('select', '', 0)
}
</script>

<style lang="scss" scoped>
.select-icon-wrapper {
  @apply inline-block;

  .select-icon-trigger {
    @apply cursor-pointer inline-block;

    .select-icon-default {
      @apply w-full h-full flex flex-col justify-center items-center rounded-lg;
      border: 2px dashed var(--el-border-color);
      transition: all 0.3s;
      background-color: var(--el-fill-color-light);

      &:hover {
        border-color: var(--el-color-primary);
        background-color: var(--el-color-primary-light-9);
      }
    }

    .select-icon-container {
      @apply w-full h-full flex flex-col justify-center items-center rounded-lg relative overflow-hidden;
      border: 1px solid var(--el-border-color);
      transition: all 0.3s;

      .icon-delete-overlay {
        @apply absolute inset-0 flex items-center justify-center cursor-pointer transition-opacity duration-300;
        background: rgba(0, 0, 0, 0.6);
        opacity: 0;

        .delete-icon {
          @apply text-white text-lg;
          transition: transform 0.3s;
        }

        &:hover .delete-icon {
          transform: scale(1.2);
        }
      }

      &:hover {
        .icon-delete-overlay {
          opacity: 1;
        }
      }
    }
  }
}
</style>
