<template>
  <div class="seven-segment-display" :style="{
    width: width + 'px',
    height: height + 'px',
    position: 'relative',
  }">
    <svg xmlns="http://www.w3.org/2000/svg" :width="width" :height="height" viewBox="0 0 120 220" class="display">
      <!-- 数码管基座 -->
      <rect width="120" height="180" x="0" y="0" fill="#222" rx="10" ry="10" />
      <rect width="110" height="170" x="5" y="5" fill="#333" rx="5" ry="5" />
      <!-- 7段 + 小数点，每个段由多边形表示，重新设计点位置使其更接近实际数码管 -->
      <!-- a段 (顶部横线) -->
      <polygon :points="'30,20 90,20 98,28 82,36 38,36 22,28'"
        :fill="isSegmentActive('a') ? segmentColor : inactiveColor"
        :style="{ opacity: isSegmentActive('a') ? 1 : 0.15 }" class="segment" />

      <!-- b段 (右上竖线) -->
      <polygon :points="'100,30 108,38 108,82 100,90 92,82 92,38'"
        :fill="isSegmentActive('b') ? segmentColor : inactiveColor"
        :style="{ opacity: isSegmentActive('b') ? 1 : 0.15 }" class="segment" />

      <!-- c段 (右下竖线) -->
      <polygon :points="'100,90 108,98 108,142 100,150 92,142 92,98'"
        :fill="isSegmentActive('c') ? segmentColor : inactiveColor"
        :style="{ opacity: isSegmentActive('c') ? 1 : 0.15 }" class="segment" />

      <!-- d段 (底部横线) -->
      <polygon :points="'30,160 90,160 98,152 82,144 38,144 22,152'"
        :fill="isSegmentActive('d') ? segmentColor : inactiveColor"
        :style="{ opacity: isSegmentActive('d') ? 1 : 0.15 }" class="segment" />

      <!-- e段 (左下竖线) -->
      <polygon :points="'20,90 28,98 28,142 20,150 12,142 12,98'"
        :fill="isSegmentActive('e') ? segmentColor : inactiveColor"
        :style="{ opacity: isSegmentActive('e') ? 1 : 0.15 }" class="segment" />

      <!-- f段 (左上竖线) -->
      <polygon :points="'20,30 28,38 28,82 20,90 12,82 12,38'"
        :fill="isSegmentActive('f') ? segmentColor : inactiveColor"
        :style="{ opacity: isSegmentActive('f') ? 1 : 0.15 }" class="segment" />

      <!-- g段 (中间横线) -->
      <polygon :points="'30,90 38,82 82,82 90,90 82,98 38,98'"
        :fill="isSegmentActive('g') ? segmentColor : inactiveColor"
        :style="{ opacity: isSegmentActive('g') ? 1 : 0.15 }" class="segment" />
      <!-- dp段 (小数点) -->
      <circle cx="108" cy="154" r="6" :fill="isSegmentActive('dp') ? segmentColor : inactiveColor"
        :style="{ opacity: isSegmentActive('dp') ? 1 : 0.15 }" class="segment" />
    </svg>

    <!-- 引脚 -->
    <div v-for="pin in pins" :key="pin.pinId" :style="{
      position: 'absolute',
      left: `${pin.x * props.size}px`,
      top: `${pin.y * props.size}px`,
      transform: 'translate(-50%, -50%)',
    }" :data-pin-wrapper="`${pin.pinId}`" :data-pin-x="`${pin.x * props.size}`"
      :data-pin-y="`${pin.y * props.size}`">
      <Pin :ref="(el) => {
          if (el) pinRefs[pin.pinId] = el;
        }
        " :label="pin.pinId" :constraint="pin.constraint" :pinId="pin.pinId" @pin-click="$emit('pin-click', $event)" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from "vue";
import { useConstraintsStore } from "../../stores/constraints";
import Pin from "./Pin.vue";

const { getConstraintState, onConstraintStateChange } = useConstraintsStore();

// 存储Pin引用
const pinRefs = ref<Record<string, any>>({});

// 数码管属性
interface SevenSegmentDisplayProps {
  size?: number;
  color?: string;
  AFTERGLOW_BUFFER_SIZE?: number; // 余晖存储槽大小
  AFTERGLOW_DURATION?: number; // 余晖持续时间（毫秒）
  pins?: {
    pinId: string;
    constraint: string;
    x: number;
    y: number;
  }[];
  cathodeType?: "common" | "anode"; // 共阴极或共阳极
}

const props = withDefaults(defineProps<SevenSegmentDisplayProps>(), {
  size: 1,
  color: "red",
  AFTERGLOW_BUFFER_SIZE: 1, // 默认存储槽大小为100
  AFTERGLOW_DURATION: 2000, // 默认余晖持续时间500毫秒
  cathodeType: "common", // 默认为共阴极
  pins: () => [
    { pinId: "a", constraint: "", x: 10, y: 170 }, // a段
    { pinId: "b", constraint: "", x: 25 - 1, y: 170 }, // b段
    { pinId: "c", constraint: "", x: 40 - 2, y: 170 }, // c段
    { pinId: "d", constraint: "", x: 55 - 3, y: 170 }, // d段
    { pinId: "e", constraint: "", x: 70 - 4, y: 170 }, // e段
    { pinId: "f", constraint: "", x: 85 - 5, y: 170 }, // f段
    { pinId: "g", constraint: "", x: 100 - 6, y: 170 }, // g段
    { pinId: "dp", constraint: "", x: 115 - 7, y: 170 }, // 小数点
    { pinId: "COM", constraint: "", x: 60, y: 10 }, // 公共端，稍微低一点
  ],
});

const width = computed(() => 120 * props.size);
const height = computed(() => 220 * props.size);

// 计算段颜色和非激活状态颜色
const segmentColor = computed(() => props.color || "red");
const inactiveColor = computed(() => "#FFFFFF");

// 监听props变化
watch(
  () => props,
  (newProps) => {
    console.log("SevenSegmentDisplay props changed:", newProps);
    updateSegmentStates();
  },
  { deep: true },
);

// 段引脚的当前状态
const segmentStates = ref({
  a: false,
  b: false,
  c: false,
  d: false,
  e: false,
  f: false,
  g: false,
  dp: false,
});

// 余晖存储槽 - 每个段有一个存储槽数组，存储历史状态
const afterglowBuffers = ref<Record<string, boolean[]>>({
  a: [],
  b: [],
  c: [],
  d: [],
  e: [],
  f: [],
  g: [],
  dp: [],
});

// 余晖判定阈值（比如持续10帧才算稳定，可根据刷新间隔和人眼余晖调节）
const STABLE_THRESHOLD = 3;

// 实际显示的段状态（只有稳定后才改变）
const stableSegmentStates = ref({
  a: false,
  b: false,
  c: false,
  d: false,
  e: false,
  f: false,
  g: false,
  dp: false,
});

// 每段的稳定计数器
const segmentStableCounters = ref<Record<string, number>>({
  a: 0,
  b: 0,
  c: 0,
  d: 0,
  e: 0,
  f: 0,
  g: 0,
  dp: 0,
});

// 段选关闭时的余晖状态保持
const afterglowStates = ref({
  a: false,
  b: false,
  c: false,
  d: false,
  e: false,
  f: false,
  g: false,
  dp: false,
});

// 余晖计时器
const afterglowTimers = ref<Record<string, number | null>>({
  a: null,
  b: null,
  c: null,
  d: null,
  e: null,
  f: null,
  g: null,
  dp: null,
});

// 余晖持续时间（毫秒）
const AFTERGLOW_DURATION = computed(() => props.AFTERGLOW_DURATION || 500);

// 当前COM口状态
const currentComActive = ref(false); // 初始化为false，等待第一次状态检查

// 是否处于余晖模式
const isInAfterglowMode = ref(false);

// 判断段是否激活（用稳定状态或余晖状态）
function isSegmentActive(
  segment: "a" | "b" | "c" | "d" | "e" | "f" | "g" | "dp",
): boolean {
  // 如果处于余晖模式，使用余晖状态
  if (isInAfterglowMode.value) {
    return afterglowStates.value[segment];
  }
  
  // 如果COM口未激活，所有段都不显示
  if (!currentComActive.value) {
    return false;
  }
  
  // 否则使用稳定状态
  return stableSegmentStates.value[segment];
}

// 更新引脚状态的函数
function updateSegmentStates() {
  // 先获取COM口状态
  const comPin = props.pins.find((p) => p.pinId === "COM");
  let comActive = false; // 默认未激活
  
  if (comPin && comPin.constraint) {
    const comState = getConstraintState(comPin.constraint);
    if (props.cathodeType === "anode") {
      // 共阳极模式下，COM为低电平才激活
      comActive = comState === "low";
    } else {
      // 共阴极模式下，COM为低电平才激活
      comActive = comState === "low";
    }
  } else if (!comPin || !comPin.constraint) {
    // 如果没有COM引脚或者COM引脚没有约束，则认为始终激活
    comActive = true;
  }

  // 检查COM口状态是否发生变化
  const comStateChanged = currentComActive.value !== comActive;
  currentComActive.value = comActive;

  // 如果COM从激活变为非激活，进入余晖模式
  if (comStateChanged && !comActive) {
    enterAfterglowMode();
    return; // 在余晖模式下，不处理其他引脚变化
  }

  // 如果COM从非激活变为激活，退出余晖模式
  if (comStateChanged && comActive) {
    exitAfterglowMode();
  }

  // 关键修复：如果COM口未激活或处于余晖模式，不处理任何引脚状态变化
  if (!comActive || isInAfterglowMode.value) {
    return;
  }

  // 只有当COM口激活时，才更新段的状态
  updateAfterglowBuffers();

  // 先更新 segmentStates
  for (const pin of props.pins) {
    if (["a", "b", "c", "d", "e", "f", "g", "dp"].includes(pin.pinId)) {
      if (!pin.constraint) {
        segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = false;
        continue;
      }
      const pinState = getConstraintState(pin.constraint);
      let newState: boolean;
      if (props.cathodeType === "common") {
        newState = pinState === "high";
      } else {
        newState = pinState === "low";
      }
      // 段状态只有在COM激活时才有效
      segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = newState;
    }
  }

  // 余晖判定：只有新状态持续 STABLE_THRESHOLD 次才更新 stableSegmentStates
  for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) {
    const typedSegmentId = segmentId as keyof typeof segmentStates.value;
    const current = segmentStates.value[typedSegmentId];
    const stable = stableSegmentStates.value[typedSegmentId];

    if (current === stable) {
      segmentStableCounters.value[segmentId] = 0; // 状态一致，计数器清零
    } else {
      segmentStableCounters.value[segmentId]++;
      if (segmentStableCounters.value[segmentId] >= STABLE_THRESHOLD) {
        stableSegmentStates.value[typedSegmentId] = current;
        segmentStableCounters.value[segmentId] = 0;
      }
    }
  }
}

// 更新余晖存储槽 - 将当前段状态添加到存储槽中
function updateAfterglowBuffers() {
  for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) {
    const typedSegmentId = segmentId as keyof typeof segmentStates.value;
    const currentState = segmentStates.value[typedSegmentId];

    // 将当前状态添加到存储槽的开头
    afterglowBuffers.value[segmentId].unshift(currentState);

    // 如果存储槽超过了最大容量，移除最旧的状态
    if (
      afterglowBuffers.value[segmentId].length > props.AFTERGLOW_BUFFER_SIZE
    ) {
      afterglowBuffers.value[segmentId].pop();
    }
  }
}

// 进入余晖模式
function enterAfterglowMode() {
  isInAfterglowMode.value = true;
  
  // 保存当前稳定状态作为余晖状态
  for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) {
    const typedSegmentId = segmentId as keyof typeof stableSegmentStates.value;
    afterglowStates.value[typedSegmentId] = stableSegmentStates.value[typedSegmentId];
    
    // 设置定时器，在余晖持续时间后退出余晖模式
    if (afterglowTimers.value[segmentId]) {
      clearTimeout(afterglowTimers.value[segmentId]!);
    }
    
    afterglowTimers.value[segmentId] = setTimeout(() => {
      afterglowStates.value[typedSegmentId] = false;
      
      // 检查是否所有段都已经关闭
      const allSegmentsOff = Object.values(afterglowStates.value).every(state => !state);
      if (allSegmentsOff) {
        exitAfterglowMode();
      }
    }, AFTERGLOW_DURATION.value);
  }
}

// 退出余晖模式
function exitAfterglowMode() {
  isInAfterglowMode.value = false;
  
  // 清除所有定时器
  for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) {
    if (afterglowTimers.value[segmentId]) {
      clearTimeout(afterglowTimers.value[segmentId]!);
      afterglowTimers.value[segmentId] = null;
    }
    
    // 重置余晖状态
    const typedSegmentId = segmentId as keyof typeof afterglowStates.value;
    afterglowStates.value[typedSegmentId] = false;
  }
}

// 监听约束状态变化
function onConstraintChange(constraint: string, level: string) {
  const affectedPin = props.pins.find((pin) => pin.constraint === constraint);
  if (affectedPin) {
    updateSegmentStates();
  }
}

// 生命周期钩子
onMounted(() => {
  // 初始化余晖存储槽
  for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) {
    afterglowBuffers.value[segmentId] = Array(props.AFTERGLOW_BUFFER_SIZE).fill(
      false,
    );
  }

  updateSegmentStates();
  onConstraintStateChange(onConstraintChange);
});

onUnmounted(() => {
  // 清理所有余晖定时器
  for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) {
    if (afterglowTimers.value[segmentId]) {
      clearTimeout(afterglowTimers.value[segmentId]!);
    }
  }
});

// 暴露属性和方法
defineExpose({
  updateSegmentStates,
});
</script>

<style scoped>
.seven-segment-display {
  display: inline-block;
  position: relative;
}

.segment {
  transition:
    opacity 0.2s,
    fill 0.2s;
}

/* 数码管发光效果 */
.segment[style*="opacity: 1"] {
  filter: drop-shadow(0 0 4px v-bind(segmentColor)) drop-shadow(0 0 2px v-bind(segmentColor));
}
</style>

<!-- 导出默认属性函数供外部使用 -->
<script lang="ts">
export function getDefaultProps() {
  return {
    size: 1,
    color: "red",
    cathodeType: "common",
    AFTERGLOW_DURATION: 500, // 默认余晖持续时间500毫秒
    pins: [
      { pinId: "a", constraint: "", x: 10, y: 170 },
      { pinId: "b", constraint: "", x: 25 - 1, y: 170 },
      { pinId: "c", constraint: "", x: 40 - 2, y: 170 },
      { pinId: "d", constraint: "", x: 55 - 3, y: 170 },
      { pinId: "e", constraint: "", x: 70 - 4, y: 170 },
      { pinId: "f", constraint: "", x: 85 - 5, y: 170 },
      { pinId: "g", constraint: "", x: 100 - 6, y: 170 },
      { pinId: "dp", constraint: "", x: 115 - 7, y: 170 },
      { pinId: "COM", constraint: "", x: 60, y: 10 },
    ],
  };
}
</script>
