<template>
  <div data-test="month-grid">
    <div class="grid grid-cols-8">
      <div class="flex h-8 items-center justify-center text-xs font-medium uppercase text-m-muted">
        Sem
      </div>
      <div
        v-for="d in dayLabels"
        :key="d"
        class="flex h-8 items-center justify-center text-xs font-medium uppercase text-m-muted"
      >
        {{ d }}
      </div>

      <template
        v-for="week in weeks"
        :key="week.days[0].isoDate"
      >
        <div
          data-test="week-number"
          class="flex h-10 items-center justify-center bg-m-primary/10 text-sm text-m-primary/70"
        >
          {{ week.weekNumber }}
        </div>
        <button
          v-for="cell in week.days"
          :key="cell.isoDate"
          type="button"
          data-test="day"
          :data-iso="cell.isoDate"
          :disabled="!inRange(cell.isoDate)"
          :aria-label="ariaLabel(cell)"
          :aria-disabled="!inRange(cell.isoDate)"
          class="flex h-10 w-10 items-center justify-center text-sm transition-colors duration-100"
          :class="cellClass(cell)"
          @click="onSelect(cell.isoDate)"
        >
          {{ cell.day }}
        </button>
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
import {toRef} from 'vue'
import {useMonthMatrix, type DayCell} from '../composables/useMonthMatrix'
import {isDateInRange} from '../composables/dateFormat'

defineOptions({name: 'MalioDateMonthGrid'})

const props = withDefaults(
  defineProps<{
    month: number
    year: number
    selectedDate?: string | null
    min?: string
    max?: string
  }>(),
  {selectedDate: null, min: undefined, max: undefined},
)

const emit = defineEmits<{(e: 'select', iso: string): void}>()

const dayLabels = ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim']
const monthsLong = ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',
  'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre']

const {weeks} = useMonthMatrix(toRef(props, 'month'), toRef(props, 'year'))

const inRange = (iso: string) => isDateInRange(iso, props.min, props.max)

const ariaLabel = (cell: DayCell) => {
  const [, m, d] = cell.isoDate.split('-')
  return `${Number(d)} ${monthsLong[Number(m) - 1]} ${cell.isoDate.slice(0, 4)}`
}

const cellClass = (cell: DayCell) => {
  const selected = props.selectedDate === cell.isoDate
  if (!inRange(cell.isoDate)) return 'text-m-muted/30 cursor-not-allowed'
  if (selected) return 'bg-m-primary text-white font-medium rounded-full'
  const parts = ['cursor-pointer hover:bg-m-primary/10 rounded-full']
  if (cell.isToday) parts.push('border border-m-primary text-m-primary font-semibold')
  else if (cell.isCurrentMonth) parts.push('text-black')
  else parts.push('text-m-muted/50')
  return parts.join(' ')
}

const onSelect = (iso: string) => {
  if (!inRange(iso)) return
  emit('select', iso)
}
</script>
