<template>
  <div class="code-puzzle">
    <!-- Code zone -->
    <div class="bg-sky-dark rounded-lg border border-sky-dark-100 p-4 font-mono text-sm mb-6">
      <div
        v-for="(line, index) in shuffledLines"
        :key="index"
        class="code-line flex items-center gap-2 p-2 rounded cursor-grab transition-all"
        :class="[
          validationResult === true && 'bg-green-500/20 border-green-500/50',
          validationResult === false && line !== solution[index] && 'bg-red-500/20 border-red-500/50',
        ]"
        draggable="true"
        @dragstart="onDragStart($event, index)"
        @drop="onDrop($event, index)"
        @dragover="onDragOver"
      >
        <!-- Line number -->
        <span class="text-sky-text/60 select-none w-6 text-right">{{ index + 1 }}</span>

        <!-- Drag handle -->
        <span class="text-sky-text/60 cursor-grab select-none">::</span>

        <!-- Code -->
        <code class="flex-1 text-sky-accent">{{ line }}</code>

        <!-- Keyboard buttons (accessibility) -->
        <div class="flex gap-1">
          <button
            type="button"
            class="p-1 text-sky-text/60 hover:text-sky-text disabled:opacity-30"
            :disabled="index === 0"
            :aria-label="$t('challenge.moveUp')"
            @click="moveLineUp(index)"
          >
            ^
          </button>
          <button
            type="button"
            class="p-1 text-sky-text/60 hover:text-sky-text disabled:opacity-30"
            :disabled="index === shuffledLines.length - 1"
            :aria-label="$t('challenge.moveDown')"
            @click="moveLineDown(index)"
          >
            v
          </button>
        </div>
      </div>
    </div>

    <!-- Current hint -->
    <div
      v-if="currentHint"
      class="bg-sky-accent/10 border border-sky-accent/30 rounded-lg p-4 mb-6"
    >
      <p class="text-sm text-sky-accent">
        <span class="font-semibold">{{ $t('challenge.hintLabel') }}:</span>
        {{ currentHint }}
      </p>
    </div>

    <!-- Actions -->
    <div class="flex flex-wrap gap-4 justify-center">
      <!-- Validate button -->
      <button
        type="button"
        class="px-6 py-3 bg-sky-accent text-white font-ui font-semibold rounded-lg hover:bg-sky-accent/90 transition-colors disabled:opacity-50"
        :disabled="isValidating"
        @click="validateSolution"
      >
        {{ isValidating ? $t('challenge.validating') : $t('challenge.validate') }}
      </button>

      <!-- Hint button -->
      <button
        v-if="props.hintsUsed < 3"
        type="button"
        class="px-6 py-3 border border-sky-dark-100 text-sky-text font-ui rounded-lg hover:bg-sky-dark-50 transition-colors"
        @click="requestHint"
      >
        {{ $t('challenge.needHint') }} ({{ props.hintsUsed }}/3)
      </button>
    </div>

    <!-- Error message -->
    <Transition name="fade">
      <p
        v-if="validationResult === false"
        class="text-red-400 text-center mt-4 font-ui"
      >
        {{ $t('challenge.wrongOrder') }}
      </p>
    </Transition>
  </div>
</template>

<script setup lang="ts">
const props = defineProps<{
  hintsUsed: number
}>()

const emit = defineEmits<{
  solved: []
  hintUsed: []
}>()

const { t } = useI18n()

// Code lines (solution)
const solution = [
  'function unlockDeveloper() {',
  '  const secret = "SKYCEL";',
  '  const key = decode(secret);',
  '  if (key === "ACCESS_GRANTED") {',
  '    return showDeveloper();',
  '  }',
  '  return "Keep exploring...";',
  '}',
]

// Shuffled lines at start
const shuffledLines = ref<string[]>([])
const isValidating = ref(false)
const validationResult = ref<boolean | null>(null)

// Shuffle on mount
onMounted(() => {
  shuffledLines.value = [...solution].sort(() => Math.random() - 0.5)
})

// Progressive hints
const hints = computed(() => [
  t('challenge.hint1'),
  t('challenge.hint2'),
  t('challenge.hint3'),
])

const currentHint = computed(() => {
  if (props.hintsUsed === 0) return null
  return hints.value[Math.min(props.hintsUsed - 1, hints.value.length - 1)]
})

// Drag & Drop
function onDragStart(e: DragEvent, index: number) {
  e.dataTransfer?.setData('text/plain', index.toString())
}

function onDrop(e: DragEvent, targetIndex: number) {
  e.preventDefault()
  const sourceIndex = parseInt(e.dataTransfer?.getData('text/plain') || '-1')
  if (sourceIndex === -1) return

  // Swap lines
  const newLines = [...shuffledLines.value]
  const temp = newLines[sourceIndex]
  newLines[sourceIndex] = newLines[targetIndex]
  newLines[targetIndex] = temp
  shuffledLines.value = newLines
}

function onDragOver(e: DragEvent) {
  e.preventDefault()
}

// Validation
function validateSolution() {
  isValidating.value = true
  validationResult.value = null

  setTimeout(() => {
    const isCorrect = shuffledLines.value.every((line, i) => line === solution[i])
    validationResult.value = isCorrect

    if (isCorrect) {
      emit('solved')
    } else {
      // Reset after 2s
      setTimeout(() => {
        validationResult.value = null
        isValidating.value = false
      }, 2000)
    }
  }, 500)
}

function requestHint() {
  if (props.hintsUsed < 3) {
    emit('hintUsed')
  }
}

// Keyboard navigation
function moveLineUp(index: number) {
  if (index === 0) return
  const newLines = [...shuffledLines.value]
  const temp = newLines[index - 1]
  newLines[index - 1] = newLines[index]
  newLines[index] = temp
  shuffledLines.value = newLines
}

function moveLineDown(index: number) {
  if (index === shuffledLines.value.length - 1) return
  const newLines = [...shuffledLines.value]
  const temp = newLines[index + 1]
  newLines[index + 1] = newLines[index]
  newLines[index] = temp
  shuffledLines.value = newLines
}
</script>

<style scoped>
.code-line {
  border: 1px solid transparent;
}

.code-line:hover {
  background-color: rgba(250, 120, 79, 0.1);
}

.code-line:active {
  cursor: grabbing;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
