<template>
  <div class="terminal-definition">
    <div class="mode-switch">
      <button :class="{ active: mode === 'cli' }" @click="mode = 'cli'">
        🖥️ CLI (命令行界面)
      </button>
      <button :class="{ active: mode === 'gui' }" @click="mode = 'gui'">
        🖱️ GUI (图形用户界面)
      </button>
    </div>

    <!-- CLI Visualization -->
    <div v-if="mode === 'cli'" class="visualization-container">
      <div class="flow-container">
        <!-- Input Side -->
        <div class="stage input-stage">
          <div class="icon-box">
            <svg
              xmlns="http://www.w3.org/2000/svg"
              width="32"
              height="32"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <rect x="2" y="4" width="20" height="16" rx="2" ry="2"></rect>
              <path d="M6 8h.001"></path>
              <path d="M10 8h.001"></path>
              <path d="M14 8h.001"></path>
              <path d="M18 8h.001"></path>
              <path d="M6 12h.001"></path>
              <path d="M10 12h.001"></path>
              <path d="M14 12h.001"></path>
              <path d="M18 12h.001"></path>
              <path d="M7 16h10"></path>
            </svg>
          </div>
          <div class="label">Input (Keyboard)</div>
          <div class="sub-label">发送指令 (字符信号)</div>
        </div>

        <!-- Stream Animation -->
        <div class="stream-path">
          <div class="stream-line"></div>
          <div class="stream-label">Character Stream / 字符流</div>
          <div
            v-for="char in activeChars"
            :key="char.id"
            class="stream-char"
            :style="{ left: char.progress + '%' }"
          >
            {{ char.val }}
          </div>
        </div>

        <!-- Output Side -->
        <div class="stage output-stage">
          <div class="terminal-screen">
            <div class="screen-content">
              <span class="prompt">$</span> {{ typedContent
              }}<span class="cursor">_</span>
            </div>
          </div>
          <div class="label">Output (Text Grid)</div>
          <div class="sub-label">文本网格反馈</div>
        </div>
      </div>

      <div class="desc-box">
        <p>
          <strong>CLI (Command Line Interface)</strong>:
          这种模式下，计算机只认识字符。你的每一次按键都会被转换成编码发送给系统，系统处理后返回文字结果。它不关心你在哪里点击，只关心你输入了什么。
        </p>
      </div>

      <div class="control-bar">
        <button @click="startSimulation" :disabled="isAnimating">
          <span v-if="!isAnimating">▶ Play Simulation / 演示输入流</span>
          <span v-else>Simulating... / 演示中...</span>
        </button>
      </div>
    </div>

    <!-- GUI Visualization -->
    <div v-else class="visualization-container">
      <div class="flow-container">
        <!-- Input Side -->
        <div class="stage input-stage">
          <div class="icon-box gui-input" :class="{ clicking: isGuiClicking }">
            <svg
              xmlns="http://www.w3.org/2000/svg"
              width="32"
              height="32"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"></path>
              <path d="M13 13l6 6"></path>
            </svg>
          </div>
          <div class="label">Input (Mouse)</div>
          <div class="sub-label">发送事件 (坐标/点击)</div>
        </div>

        <!-- Event Animation -->
        <div class="stream-path">
          <div class="stream-line dashed"></div>
          <div class="stream-label">Event Loop / 事件循环</div>
          <div
            v-for="ev in guiEvents"
            :key="ev.id"
            class="gui-event-packet"
            :style="{ left: ev.progress + '%' }"
          >
            {{ ev.type }}
          </div>
        </div>

        <!-- Output Side -->
        <div class="stage output-stage">
          <div class="gui-screen">
            <div class="window-frame">
              <div class="win-header"></div>
              <div class="win-body">
                <div class="icon-grid">
                  <div class="desktop-icon" :class="{ selected: iconSelected }">
                    📁
                  </div>
                  <div class="desktop-icon">📄</div>
                </div>
                <div class="gui-cursor" :style="cursorStyle">
                  <svg
                    width="12"
                    height="12"
                    viewBox="0 0 24 24"
                    fill="white"
                    stroke="black"
                    stroke-width="2"
                  >
                    <path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"></path>
                  </svg>
                </div>
              </div>
            </div>
          </div>
          <div class="label">Output (Graphics)</div>
          <div class="sub-label">像素图形渲染</div>
        </div>
      </div>

      <div class="desc-box">
        <p>
          <strong>GUI (Graphical User Interface)</strong>:
          这种模式下，计算机实时追踪鼠标坐标和点击事件，并每秒刷新 60
          次屏幕像素。它更直观，但需要消耗大量资源来处理图形渲染。
        </p>
      </div>

      <div class="control-bar">
        <button @click="startGuiSimulation" :disabled="isGuiAnimating">
          <span v-if="!isGuiAnimating">▶ Play Interaction / 演示交互</span>
          <span v-else>Simulating... / 演示中...</span>
        </button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'

const mode = ref('cli') // 'cli' | 'gui'

// CLI Logic
const isAnimating = ref(false)
const activeChars = ref([])
const typedContent = ref('')
const demoText = 'echo "hello world"'

const startSimulation = () => {
  if (isAnimating.value) return
  isAnimating.value = true
  typedContent.value = ''
  activeChars.value = []

  let index = 0

  const processNextChar = () => {
    if (index >= demoText.length) {
      setTimeout(() => {
        isAnimating.value = false
      }, 1000)
      return
    }

    const char = demoText[index]
    const charId = Date.now() + index

    // Create new flying char
    const newChar = {
      id: charId,
      val: char,
      progress: 10 // start position
    }

    activeChars.value.push(newChar)

    // Animate this char
    let progress = 10
    const interval = setInterval(() => {
      progress += 4 // Faster speed
      const charObj = activeChars.value.find((c) => c.id === charId)
      if (charObj) charObj.progress = progress

      if (progress >= 90) {
        clearInterval(interval)
        // Remove from stream and add to screen
        activeChars.value = activeChars.value.filter((c) => c.id !== charId)
        typedContent.value += char

        // Next char
        index++
        setTimeout(processNextChar, 100) // Faster typing
      }
    }, 20)
  }

  processNextChar()
}

// GUI Logic
const isGuiAnimating = ref(false)
const isGuiClicking = ref(false)
const guiEvents = ref([]) // Array of events
const iconSelected = ref(false)
const inputMousePosition = ref({ x: 80, y: 60 }) // Input side (Invisible physical mouse)
const screenCursorPosition = ref({ x: 80, y: 60 }) // Output side (Visible screen cursor)

const cursorStyle = computed(() => ({
  transform: `translate(${screenCursorPosition.value.x}px, ${screenCursorPosition.value.y}px)`
}))

const startGuiSimulation = () => {
  if (isGuiAnimating.value) return
  isGuiAnimating.value = true
  iconSelected.value = false
  inputMousePosition.value = { x: 80, y: 60 }
  screenCursorPosition.value = { x: 80, y: 60 }
  guiEvents.value = []

  // 1. Move Cursor (Physical Mouse Movement)
  let step = 0
  const moveInterval = setInterval(() => {
    step++
    inputMousePosition.value = {
      x: 80 - step * 2,
      y: 60 - step * 1.5
    }

    // Emit Move Event frequently (Simulate high polling rate)
    if (step % 2 === 0) {
      const targetX = inputMousePosition.value.x
      const targetY = inputMousePosition.value.y
      emitGuiEvent(
        `Move(${Math.round(targetX)},${Math.round(targetY)})`,
        () => {
          // When packet arrives: Update screen cursor
          screenCursorPosition.value = { x: targetX, y: targetY }
        }
      )
    }

    if (step >= 20) {
      clearInterval(moveInterval)
      // 2. Click
      performClick()
    }
  }, 50)
}

const emitGuiEvent = (type, onArrive) => {
  const eventId = Date.now() + Math.random()
  const newEvent = {
    id: eventId,
    type: type,
    progress: 10
  }
  guiEvents.value.push(newEvent)

  let progress = 10
  const packetInterval = setInterval(() => {
    progress += 2
    const ev = guiEvents.value.find((e) => e.id === eventId)
    if (ev) ev.progress = progress

    if (progress >= 90) {
      clearInterval(packetInterval)
      guiEvents.value = guiEvents.value.filter((e) => e.id !== eventId)

      // Execute callback when packet arrives at Output
      if (onArrive) onArrive()
    }
  }, 10)
}

const performClick = () => {
  setTimeout(() => {
    isGuiClicking.value = true

    // Send Click Event
    emitGuiEvent('Click(40,30)', () => {
      // When packet arrives: Select icon
      iconSelected.value = true

      setTimeout(() => {
        isGuiAnimating.value = false
      }, 1000)
    })

    setTimeout(() => {
      isGuiClicking.value = false
    }, 200) // Input click feedback is fast
  }, 300)
}
</script>

<style scoped>
.terminal-definition {
  background: #09090b;
  border: 1px solid #27272a;
  border-radius: 12px;
  padding: 20px;
  font-family: 'JetBrains Mono', monospace;
  margin: 20px 0;
}

.mode-switch {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  border-bottom: 1px solid #27272a;
  padding-bottom: 15px;
}

.mode-switch button {
  background: transparent;
  border: 1px solid transparent;
  color: #71717a;
  padding: 6px 12px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  transition: all 0.2s;
}

.mode-switch button.active {
  background: #27272a;
  color: #e4e4e7;
  border-color: #3f3f46;
}

.mode-switch button:hover {
  color: #e4e4e7;
}

.flow-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
  height: 120px;
}

.stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 2;
  position: relative;
  width: 100px;
}

.input-stage {
  flex: 0 0 auto;
}

.output-stage {
  flex: 0 0 auto;
}

.icon-box {
  width: 60px;
  height: 60px;
  background: #18181b;
  border: 1px solid #3f3f46;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #a1a1aa;
  margin-bottom: 10px;
  transition: all 0.2s;
}

.icon-box.clicking {
  transform: scale(0.9);
  border-color: #22d3ee;
  color: #22d3ee;
}

.terminal-screen {
  width: 140px;
  height: 80px;
  background: #000;
  border: 1px solid #3f3f46;
  border-radius: 6px;
  padding: 10px;
  color: #22c55e;
  font-size: 12px;
  display: flex;
  align-items: flex-start;
  margin-bottom: 10px;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.2);
  overflow: hidden;
}

.gui-screen {
  width: 140px;
  height: 80px;
  background: #27272a;
  border: 1px solid #52525b;
  border-radius: 4px;
  margin-bottom: 10px;
  overflow: hidden;
  position: relative;
}

.window-frame {
  background: #3f3f46;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.win-header {
  height: 12px;
  background: #52525b;
  border-bottom: 1px solid #27272a;
}

.win-body {
  flex: 1;
  background: #18181b; /* Wallpaper */
  position: relative;
  padding: 10px;
}

.icon-grid {
  display: flex;
  gap: 10px;
}

.desktop-icon {
  font-size: 16px;
  padding: 2px;
  border-radius: 4px;
  border: 1px solid transparent;
}

.desktop-icon.selected {
  background: rgba(34, 211, 238, 0.2);
  border-color: #22d3ee;
}

.gui-cursor {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  transition: transform 0.1s linear; /* Smooth interpolation */
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.5));
}

.screen-content {
  word-break: break-all;
}

.label {
  font-size: 13px;
  font-weight: 600;
  color: #e4e4e7;
  text-align: center;
}

.sub-label {
  font-size: 10px;
  color: #71717a;
  margin-top: 2px;
  text-align: center;
}

.stream-path {
  flex: 1;
  height: 60px;
  position: relative;
  margin: 0 10px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.stream-line {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 2px;
  background: #27272a;
  transform: translateY(-50%);
}

.stream-line.dashed {
  background: repeating-linear-gradient(
    90deg,
    #27272a 0,
    #27272a 6px,
    transparent 6px,
    transparent 10px
  );
  height: 1px;
}

.stream-line::after {
  content: '';
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  border-left: 6px solid #27272a;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
}

.stream-label {
  position: absolute;
  top: 10px;
  font-size: 10px;
  color: #52525b;
  background: #09090b;
  padding: 0 8px;
}

.stream-char {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  background: #22d3ee;
  color: #000;
  font-weight: bold;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 14px;
  box-shadow: 0 0 10px rgba(34, 211, 238, 0.3);
  z-index: 10;
}

.gui-event-packet {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  background: #facc15;
  color: #000;
  font-weight: bold;
  padding: 2px 6px;
  border-radius: 10px;
  font-size: 10px;
  box-shadow: 0 0 5px rgba(250, 204, 21, 0.3);
  white-space: nowrap;
  z-index: 10;
}

.cursor {
  animation: blink 1s step-end infinite;
}

@keyframes blink {
  50% {
    opacity: 0;
  }
}

.desc-box {
  background: #18181b;
  padding: 12px;
  border-radius: 6px;
  margin-bottom: 15px;
  font-size: 13px;
  color: #a1a1aa;
  line-height: 1.5;
}

.desc-box strong {
  color: #e4e4e7;
}

.control-bar {
  display: flex;
  justify-content: center;
}

button {
  background: #18181b;
  color: #e4e4e7;
  border: 1px solid #27272a;
  padding: 8px 16px;
  border-radius: 6px;
  cursor: pointer;
  font-family: inherit;
  font-size: 13px;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  gap: 8px;
}

button:hover:not(:disabled) {
  background: #27272a;
  border-color: #52525b;
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

@media (max-width: 600px) {
  .flow-container {
    flex-direction: column;
    height: auto;
    gap: 20px;
  }

  .stream-path {
    width: 100%;
    height: 40px;
    margin: 10px 0;
  }

  .stream-line {
    transform: rotate(90deg);
    width: 40px;
    left: 50%;
    margin-left: -20px;
  }
}
</style>
