<template>
  <div
    class="inline-block select-none"
    :style="{
      width: width + 'px',
      height: height + 'px',
      position: 'relative',
    }"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      :width="width"
      :height="height"
      viewBox="0 0 100 100"
      class="ec11-encoder"
    >
      <defs>
        <!-- 发光效果滤镜 -->
        <filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
          <feFlood
            result="flood"
            flood-color="#00ff88"
            flood-opacity="1"
          ></feFlood>
          <feComposite
            in="flood"
            result="mask"
            in2="SourceGraphic"
            operator="in"
          ></feComposite>
          <feMorphology
            in="mask"
            result="dilated"
            operator="dilate"
            radius="1"
          ></feMorphology>
          <feGaussianBlur in="dilated" stdDeviation="2" result="blur1" />
          <feGaussianBlur in="dilated" stdDeviation="4" result="blur2" />
          <feGaussianBlur in="dilated" stdDeviation="8" result="blur3" />
          <feMerge>
            <feMergeNode in="blur3" />
            <feMergeNode in="blur2" />
            <feMergeNode in="blur1" />
            <feMergeNode in="SourceGraphic" />
          </feMerge>
        </filter>

        <!-- 编码器主体渐变 -->
        <radialGradient id="encoderGradient" cx="50%" cy="30%">
          <stop offset="0%" stop-color="#666666" />
          <stop offset="70%" stop-color="#333333" />
          <stop offset="100%" stop-color="#1a1a1a" />
        </radialGradient>

        <!-- 旋钮渐变 -->
        <radialGradient id="knobGradient" cx="30%" cy="30%">
          <stop offset="0%" stop-color="#555555" />
          <stop offset="70%" stop-color="#222222" />
          <stop offset="100%" stop-color="#111111" />
        </radialGradient>

        <!-- 按下状态渐变 -->
        <radialGradient id="knobPressedGradient" cx="50%" cy="50%">
          <stop offset="0%" stop-color="#333333" />
          <stop offset="70%" stop-color="#555555" />
          <stop offset="100%" stop-color="#888888" />
        </radialGradient>
      </defs>

      <!-- 编码器底座 -->
      <rect
        x="10"
        y="30"
        width="80"
        height="60"
        rx="8"
        ry="8"
        fill="#2a2a2a"
        stroke="#444444"
        stroke-width="1"
      />

      <!-- 编码器主体外壳 -->
      <circle
        cx="50"
        cy="60"
        r="32"
        fill="url(#encoderGradient)"
        stroke="#555555"
        stroke-width="1"
      />

      <!-- 编码器接线端子 -->
      <rect x="5" y="75" width="4" height="8" fill="#c9c9c9" rx="1" />
      <rect x="15" y="85" width="4" height="8" fill="#c9c9c9" rx="1" />
      <rect x="25" y="85" width="4" height="8" fill="#c9c9c9" rx="1" />
      <rect x="81" y="85" width="4" height="8" fill="#c9c9c9" rx="1" />
      <rect x="91" y="75" width="4" height="8" fill="#c9c9c9" rx="1" />

      <!-- 旋钮 -->
      <circle
        cx="50"
        cy="60"
        r="22"
        :fill="isPressed ? 'url(#knobPressedGradient)' : 'url(#knobGradient)'"
        stroke="#666666"
        stroke-width="1"
        :transform="`rotate(${rotationStep * 7.5} 50 60)`"
        class="interactive"
        @mousedown="handleMouseDown"
        @mouseup="handlePress(false)"
        @mouseleave="handlePress(false)"
      />

      <!-- 旋钮指示器 -->
      <line
        x1="50"
        y1="42"
        x2="50"
        y2="48"
        stroke="#ffffff"
        stroke-width="2"
        stroke-linecap="round"
        :transform="`rotate(${rotationStep * 15} 50 60)`"
      />

      <!-- 旋钮上的纹理刻度 -->
      <g :transform="`rotate(${rotationStep * 15} 50 60)`">
        <circle
          cx="50"
          cy="60"
          r="18"
          fill="none"
          stroke="#777777"
          stroke-width="0.5"
        />
        <!-- 刻度线 -->
        <g v-for="i in 16" :key="i">
          <line
            :x1="50 + 16 * Math.cos(((i - 1) * Math.PI) / 8)"
            :y1="60 + 16 * Math.sin(((i - 1) * Math.PI) / 8)"
            :x2="50 + 18 * Math.cos(((i - 1) * Math.PI) / 8)"
            :y2="60 + 18 * Math.sin(((i - 1) * Math.PI) / 8)"
            stroke="#999999"
            stroke-width="0.5"
          />
        </g>
      </g>

      <!-- 编码器编号标签 -->
      <text
        x="50"
        y="15"
        text-anchor="middle"
        font-family="Arial"
        font-size="10"
        fill="#cccccc"
        font-weight="bold"
      >
        EC11-{{ encoderNumber }}
      </text>

      <!-- 状态指示器 -->
      <circle
        cx="85"
        cy="20"
        r="3"
        :fill="isPressed ? '#ff4444' : '#444444'"
        :filter="isPressed ? 'url(#glow)' : ''"
        stroke="#666666"
        stroke-width="0.5"
      />
    </svg>
  </div>
</template>

<script lang="ts" setup>
import { useRotaryEncoder } from "@/stores/Peripherals/RotaryEncoder";
import {
  RotaryEncoderDirection,
  RotaryEncoderPressStatus,
} from "@/utils/signalR/Peripherals.RotaryEncoderClient";
import { watch } from "vue";
import { watchEffect } from "vue";
import { ref, computed } from "vue";

const rotataryEncoderStore = useRotaryEncoder();

interface Props {
  size?: number;
  componentId?: string;
  enableDigitalTwin?: boolean;
  encoderNumber?: number;
}

const props = withDefaults(defineProps<Props>(), {
  size: 1,
  enableDigitalTwin: false,
  encoderNumber: 1,
});

// 组件状态
const isPressed = ref(false);
const rotationStep = ref(0); // 步进计数，1步=15度

// 拖动状态对象，增加 hasRotated 标记
const drag = ref<{
  active: boolean;
  startX: number;
  hasRotated: boolean;
} | null>(null);

const dragThreshold = 20; // 每20像素触发一次旋转

// 计算宽高
const width = computed(() => 100 * props.size);
const height = computed(() => 100 * props.size);

// 鼠标按下处理
function handleMouseDown(event: MouseEvent) {
  drag.value = { active: true, startX: event.clientX, hasRotated: false };
  window.addEventListener("mousemove", handleMouseMove);
  window.addEventListener("mouseup", handleMouseUp);
}

// 鼠标移动处理
function handleMouseMove(event: MouseEvent) {
  if (!drag.value?.active) return;
  const dx = event.clientX - drag.value.startX;
  if (Math.abs(dx) >= dragThreshold) {
    rotationStep.value += dx > 0 ? 1 : -1;
    drag.value.startX = event.clientX;
    drag.value.hasRotated = true;
  }
}

// 鼠标松开处理
function handleMouseUp() {
  if (drag.value && drag.value.active) {
    // 仅在未发生旋转时才触发按压
    if (!drag.value.hasRotated) {
      isPressed.value = true;
      rotataryEncoderStore.pressOnce(
        props.encoderNumber,
        RotaryEncoderPressStatus.Press,
      );
      setTimeout(() => {
        isPressed.value = false;
        rotataryEncoderStore.pressOnce(
          props.encoderNumber,
          RotaryEncoderPressStatus.Release,
        );
      }, 100);
    }
  }
  drag.value = null;
  window.removeEventListener("mousemove", handleMouseMove);
  window.removeEventListener("mouseup", handleMouseUp);
}

// 按压处理（用于鼠标离开和mouseup）
function handlePress(pressed: boolean) {
  isPressed.value = pressed;
}

watchEffect(() => {
  if (!props.enableDigitalTwin) return;

  if (props.componentId)
    rotataryEncoderStore.setEnable(props.enableDigitalTwin);
});

watch(
  () => rotationStep.value,
  (newStep, oldStep) => {
    if (!props.enableDigitalTwin) return;

    if (newStep > oldStep) {
      rotataryEncoderStore.rotateOnce(
        props.encoderNumber,
        RotaryEncoderDirection.Clockwise,
      );
    } else if (newStep < oldStep) {
      rotataryEncoderStore.rotateOnce(
        props.encoderNumber,
        RotaryEncoderDirection.CounterClockwise,
      );
    }
  },
);
</script>

<script lang="ts">
// 添加一个静态方法来获取默认props
export function getDefaultProps() {
  return {
    size: 1,
    enableDigitalTwin: false,
    encoderNumber: 1,
  };
}
</script>

<style scoped lang="postcss">
.ec11-container {
  display: inline-block;
  user-select: none;
}

.ec11-encoder {
  display: block;
  overflow: visible;
}

.interactive {
  cursor: pointer;
}
</style>
