<script setup lang="ts">
import { ref, computed, nextTick } from 'vue'
import { X } from 'lucide-vue-next'

interface Props {
  modelValue: string
  label?: string
}

const props = withDefaults(defineProps<Props>(), {
  label: '',
})

const emit = defineEmits<{
  'update:modelValue': [value: string]
}>()

const recording = ref(false)
const announcement = ref('')
const recorderRef = ref<HTMLDivElement | null>(null)

const isMac = navigator.platform.toUpperCase().includes('MAC')

const keyChips = computed(() => {
  if (!props.modelValue) return []
  return props.modelValue.split('+').map(k =>
    k === 'CmdOrCtrl' ? (isMac ? 'Cmd' : 'Ctrl') : k
  )
})

function startRecording() {
  recording.value = true
  announcement.value = 'Recording. Press your key combination.'
  nextTick(() => {
    recorderRef.value?.focus()
  })
}

function cancelRecording() {
  recording.value = false
  announcement.value = ''
}

function onKeydown(e: KeyboardEvent) {
  if (!recording.value) return

  e.preventDefault()
  e.stopPropagation()

  if (e.key === 'Escape') {
    cancelRecording()
    return
  }

  // Ignore standalone modifier keys
  const modifierKeys = ['Control', 'Shift', 'Alt', 'Meta']
  if (modifierKeys.includes(e.key)) return

  // Must have at least one modifier
  const hasModifier = e.ctrlKey || e.metaKey || e.shiftKey || e.altKey
  if (!hasModifier) return

  // Build the shortcut string
  const parts: string[] = []

  if (e.ctrlKey || e.metaKey) {
    parts.push('CmdOrCtrl')
  }
  if (e.shiftKey) {
    parts.push('Shift')
  }
  if (e.altKey) {
    parts.push('Alt')
  }

  // Normalize the key name
  let key = e.key
  if (key === ' ') {
    key = 'Space'
  } else if (key.length === 1) {
    key = key.toUpperCase()
  }

  parts.push(key)

  const combo = parts.join('+')
  recording.value = false
  emit('update:modelValue', combo)
  announcement.value = `Shortcut set to ${combo}`
}

function clearShortcut() {
  emit('update:modelValue', '')
  announcement.value = 'Shortcut cleared'
}
</script>

<template>
  <div role="group" :aria-label="label || 'Keyboard shortcut'" class="inline-flex items-center gap-2">
    <!-- Key chips display -->
    <div v-if="!recording && modelValue" class="flex items-center gap-1" aria-hidden="true">
      <template v-for="(chip, index) in keyChips" :key="index">
        <span
          class="px-1.5 py-0.5 bg-bg-elevated border border-border-subtle rounded text-text-secondary font-mono text-[0.6875rem]"
        >{{ chip }}</span>
        <span v-if="index < keyChips.length - 1" class="text-text-tertiary text-[0.6875rem]">+</span>
      </template>
    </div>

    <!-- Screen reader text -->
    <span class="sr-only">Current shortcut: {{ modelValue || 'None' }}</span>

    <!-- Recording capture area (focused div) -->
    <div
      v-if="recording"
      ref="recorderRef"
      tabindex="0"
      role="application"
      aria-label="Press your key combination"
      @keydown="onKeydown"
      @blur="cancelRecording"
      class="flex items-center gap-2 px-3 py-1 border border-accent rounded-lg bg-bg-inset focus:outline-none focus:ring-1 focus:ring-accent"
    >
      <span class="text-[0.75rem] text-accent motion-safe:animate-pulse">Press keys...</span>
      <button
        type="button"
        aria-label="Cancel recording"
        @mousedown.prevent="cancelRecording"
        class="text-[0.6875rem] text-text-tertiary hover:text-text-primary transition-colors"
      >
        Cancel
      </button>
    </div>

    <!-- Record button -->
    <button
      v-if="!recording"
      type="button"
      aria-label="Record shortcut"
      @click="startRecording"
      class="px-2.5 py-1 text-[0.6875rem] font-medium border border-border-subtle text-text-secondary rounded-lg hover:bg-bg-elevated hover:text-text-primary transition-colors"
    >
      Record
    </button>

    <!-- Clear button -->
    <button
      v-if="!recording && modelValue"
      type="button"
      aria-label="Clear shortcut"
      v-tooltip="'Clear shortcut'"
      @click="clearShortcut"
      class="w-5 h-5 flex items-center justify-center text-text-tertiary hover:text-text-primary transition-colors"
    >
      <X class="w-3.5 h-3.5" :stroke-width="2" aria-hidden="true" />
    </button>

    <!-- aria-live region for announcements -->
    <div class="sr-only" aria-live="assertive" aria-atomic="true">{{ announcement }}</div>
  </div>
</template>
