<script setup>
import { useCalendarStore } from '@/stores/CalendarStore'
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
import BaseDialog from './BaseDialog.vue'
import WeekdaySelector from './WeekdaySelector.vue'
import Numeric from './Numeric.vue'
import { addDaysStr, getMondayOfISOWeek } from '@/utils/date'

const props = defineProps({
  selection: { type: Object, default: () => ({ startDate: null, dayCount: 0 }) },
})

const emit = defineEmits(['clear-selection'])

const calendarStore = useCalendarStore()

const showDialog = ref(false)
const dialogMode = ref('create') // 'create' or 'edit'
const editingEventId = ref(null) // base event id if repeating occurrence clicked
// Track the id of an unsaved event created in the current create dialog session
const unsavedCreateId = ref(null)
const occurrenceContext = ref(null) // { baseId, occurrenceIndex, weekday, occurrenceDate }
const title = ref('')
const recurrenceEnabled = ref(false)
const recurrenceInterval = ref(1) // N in "Every N weeks/months"
const recurrenceFrequency = ref('weeks') // 'weeks' | 'months'
const recurrenceWeekdays = ref([false, false, false, false, false, false, false])
const recurrenceOccurrences = ref(0) // 0 = unlimited
const colorId = ref(0)
const eventSaved = ref(false)
const titleInput = ref(null)
const modalRef = ref(null)

// Drag functionality
const isDragging = ref(false)
const dragOffset = ref({ x: 0, y: 0 })
const modalPosition = ref({ x: 0, y: 0 })

function startDrag(event) {
  if (!modalRef.value) return

  isDragging.value = true
  const rect = modalRef.value.getBoundingClientRect()
  dragOffset.value = {
    x: event.clientX - rect.left,
    y: event.clientY - rect.top,
  }

  // Set pointer capture for better touch handling
  if (event.pointerId !== undefined) {
    try {
      event.target.setPointerCapture(event.pointerId)
    } catch (e) {
      console.warn('Could not set pointer capture:', e)
    }
  }

  document.addEventListener('pointermove', handleDrag, { passive: false })
  document.addEventListener('pointerup', stopDrag)
  document.addEventListener('pointercancel', stopDrag)
  event.preventDefault()
}

function handleDrag(event) {
  if (!isDragging.value || !modalRef.value) return

  modalPosition.value = {
    x: event.clientX - dragOffset.value.x,
    y: event.clientY - dragOffset.value.y,
  }

  event.preventDefault()
}

function stopDrag() {
  isDragging.value = false
  document.removeEventListener('pointermove', handleDrag)
  document.removeEventListener('pointerup', stopDrag)
  document.removeEventListener('pointercancel', stopDrag)
}

const modalStyle = computed(() => {
  if (modalPosition.value.x !== 0 || modalPosition.value.y !== 0) {
    return {
      transform: 'none',
      left: `${modalPosition.value.x}px`,
      top: `${modalPosition.value.y}px`,
    }
  }
  return {}
})

// Helper to get starting weekday (Sunday-first index)
function getStartingWeekday(selectionData = null) {
  const currentSelection = selectionData || props.selection
  if (!currentSelection.start) return 0 // Default to Sunday
  const date = new Date(currentSelection.start + 'T00:00:00')
  const dayOfWeek = date.getDay() // 0=Sunday, 1=Monday, ...
  return dayOfWeek // Keep Sunday-first (0=Sunday, 6=Saturday)
}

// Computed property for fallback weekdays - true for the initial day of the event, false for others
const fallbackWeekdays = computed(() => {
  const startingDay = getStartingWeekday()
  const fallback = [false, false, false, false, false, false, false]
  fallback[startingDay] = true
  return fallback
})

// Repeat mapping uses 'weeks' | 'months' | 'none' directly
const repeat = computed({
  get() {
    if (!recurrenceEnabled.value) return 'none'
    return recurrenceFrequency.value // 'weeks' | 'months'
  },
  set(val) {
    if (val === 'none') {
      recurrenceEnabled.value = false
      return
    }
    recurrenceEnabled.value = true
    if (val === 'weeks') recurrenceFrequency.value = 'weeks'
    else if (val === 'months') recurrenceFrequency.value = 'months'
  },
})

// Convert Sunday-first recurrenceWeekdays to Sunday-first pattern for store
function buildStoreWeekdayPattern() {
  // store expects Sun..Sat; we have Sun..Sat
  // Direct mapping: recurrenceWeekdays indices 0..6 (Sun..Sat) -> store array [Sun,Mon,Tue,Wed,Thu,Fri,Sat]
  let sunFirst = [...recurrenceWeekdays.value]

  // Ensure at least one day is selected - fallback to starting day
  if (!sunFirst.some(Boolean)) {
    const startingDay = getStartingWeekday()
    sunFirst[startingDay] = true
  }

  return sunFirst
}

function loadWeekdayPatternFromStore(storePattern) {
  if (!Array.isArray(storePattern) || storePattern.length !== 7) return
  // store: Sun..Sat -> keep as Sun..Sat
  recurrenceWeekdays.value = [...storePattern]
}

const selectedColor = computed({
  get: () => colorId.value,
  set: (val) => {
    colorId.value = parseInt(val)
    // Update the event immediately when color changes
    if (editingEventId.value) {
      updateEventInStore()
    }
  },
})

function openCreateDialog(selectionData = null) {
  // Start a fresh create dialog; delete any prior unsaved create
  if (unsavedCreateId.value && !eventSaved.value) {
    if (calendarStore.events?.has(unsavedCreateId.value)) {
      calendarStore.deleteEvent(unsavedCreateId.value)
    }
    unsavedCreateId.value = null
  }
  // Reset saved flag for new create
  const currentSelection = selectionData || props.selection

  // Convert new format to start/end for compatibility with existing logic
  let start, end
  if (currentSelection.startDate && currentSelection.dayCount) {
    start = currentSelection.startDate
    end = addDaysStr(currentSelection.startDate, currentSelection.dayCount - 1)
  } else if (currentSelection.start && currentSelection.end) {
    // Fallback for old format
    start = currentSelection.start
    end = currentSelection.end
  } else {
    start = null
    end = null
  }

  occurrenceContext.value = null
  dialogMode.value = 'create'
  title.value = ''
  recurrenceEnabled.value = false
  recurrenceInterval.value = 1
  recurrenceFrequency.value = 'weeks'
  recurrenceWeekdays.value = [false, false, false, false, false, false, false]
  recurrenceOccurrences.value = 0
  colorId.value = calendarStore.selectEventColorId(start, end)
  eventSaved.value = false

  const startingDay = getStartingWeekday({ start, end })
  recurrenceWeekdays.value[startingDay] = true

  editingEventId.value = calendarStore.createEvent({
    title: '',
    startDate: start,
    endDate: end,
    colorId: colorId.value,
    repeat: repeat.value,
    repeatInterval: recurrenceInterval.value,
    repeatCount:
      recurrenceOccurrences.value === 0 ? 'for now' : String(recurrenceOccurrences.value),
    repeatWeekdays: buildStoreWeekdayPattern(),
  })
  // Track unsaved create id until saved or discarded
  unsavedCreateId.value = editingEventId.value

  showDialog.value = true

  // Focus and select text after dialog is shown
  nextTick(() => {
    if (titleInput.value) {
      titleInput.value.focus()
      if (title.value) {
        titleInput.value.select()
      }
    }
  })
}

function openEditDialog(payload) {
  // If we are switching away from an unsaved create to a DIFFERENT event, remove the temporary one.
  // If user clicked the same newly created event again, keep it (no deletion, no dialog flicker).
  if (
    dialogMode.value === 'create' &&
    unsavedCreateId.value &&
    !eventSaved.value &&
    payload &&
    unsavedCreateId.value !== payload.id
  ) {
    if (calendarStore.events?.has(unsavedCreateId.value)) {
      calendarStore.deleteEvent(unsavedCreateId.value)
    }
    unsavedCreateId.value = null
  }
  occurrenceContext.value = null
  if (!payload) return
  // Payload expected: { id: baseId, instanceId, occurrenceIndex }
  const baseId = payload.id
  let occurrenceIndex = payload.occurrenceIndex || 0
  let weekday = null
  let occurrenceDate = null

  const event = calendarStore.getEventById(baseId)
  if (!event) return
  // Compute occurrenceDate based on occurrenceIndex rather than parsing instanceId
  if (event.isRepeating) {
    if (event.repeat === 'weeks' && occurrenceIndex >= 0) {
      const pattern = event.repeatWeekdays || []
      const baseStart = new Date(event.startDate + 'T00:00:00')
      const baseEnd = new Date(event.endDate + 'T00:00:00')
      if (occurrenceIndex === 0) {
        occurrenceDate = baseStart
        weekday = baseStart.getDay()
      } else {
        // Count valid repeat occurrences (pattern + interval alignment) AFTER the base span
        const interval = event.repeatInterval || 1
        const WEEK_MS = 7 * 86400000
        const baseBlockStart = getMondayOfISOWeek(baseStart)
        function isAligned(d) {
          const blk = getMondayOfISOWeek(d)
          const diff = Math.floor((blk - baseBlockStart) / WEEK_MS)
          return diff % interval === 0
        }
        let cur = new Date(baseEnd)
        cur.setDate(cur.getDate() + 1)
        let found = 0 // number of repeat occurrences found so far
        let safety = 0
        while (found < occurrenceIndex && safety < 20000) {
          if (pattern[cur.getDay()] && isAligned(cur)) {
            found++
            if (found === occurrenceIndex) break
          }
          cur.setDate(cur.getDate() + 1)
          safety++
        }
        occurrenceDate = cur
        weekday = cur.getDay()
      }
    } else if (event.repeat === 'months' && occurrenceIndex >= 0) {
      const baseDate = new Date(event.startDate + 'T00:00:00')
      const cur = new Date(baseDate)
      cur.setMonth(cur.getMonth() + occurrenceIndex)
      occurrenceDate = cur
    }
  }
  dialogMode.value = 'edit'
  editingEventId.value = baseId
  title.value = event.title
  loadWeekdayPatternFromStore(event.repeatWeekdays)
  repeat.value = event.repeat // triggers setter mapping into recurrence state
  if (event.repeatInterval) recurrenceInterval.value = event.repeatInterval
  // Map repeatCount
  const rc = event.repeatCount ?? 'unlimited'
  recurrenceOccurrences.value = rc === 'unlimited' ? 0 : parseInt(rc, 10) || 0
  colorId.value = event.colorId
  eventSaved.value = false
  // Build occurrence context: treat any occurrenceIndex > 0 as a specific occurrence (weekday only relevant for weekly)
  if (event.isRepeating) {
    if (event.repeat === 'weeks' && occurrenceIndex >= 0) {
      occurrenceContext.value = { baseId, occurrenceIndex, weekday, occurrenceDate }
    } else if (event.repeat === 'months' && occurrenceIndex > 0) {
      occurrenceContext.value = { baseId, occurrenceIndex, weekday: null, occurrenceDate }
    }
  }
  showDialog.value = true

  // Focus and select text after dialog is shown
  nextTick(() => {
    if (titleInput.value) {
      titleInput.value.focus()
      if (title.value) {
        titleInput.value.select()
      }
    }
  })
}

function closeDialog() {
  showDialog.value = false
  // If we were creating a new event and user cancels (didn't save), delete it
  if (unsavedCreateId.value && !eventSaved.value) {
    if (calendarStore.events?.has(unsavedCreateId.value)) {
      calendarStore.deleteEvent(unsavedCreateId.value)
    }
  }
  editingEventId.value = null
  unsavedCreateId.value = null
}

function updateEventInStore() {
  if (!editingEventId.value) return

  // For simple property updates (title, color, repeat), update all instances directly
  // This avoids the expensive remove/re-add cycle
  if (calendarStore.events?.has(editingEventId.value)) {
    const event = calendarStore.events.get(editingEventId.value)
    event.title = title.value
    event.colorId = colorId.value
    event.repeat = repeat.value
    event.repeatInterval = recurrenceInterval.value
    event.repeatWeekdays = buildStoreWeekdayPattern()
    event.repeatCount =
      recurrenceOccurrences.value === 0 ? 'unlimited' : String(recurrenceOccurrences.value)
    event.isRepeating = recurrenceEnabled.value && repeat.value !== 'none'
  }
}

function saveEvent() {
  if (editingEventId.value) updateEventInStore()
  eventSaved.value = true
  if (dialogMode.value === 'create') {
    // This create is now saved; clear tracking so it won't be auto-deleted
    unsavedCreateId.value = null
  }
  if (dialogMode.value === 'create') emit('clear-selection')
  closeDialog()
}

function deleteEventAll() {
  if (editingEventId.value) calendarStore.deleteEvent(editingEventId.value)
  closeDialog()
}

function deleteEventOne() {
  if (occurrenceContext.value) {
    calendarStore.deleteSingleOccurrence(occurrenceContext.value)
  } else if (isRepeatingBaseEdit.value && editingEventId.value) {
    calendarStore.deleteFirstOccurrence(editingEventId.value)
  }
  closeDialog()
}

function deleteEventFrom() {
  if (!occurrenceContext.value) return
  calendarStore.deleteFromOccurrence(occurrenceContext.value)
  closeDialog()
}

function toggleWeekday(index) {
  recurrenceWeekdays.value[index] = !recurrenceWeekdays.value[index]
}

// Watch for title changes and update the event immediately
watch(title, (newTitle) => {
  if (editingEventId.value && showDialog.value) {
    updateEventInStore()
  }
})

// Watch for dialog being closed unexpectedly and cleanup unsaved events
// Removed placeholder watcher

// Watch for editingEventId changes (switching to a different event while create in progress)
// Removed editingEventId placeholder cleanup watcher

// Cleanup drag listeners on unmount
onUnmounted(() => {
  if (unsavedCreateId.value && !eventSaved.value) {
    if (calendarStore.events?.has(unsavedCreateId.value))
      calendarStore.deleteEvent(unsavedCreateId.value)
  }
  document.removeEventListener('pointermove', handleDrag)
  document.removeEventListener('pointerup', stopDrag)
  document.removeEventListener('pointercancel', stopDrag)
})

watch([recurrenceEnabled, recurrenceInterval, recurrenceFrequency], () => {
  if (editingEventId.value && showDialog.value) updateEventInStore()
})
watch(
  recurrenceWeekdays,
  () => {
    if (editingEventId.value && showDialog.value && repeat.value === 'weeks') updateEventInStore()
  },
  { deep: true },
)
watch(recurrenceOccurrences, () => {
  if (editingEventId.value && showDialog.value) updateEventInStore()
})

// Handle Esc key to close dialog
function handleKeydown(event) {
  if (event.key === 'Escape' && showDialog.value) {
    closeDialog()
  }
}

onMounted(() => {
  document.addEventListener('keydown', handleKeydown)
})

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown)
})

defineExpose({
  openCreateDialog,
  openEditDialog,
})

// Computed helpers for delete UI
const isRepeatingEdit = computed(
  () => dialogMode.value === 'edit' && recurrenceEnabled.value && repeat.value !== 'none',
)
const showDeleteVariants = computed(() => isRepeatingEdit.value && occurrenceContext.value)
const isRepeatingBaseEdit = computed(() => isRepeatingEdit.value && !occurrenceContext.value)
const formattedOccurrenceShort = computed(() => {
  if (occurrenceContext.value?.occurrenceDate) {
    try {
      return occurrenceContext.value.occurrenceDate
        .toLocaleDateString(undefined, { month: 'short', day: 'numeric' })
        .replace(/, /, ' ')
    } catch {
      /* noop */
    }
  }
  if (isRepeatingBaseEdit.value && editingEventId.value) {
    const ev = calendarStore.getEventById(editingEventId.value)
    if (ev?.startDate) {
      try {
        return new Date(ev.startDate + 'T00:00:00')
          .toLocaleDateString(undefined, { month: 'short', day: 'numeric' })
          .replace(/, /, ' ')
      } catch {
        /* noop */
      }
    }
  }
  return ''
})

// Short date shown in header (works for create, edit base, and occurrence)
const headerDateShort = computed(() => {
  // If editing a specific occurrence use that date
  if (occurrenceContext.value?.occurrenceDate) {
    try {
      return occurrenceContext.value.occurrenceDate
        .toLocaleDateString(undefined, { month: 'short', day: 'numeric' })
        .replace(/, /, ' ')
    } catch {
      return ''
    }
  }
  // Otherwise use the base event start date (covers create + edit base)
  if (editingEventId.value) {
    const ev = calendarStore.getEventById(editingEventId.value)
    if (ev?.startDate) {
      try {
        return new Date(ev.startDate + 'T00:00:00')
          .toLocaleDateString(undefined, { month: 'short', day: 'numeric' })
          .replace(/, /, ' ')
      } catch {
        return ''
      }
    }
  }
  return ''
})

const finalOccurrenceDate = computed(() => {
  if (!recurrenceEnabled.value) return null
  const count = recurrenceOccurrences.value
  if (!count || count < 1) return null // unlimited or invalid
  // Need start date
  const base = editingEventId.value ? calendarStore.getEventById(editingEventId.value) : null
  if (!base) return null
  const start = new Date(base.startDate + 'T00:00:00')
  if (recurrenceFrequency.value === 'weeks') {
    // iterate days until we count 'count-1' additional occurrences (first is base if selected weekday)
    const pattern = buildStoreWeekdayPattern() // Sun..Sat
    // Build Monday-first pattern again for selection clarity
    const monFirst = recurrenceWeekdays.value
    const selectedCount = monFirst.some(Boolean)
    if (!selectedCount) return null
    let occs = 0
    // Determine if the start day counts
    const startWeekdaySun = start.getDay()
    // Convert to Monday-first index
    // We'll just check store pattern
    if (pattern[startWeekdaySun]) occs = 1
    let cursor = new Date(start)
    while (occs < count && occs < 10000) {
      cursor.setDate(cursor.getDate() + 1)
      if (pattern[cursor.getDay()]) occs++
    }
    if (occs === count) return cursor
    return null
  } else if (recurrenceFrequency.value === 'months') {
    const monthsToAdd = recurrenceInterval.value * (count - 1)
    const d = new Date(start)
    d.setMonth(d.getMonth() + monthsToAdd)
    return d
  }
})

const formattedFinalOccurrence = computed(() => {
  const d = finalOccurrenceDate.value
  if (!d) return ''
  const now = new Date()
  const includeYear =
    d.getFullYear() !== now.getFullYear() ||
    d.getTime() - now.getTime() >= 1000 * 60 * 60 * 24 * 365
  const opts = {
    weekday: 'short',
    month: 'short',
    day: 'numeric',
    ...(includeYear ? { year: 'numeric' } : {}),
  }
  try {
    return d.toLocaleDateString(undefined, opts)
  } catch {
    return d.toDateString()
  }
})

const recurrenceSummary = computed(() => {
  if (!recurrenceEnabled.value) return 'Does not recur'
  if (recurrenceFrequency.value === 'weeks') {
    return recurrenceInterval.value === 1 ? 'Weekly' : `Every ${recurrenceInterval.value} weeks`
  }
  // months frequency
  if (recurrenceInterval.value % 12 === 0) {
    const years = recurrenceInterval.value / 12
    return years === 1 ? 'Annually' : `Every ${years} years`
  }
  return recurrenceInterval.value === 1 ? 'Monthly' : `Every ${recurrenceInterval.value} months`
})
</script>

<template>
  <BaseDialog v-model="showDialog" @submit="saveEvent">
    <template #title>
      {{ dialogMode === 'create' ? 'Create Event' : 'Edit Event'
      }}<template v-if="headerDateShort"> · {{ headerDateShort }}</template>
    </template>
    <label class="ec-field" ref="modalRef">
      <input type="text" v-model="title" autocomplete="off" ref="titleInput" />
    </label>
    <div class="ec-color-swatches">
      <label v-for="i in 8" :key="i - 1" class="swatch-label">
        <input
          class="swatch"
          :class="'event-color-' + (i - 1)"
          type="radio"
          name="colorId"
          :value="i - 1"
          v-model="selectedColor"
        />
      </label>
    </div>
    <div class="recurrence-block">
      <div class="recurrence-header">
        <label class="switch">
          <input type="checkbox" v-model="recurrenceEnabled" />
          <span>Repeat</span>
        </label>
        <span class="recurrence-summary" v-if="recurrenceEnabled">
          {{ recurrenceSummary }}
          <template v-if="recurrenceOccurrences > 0">
            until {{ formattedFinalOccurrence }}</template
          >
        </span>
        <span class="recurrence-summary muted" v-else>Does not recur</span>
      </div>
      <div v-if="recurrenceEnabled" class="recurrence-form">
        <div class="line compact">
          <Numeric
            v-model="recurrenceInterval"
            :prefix-values="[{ value: 1, display: 'Every' }]"
            :min="2"
            number-prefix="Every "
            aria-label="Interval"
          />
          <select v-model="recurrenceFrequency" class="freq-select">
            <option value="weeks">{{ recurrenceInterval === 1 ? 'week' : 'weeks' }}</option>
            <option value="months">{{ recurrenceInterval === 1 ? 'month' : 'months' }}</option>
          </select>
          <Numeric
            class="occ-stepper"
            v-model="recurrenceOccurrences"
            :min="2"
            :prefix-values="[{ value: 0, display: '∞' }]"
            number-postfix=" times"
            aria-label="Occurrences (0 = no end)"
            extra-class="occ"
          />
        </div>
        <div v-if="recurrenceFrequency === 'weeks'" @click.stop>
          <WeekdaySelector
            v-model="recurrenceWeekdays"
            :fallback="fallbackWeekdays"
            :first-day="calendarStore.config.first_day"
          />
        </div>
      </div>
    </div>
    <template #footer>
      <template v-if="dialogMode === 'create'">
        <button type="button" class="ec-btn delete-btn" @click="deleteEventAll">Delete</button>
        <button type="submit" class="ec-btn save-btn">Save</button>
      </template>
      <template v-else>
        <template v-if="showDeleteVariants">
          <div class="ec-delete-group">
            <button type="button" class="ec-btn delete-btn" @click="deleteEventOne">
              Delete {{ formattedOccurrenceShort }}
            </button>
            <button type="button" class="ec-btn delete-btn" @click="deleteEventFrom">Rest</button>
            <button type="button" class="ec-btn delete-btn" @click="deleteEventAll">All</button>
          </div>
        </template>
        <template v-else-if="isRepeatingBaseEdit">
          <div class="ec-delete-group">
            <button type="button" class="ec-btn delete-btn" @click="deleteEventOne">
              Delete {{ formattedOccurrenceShort }}
            </button>
            <button type="button" class="ec-btn delete-btn" @click="deleteEventAll">All</button>
          </div>
        </template>
        <template v-else>
          <button type="button" class="ec-btn delete-btn" @click="deleteEventAll">Delete</button>
        </template>
        <button type="button" class="ec-btn close-btn" @click="closeDialog">Close</button>
      </template>
    </template>
  </BaseDialog>
</template>

<style scoped>
.ec-field {
  display: grid;
  gap: 0.25rem;
}

.ec-field > span {
  font-size: 0.85em;
  color: var(--muted);
}

.ec-field input[type='text'],
.ec-field input[type='time'],
.ec-field input[type='number'],
.ec-field select {
  border: 1px solid var(--muted);
  border-radius: 0.4rem;
  padding: 0.5rem 0.6rem;
  width: 100%;
  background: transparent;
  color: var(--ink);
}

.ec-color-swatches {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
}

.ec-color-swatches .swatch {
  display: grid;
  place-items: center;
  border-radius: 0.4em;
  padding: 0.25em;
  outline: 0.125em solid transparent;
  outline-offset: 0.125em;
  cursor: pointer;
  appearance: none;
  width: 3em;
  height: 1em;
}

.ec-color-swatches .swatch:checked {
  outline-color: var(--ink);
}

.ec-footer {
  display: flex;
  justify-content: space-between;
  gap: 0.75em;
}

.ec-btn {
  border: 0.0625em solid var(--muted);
  background: transparent;
  color: var(--ink);
  padding: 0.5em 0.8em;
  border-radius: 0.4em;
  cursor: pointer;
  transition: all 0.2s ease;
}

.ec-btn:hover {
  background: var(--muted);
}

.ec-btn.save-btn {
  background: var(--today);
  color: #000;
  border-color: transparent;
  font-weight: 500;
}

.ec-btn.save-btn:hover {
  background: color-mix(in srgb, var(--today) 90%, black);
}

.ec-btn.close-btn {
  background: var(--panel);
  border-color: var(--muted);
  font-weight: 500;
}

.ec-btn.close-btn:hover {
  background: var(--muted);
}

.ec-btn.delete-btn {
  background: hsl(0, 70%, 50%);
  color: #fff;
  border-color: transparent;
  font-weight: 500;
}

.ec-btn.delete-btn:hover {
  background: hsl(0, 70%, 45%);
}

.ec-weekday-selector {
  display: grid;
  gap: 0.5em;
}

.ec-field-label {
  font-size: 0.85em;
  color: var(--muted);
}

.ec-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.25em;
}

.ec-weekday-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  cursor: pointer;
  padding: 0.5rem 0.25rem;
  border-radius: 0.3rem;
  transition: background-color 0.2s ease;
}

.ec-weekday-label:hover {
  background: var(--muted);
}

.ec-weekday-checkbox {
  margin: 0;
}

.ec-weekday-text {
  font-size: 0.8em;
  font-weight: 500;
  text-align: center;
}

/* New recurrence block */
.recurrence-block {
  display: grid;
  gap: 0.6em;
}
.recurrence-header {
  display: flex;
  align-items: center;
  gap: 0.75em;
}
.recurrence-header .recurrence-summary {
  font-size: 0.75rem;
  color: var(--ink);
  opacity: 0.85;
}
.recurrence-header .recurrence-summary.muted {
  opacity: 0.5;
}
.switch {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
  font-size: 0.85rem;
}
.switch input {
  width: 1rem;
  height: 1rem;
}
.recurrence-form {
  display: grid;
  gap: 0.6em;
  padding: 0.6em 0.75em 0.75em;
  border: 0.0625em solid var(--muted);
  border-radius: 0.5em;
  background: color-mix(in srgb, var(--muted) 15%, transparent);
}
.line.compact {
  display: flex;
  align-items: center;
  gap: 0.5em;
  flex-wrap: wrap;
  font-size: 0.75em;
}
.freq-select {
  padding: 0.4rem 0.55rem;
  font-size: 0.75rem;
  border: 1px solid var(--input-border);
  background: var(--panel-alt);
  color: var(--ink);
  border-radius: 0.45rem;
  transition:
    border-color 0.18s ease,
    background-color 0.18s ease;
}
.freq-select:focus {
  outline: none;
  border-color: var(--input-focus);
  background: var(--panel-accent);
  color: var(--ink);
  box-shadow:
    0 0 0 1px var(--input-focus),
    0 0 0 4px rgba(37, 99, 235, 0.15);
}
.interval-input,
.occ-input {
  display: none;
}
.ec-field input[type='text'] {
  border: 1px solid var(--input-border);
  background: var(--panel-alt);
  border-radius: 0.45rem;
  padding: 0.4rem 0.5rem;
  transition:
    border-color 0.18s ease,
    background-color 0.18s ease,
    box-shadow 0.18s ease;
}
.ec-field input[type='text']:focus {
  outline: none;
  border-color: var(--input-focus);
  background: var(--panel-accent);
  box-shadow:
    0 0 0 1px var(--input-focus),
    0 0 0 4px rgba(37, 99, 235, 0.15);
}
.mini-stepper {
  display: inline-flex;
  align-items: center;
  background: var(--panel-alt);
  border: 1px solid var(--input-border);
  border-radius: 0.5rem;
  overflow: hidden;
  font-size: 0.7rem;
  height: 1.9rem;
}
.mini-stepper .step {
  background: transparent;
  border: none;
  color: var(--ink);
  padding: 0 0.55rem;
  cursor: pointer;
  font-size: 0.9rem;
  line-height: 1;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  transition:
    background-color 0.15s ease,
    color 0.15s ease;
}
.mini-stepper .step:hover:not(:disabled) {
  background: var(--pill-hover-bg);
}
.mini-stepper .step:disabled {
  opacity: 0.35;
  cursor: default;
}
.mini-stepper .value {
  min-width: 1.6rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.mini-stepper:focus-within {
  border-color: var(--input-focus);
  box-shadow:
    0 0 0 1px var(--input-focus),
    0 0 0 4px rgba(37, 99, 235, 0.15);
}
.mini-stepper.occ .value {
  min-width: 2rem;
}
.occ-stepper.mini-stepper.occ .value {
  min-width: 2rem;
}
.mini-stepper .step:focus-visible {
  outline: 2px solid var(--input-focus);
  outline-offset: -2px;
}
.hint {
  font-size: 0.65rem;
  opacity: 0.65;
}

/* Recurrence UI */
.ec-recurrence-section {
  display: grid;
  gap: 0.4rem;
}
.ec-recurrence-toggle {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--muted);
  background: var(--panel);
  border-radius: 0.4rem;
  cursor: pointer;
  font-size: 0.9rem;
  text-align: left;
  transition: background-color 0.15s ease;
}
.ec-recurrence-toggle:hover {
  background: var(--muted);
}
.ec-recurrence-toggle .toggle-icon {
  transition: transform 0.2s ease;
  font-size: 0.7rem;
  color: var(--muted);
}
.ec-recurrence-toggle .toggle-icon.open {
  transform: rotate(180deg);
}
.ec-recurrence-panel {
  display: grid;
  gap: 0.6rem;
  padding: 0.6rem;
  border: 1px solid var(--muted);
  border-radius: 0.4rem;
  background: color-mix(in srgb, var(--muted) 20%, transparent);
}

/* Repeat modes */
.ec-repeat-modes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}
.ec-repeat-modes .mode-btn {
  flex: 1 1 auto;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--muted);
  background: var(--panel);
  border-radius: 0.4rem;
  cursor: pointer;
  font-size: 0.75rem;
  line-height: 1.1;
  white-space: nowrap;
  transition:
    background-color 0.15s ease,
    color 0.15s ease,
    border-color 0.15s ease;
}
.ec-repeat-modes .mode-btn.active {
  background: var(--today);
  color: #000;
  border-color: var(--today);
  font-weight: 600;
}
.ec-repeat-modes .mode-btn:hover {
  background: var(--muted);
}

.ec-occurrences-field {
  margin-top: 0.2rem;
}
.ec-occurrences-field .ec-field input[type='number'] {
  max-width: 6rem;
}
</style>
