<script setup lang="ts">
import { type Component, computed } from 'vue';
import { FEEDBACK_STATUS_DICT_CODE, FEEDBACK_TYPE_DICT_CODE } from '@/constants/dict';
import { getFeedbackStatusTagType } from '@/constants/status-tag';
import { useDict } from '@/hooks/business/dict';
import IconBugOutline from '~icons/mdi/bug-outline';
import IconEmoticonSadOutline from '~icons/mdi/emoticon-sad-outline';
import IconLightbulbOnOutline from '~icons/mdi/lightbulb-on-outline';
import IconTagOutline from '~icons/mdi/tag-outline';

defineOptions({ name: 'FeedbackFacet' });

interface Props {
  /** 全部反馈总数 */
  total: number;
  /** 各分类计数：key=分类码值字符串 */
  typeCounts: Record<string, number>;
  /** 各状态计数：key=状态码值字符串 */
  statusCounts: Record<string, number>;
  /** 当前选中的分类码值（来自列表搜索参数） */
  selectedType?: string | number | null;
  /** 当前选中的状态码值 */
  selectedStatus?: string | number | null;
  /** 统计加载态 */
  loading?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  selectedType: undefined,
  selectedStatus: undefined,
  loading: false
});

const emit = defineEmits<{
  /** 切换分类筛选（已处理单选 toggle，传最终值或 undefined） */
  selectType: [value: string | number | undefined];
  /** 切换状态筛选 */
  selectStatus: [value: string | number | undefined];
  /** 清空分类 + 状态筛选 */
  selectAll: [];
}>();

const { dictData: typeDictData } = useDict(FEEDBACK_TYPE_DICT_CODE);
const { dictData: statusDictData } = useDict(FEEDBACK_STATUS_DICT_CODE);

// 统计接口按字典全集返回计数，分面也使用全集，避免停用码值的历史数据被隐藏。
const typeOptions = computed(() => typeDictData.value.map(item => ({ label: item.label, value: item.value })));
const statusOptions = computed(() => statusDictData.value.map(item => ({ label: item.label, value: item.value })));

// ElTag type → 主题色变量，用于状态色点（颜色语义来源仍是 status-tag.ts）
// 注意：本主题把 --el-color-info 设成了蓝色（settings.ts otherColor.info=#2080f0），
// 与「处理中」的 primary 蓝撞色；故分面里 info（已忽略/兜底）单独落真实灰，仅作用于左侧圆点，
// 右侧表格状态标签仍走主题色不受影响。
const TAG_TYPE_COLOR_VAR: Record<string, string> = {
  primary: 'var(--el-color-primary)',
  success: 'var(--el-color-success)',
  warning: 'var(--el-color-warning)',
  danger: 'var(--el-color-danger)',
  info: 'var(--el-text-color-secondary)'
};

function statusDotColor(value: string | number) {
  return TAG_TYPE_COLOR_VAR[getFeedbackStatusTagType(value)] ?? TAG_TYPE_COLOR_VAR.info;
}

// 分类图标按字典码值映射（feedback_type：1 缺陷 / 2 体验问题 / 3 功能建议，口径见 constants/dict.ts）
const TYPE_ICON_MAP: Record<string, Component> = {
  '1': IconBugOutline,
  '2': IconEmoticonSadOutline,
  '3': IconLightbulbOnOutline
};

/** 分类前导图标，未匹配码值回退通用标签图标 */
function typeIcon(value: string | number): Component {
  return TYPE_ICON_MAP[String(value)] ?? IconTagOutline;
}

/** 未选任何分类 / 状态时，「全部」高亮 */
const isAllActive = computed(
  () =>
    (props.selectedType === undefined || props.selectedType === null) &&
    (props.selectedStatus === undefined || props.selectedStatus === null)
);

/** 选中值与候选项是否同一码值（统一 String 比较，兼容字典 value 的 number/string 形态） */
function isSame(selected: string | number | null | undefined, value: string | number) {
  return selected !== undefined && selected !== null && String(selected) === String(value);
}

function handleType(value: string | number) {
  emit('selectType', isSame(props.selectedType, value) ? undefined : value);
}

function handleStatus(value: string | number) {
  emit('selectStatus', isSame(props.selectedStatus, value) ? undefined : value);
}

function handleAll() {
  emit('selectAll');
}
</script>

<template>
  <ElCard class="feedback-facet card-wrapper">
    <div v-loading="loading" class="feedback-facet__scroll">
      <button
        type="button"
        class="facet-item facet-item--all"
        :class="{ 'is-active': isAllActive }"
        :aria-pressed="isAllActive"
        @click="handleAll"
      >
        <span class="facet-item__lead" aria-hidden="true"><icon-mdi-inbox-multiple-outline /></span>
        <span class="facet-item__label">全部</span>
        <span class="facet-item__count" :class="{ 'is-zero': total === 0 }">{{ total }}</span>
      </button>

      <div class="facet-group">
        <p class="facet-group__title">分类</p>
        <button
          v-for="opt in typeOptions"
          :key="opt.value"
          type="button"
          class="facet-item"
          :class="{ 'is-active': isSame(selectedType, opt.value) }"
          :aria-pressed="isSame(selectedType, opt.value)"
          @click="handleType(opt.value)"
        >
          <span class="facet-item__lead" aria-hidden="true"><component :is="typeIcon(opt.value)" /></span>
          <span class="facet-item__label">{{ opt.label }}</span>
          <span class="facet-item__count" :class="{ 'is-zero': (typeCounts[String(opt.value)] ?? 0) === 0 }">
            {{ typeCounts[String(opt.value)] ?? 0 }}
          </span>
        </button>
        <p v-if="!typeOptions.length" class="facet-empty">分类字典未加载</p>
      </div>

      <div class="facet-group">
        <p class="facet-group__title">状态</p>
        <button
          v-for="opt in statusOptions"
          :key="opt.value"
          type="button"
          class="facet-item"
          :class="{ 'is-active': isSame(selectedStatus, opt.value) }"
          :aria-pressed="isSame(selectedStatus, opt.value)"
          @click="handleStatus(opt.value)"
        >
          <span class="facet-item__lead" aria-hidden="true">
            <span class="facet-item__dot" :style="{ backgroundColor: statusDotColor(opt.value) }" />
          </span>
          <span class="facet-item__label">{{ opt.label }}</span>
          <span class="facet-item__count" :class="{ 'is-zero': (statusCounts[String(opt.value)] ?? 0) === 0 }">
            {{ statusCounts[String(opt.value)] ?? 0 }}
          </span>
        </button>
        <p v-if="!statusOptions.length" class="facet-empty">状态字典未加载</p>
      </div>
    </div>
  </ElCard>
</template>

<style scoped lang="scss">
.feedback-facet {
  display: flex;
  flex-direction: column;
  overflow: hidden;

  :deep(.el-card__body) {
    flex: 1;
    min-height: 0;
    padding: 8px;
  }
}

.feedback-facet__scroll {
  height: 100%;
  overflow-y: auto;
  padding-right: 2px;
}

.facet-item--all {
  margin-bottom: 2px;
}

.facet-group + .facet-group {
  margin-top: 2px;
}

.facet-group__title {
  margin: 14px 10px 4px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--el-text-color-secondary);
}

.facet-empty {
  margin: 4px 10px;
  font-size: 12px;
  color: var(--el-text-color-placeholder);
}

.facet-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px 10px;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--el-text-color-regular);
  font-size: 13px;
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
  transition: background-color 0.18s ease-out;
}

.facet-item:hover {
  background: var(--el-fill-color-light);
}

// 键盘聚焦可见环（offset 内缩，避免被圆角裁切）
.facet-item:focus-visible {
  outline: 2px solid var(--el-color-primary);
  outline-offset: -2px;
}

.facet-item.is-active {
  font-weight: 600;
  color: var(--el-color-primary);
  background: var(--el-color-primary-light-9);
}

// 选中项左侧主题色强调条
.facet-item.is-active::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 3px;
  width: 3px;
  height: 14px;
  border-radius: 2px;
  background: var(--el-color-primary);
  transform: translateY(-50%);
}

// 前导标记列：全部=收件箱图标 / 状态=语义色点，对齐同一宽度
.facet-item__lead {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 18px;
  font-size: 16px;
  color: var(--el-text-color-secondary);
}

.facet-item:hover .facet-item__lead,
.facet-item.is-active .facet-item__lead {
  color: var(--el-color-primary);
}

.facet-item__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.facet-item__label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.facet-item__count {
  flex-shrink: 0;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--el-text-color-secondary);
}

// 计数为 0 的项弱化，避免一排 0 抢视线
.facet-item__count.is-zero {
  color: var(--el-text-color-placeholder);
}

.facet-item.is-active .facet-item__count {
  color: var(--el-color-primary);
}

// 尊重系统「减少动态效果」偏好
@media (prefers-reduced-motion: reduce) {
  .facet-item {
    transition: none;
  }
}
</style>
