<template>
  <div
    role="group"
    aria-label="Date range presets"
    class="flex flex-wrap gap-1.5"
    @keydown="onKeydown"
  >
    <button
      v-for="(preset, index) in presets"
      :key="preset.label"
      type="button"
      :aria-pressed="isActive(preset)"
      :tabindex="index === focusedIndex ? 0 : -1"
      :ref="(el) => { if (el) buttonRefs[index] = el as HTMLButtonElement }"
      class="px-3 py-1 text-[0.6875rem] font-medium rounded-full border transition-colors duration-150"
      :class="isActive(preset)
        ? 'bg-accent text-bg-base border-accent'
        : 'border-border-subtle text-text-secondary hover:text-text-primary hover:border-border-visible'"
      @click="selectPreset(preset)"
    >
      {{ preset.label }}
    </button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const props = defineProps<{
  startDate?: string
  endDate?: string
}>()

const emit = defineEmits<{
  select: [payload: { start: string; end: string }]
}>()

const focusedIndex = ref(0)
const buttonRefs = ref<HTMLButtonElement[]>([])

interface Preset {
  label: string
  getRange: () => { start: string; end: string }
}

function fmt(d: Date): string {
  const y = d.getFullYear()
  const m = String(d.getMonth() + 1).padStart(2, '0')
  const dd = String(d.getDate()).padStart(2, '0')
  return `${y}-${m}-${dd}`
}

function getMonday(d: Date): Date {
  const result = new Date(d)
  const day = result.getDay()
  const diff = day === 0 ? -6 : 1 - day
  result.setDate(result.getDate() + diff)
  return result
}

const presets: Preset[] = [
  {
    label: 'Today',
    getRange: () => {
      const today = fmt(new Date())
      return { start: today, end: today }
    },
  },
  {
    label: 'This Week',
    getRange: () => {
      const now = new Date()
      const monday = getMonday(now)
      const sunday = new Date(monday)
      sunday.setDate(monday.getDate() + 6)
      return { start: fmt(monday), end: fmt(sunday) }
    },
  },
  {
    label: 'Last Week',
    getRange: () => {
      const now = new Date()
      const thisMonday = getMonday(now)
      const lastMonday = new Date(thisMonday)
      lastMonday.setDate(thisMonday.getDate() - 7)
      const lastSunday = new Date(lastMonday)
      lastSunday.setDate(lastMonday.getDate() + 6)
      return { start: fmt(lastMonday), end: fmt(lastSunday) }
    },
  },
  {
    label: 'This Month',
    getRange: () => {
      const now = new Date()
      const first = new Date(now.getFullYear(), now.getMonth(), 1)
      const last = new Date(now.getFullYear(), now.getMonth() + 1, 0)
      return { start: fmt(first), end: fmt(last) }
    },
  },
  {
    label: 'Last Month',
    getRange: () => {
      const now = new Date()
      const first = new Date(now.getFullYear(), now.getMonth() - 1, 1)
      const last = new Date(now.getFullYear(), now.getMonth(), 0)
      return { start: fmt(first), end: fmt(last) }
    },
  },
  {
    label: 'This Quarter',
    getRange: () => {
      const now = new Date()
      const qMonth = Math.floor(now.getMonth() / 3) * 3
      const first = new Date(now.getFullYear(), qMonth, 1)
      const last = new Date(now.getFullYear(), qMonth + 3, 0)
      return { start: fmt(first), end: fmt(last) }
    },
  },
  {
    label: 'Last 30 Days',
    getRange: () => {
      const now = new Date()
      const start = new Date(now)
      start.setDate(now.getDate() - 29)
      return { start: fmt(start), end: fmt(now) }
    },
  },
  {
    label: 'This Year',
    getRange: () => {
      const now = new Date()
      const first = new Date(now.getFullYear(), 0, 1)
      return { start: fmt(first), end: fmt(now) }
    },
  },
]

function isActive(preset: Preset): boolean {
  if (!props.startDate || !props.endDate) return false
  const range = preset.getRange()
  return range.start === props.startDate && range.end === props.endDate
}

function selectPreset(preset: Preset) {
  const range = preset.getRange()
  emit('select', range)
}

function onKeydown(e: KeyboardEvent) {
  let next = focusedIndex.value
  if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
    e.preventDefault()
    next = (focusedIndex.value + 1) % presets.length
  } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
    e.preventDefault()
    next = (focusedIndex.value - 1 + presets.length) % presets.length
  } else if (e.key === 'Home') {
    e.preventDefault()
    next = 0
  } else if (e.key === 'End') {
    e.preventDefault()
    next = presets.length - 1
  } else {
    return
  }
  focusedIndex.value = next
  buttonRefs.value[next]?.focus()
}
</script>
