<template>
  <main class="neo-container page-padding">
    <div class="neo-list-header">
      <div class="header-left">
        <h1 class="neo-title">{{ t('choresPage.title') }}</h1>
        <div class="view-tabs" role="tablist">
          <button class="neo-tab-btn" :class="{ active: activeView === 'overdue' }" @click="activeView = 'overdue'"
            :disabled="isLoading" role="tab" :aria-selected="activeView === 'overdue'">
            <span class="material-icons">warning</span>
            {{ t('choresPage.tabs.overdue') }}
            <span v-if="counts.overdue > 0" class="neo-tab-count">{{ counts.overdue }}</span>
          </button>
          <button class="neo-tab-btn" :class="{ active: activeView === 'today' }" @click="activeView = 'today'"
            :disabled="isLoading" role="tab" :aria-selected="activeView === 'today'">
            <span class="material-icons">today</span>
            {{ t('choresPage.tabs.today') }}
            <span v-if="counts.today > 0" class="neo-tab-count">{{ counts.today }}</span>
          </button>
          <button class="neo-tab-btn" :class="{ active: activeView === 'upcoming' }" @click="activeView = 'upcoming'"
            :disabled="isLoading" role="tab" :aria-selected="activeView === 'upcoming'">
            <span class="material-icons">upcoming</span>
            {{ t('choresPage.tabs.upcoming') }}
          </button>
          <button class="neo-tab-btn" :class="{ active: activeView === 'all' }" @click="activeView = 'all'"
            :disabled="isLoading" role="tab" :aria-selected="activeView === 'all'">
            <span class="material-icons">list</span>
            {{ t('choresPage.tabs.allPending') }}
          </button>
          <button class="neo-tab-btn" :class="{ active: activeView === 'completed' }" @click="activeView = 'completed'"
            :disabled="isLoading" role="tab" :aria-selected="activeView === 'completed'">
            <span class="material-icons">check_circle</span>
            {{ t('choresPage.tabs.completed') }}
          </button>
        </div>
      </div>
      <div class="header-right">
        <div class="neo-view-toggle">
          <button class="neo-toggle-btn" :class="{ active: viewMode === 'calendar' }" @click="viewMode = 'calendar'"
            :disabled="isLoading" :aria-pressed="viewMode === 'calendar'" :aria-label="t('choresPage.viewToggle.calendarLabel')">
            <span class="material-icons">calendar_month</span>
            <span class="btn-text hide-text-on-mobile">{{ t('choresPage.viewToggle.calendarText') }}</span>
          </button>
          <button class="neo-toggle-btn" :class="{ active: viewMode === 'list' }" @click="viewMode = 'list'"
            :disabled="isLoading" :aria-pressed="viewMode === 'list'" :aria-label="t('choresPage.viewToggle.listLabel')">
            <span class="material-icons">view_list</span>
            <span class="btn-text hide-text-on-mobile">{{ t('choresPage.viewToggle.listText') }}</span>
          </button>
        </div>
        <button class="neo-action-button" @click="openCreateChoreModal(null)" :disabled="isLoading"
          :aria-label="t('choresPage.newChoreButtonLabel')">
          <span class="material-icons">add</span>
          <span class="btn-text hide-text-on-mobile-sm">{{ t('choresPage.newChoreButtonText') }}</span>
        </button>
      </div>
    </div>

    <!-- Loading State -->
    <div v-if="isLoading" class="neo-loading-state">
      <div class="loading-spinner"></div>
      <p>{{ t('choresPage.loadingState.loadingChores') }}</p>
    </div>

    <!-- Calendar View -->
    <div v-else-if="viewMode === 'calendar'" class="calendar-view">
      <div class="calendar-header">
        <button class="btn btn-icon" @click="previousMonth" :aria-label="t('choresPage.calendar.prevMonthLabel')">
          <span class="material-icons">chevron_left</span>
        </button>
        <h2>{{ currentMonthYear }}</h2>
        <button class="btn btn-icon" @click="nextMonth" :aria-label="t('choresPage.calendar.nextMonthLabel')">
          <span class="material-icons">chevron_right</span>
        </button>
      </div>
      <div v-if="calendarDays.length > 0">
        <div class="calendar-grid">
          <div class="calendar-weekdays">
            <div v-for="dayNameKey in weekDayKeys" :key="dayNameKey" class="weekday">{{ t(dayNameKey) }}</div>
          </div>
          <div class="calendar-days">
            <div v-for="(day, index) in calendarDays" :key="index" class="calendar-day" :class="{
              'other-month': !day.isCurrentMonth,
              'today': day.isToday,
              'has-chores': day.chores.length > 0
            }" tabindex="0" @keydown.enter="openCreateChoreModal(null, day.date)"
              @keydown.space="openCreateChoreModal(null, day.date)">
              <div class="day-header">
                <span class="day-number">{{ day.date.getDate() }}</span>
                <button v-if="!day.isOtherMonth" class="add-chore-indicator"
                  @click.stop="openCreateChoreModal(null, day.date)" :aria-label="t('choresPage.calendar.addChoreToDayLabel')">
                  <span class="material-icons">add_circle_outline</span>
                </button>
              </div>
              <div class="day-chores">
                <div v-for="chore in day.chores" :key="chore.id" class="calendar-chore-item"
                  :class="{ 'is-completed': chore.is_completed }" @click="openEditChoreModal(chore)" tabindex="0"
                  @keydown.enter="openEditChoreModal(chore)" @keydown.space="openEditChoreModal(chore)">
                  <div class="chore-status" :class="getStatusClass(chore)"></div>
                  <span class="chore-name">{{ chore.name }}</span>
                </div>
                <div v-if="day.chores.length === 0 && day.isCurrentMonth" class="no-chores-in-day">
                  <!-- Optionally, a subtle indicator for no chores -->
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div v-else class="empty-state">
        <span class="material-icons empty-icon">calendar_today</span>
        <p>{{ t('choresPage.calendar.emptyState') }}</p>
      </div>
    </div>

    <!-- List View -->
    <div v-else class="chores-list-container">
      <transition-group name="chore-list" tag="div" class="chores-grid">
        <div v-for="chore in filteredChores" :key="chore.id" class="chore-card"
          :class="{ 'is-overdue': !chore.is_completed && isOverdue(chore), 'is-completed': chore.is_completed }">
          <div class="chore-status" :class="getStatusClass(chore)"></div>
          <div class="chore-content">
            <div class="chore-main-info">
              <div class="chore-header">
                <h3>{{ chore.name }}</h3>
                <div class="chore-tags">
                  <span class="chore-type-tag" :class="chore.type">
                    {{ chore.type === 'personal' ? t('choresPage.listView.choreTypePersonal') : getGroupName(chore.group_id) || t('choresPage.listView.choreTypeGroupFallback') }}
                  </span>
                  <span v-if="!chore.is_completed" class="chore-frequency-tag" :class="chore.frequency">
                    {{ formatFrequency(chore.frequency) }}
                  </span>
                </div>
              </div>
              <div class="chore-meta">
                <div v-if="!chore.is_completed" class="chore-due-date" :class="getDueDateClass(chore)">
                  <span class="material-icons">schedule</span>
                  {{ formatDueDate(chore.next_due_date) }}
                </div>
                <div v-else class="chore-completed-date">
                  <span class="material-icons">check_circle_outline</span>
                  {{ t('choresPage.listView.completedDatePrefix') }} {{ formatDate(chore.completed_at || chore.next_due_date) }}
                </div>
                <div v-if="chore.description" class="chore-description">
                  {{ chore.description }}
                </div>
              </div>
            </div>
            <div class="chore-card-actions">
              <button v-if="!chore.is_completed" class="btn btn-success btn-sm btn-complete"
                @click="toggleChoreCompletion(chore)" :title="t('choresPage.listView.actions.doneTitle')">
                <span class="material-icons">check_circle</span> {{ t('choresPage.listView.actions.doneText') }}
              </button>
              <button v-else class="btn btn-warning btn-sm btn-undo" @click="toggleChoreCompletion(chore)"
                :title="t('choresPage.listView.actions.undoTitle')">
                <span class="material-icons">undo</span> {{ t('choresPage.listView.actions.undoText') }}
              </button>
              <button class="btn btn-icon" @click="openEditChoreModal(chore)" :title="t('choresPage.listView.actions.editTitle')" :aria-label="t('choresPage.listView.actions.editLabel')">
                <span class="material-icons">edit</span>
                <span class="btn-text hide-text-on-mobile">{{ t('choresPage.listView.actions.editText') }}</span>
              </button>
              <button class="btn btn-icon btn-danger-icon" @click="confirmDeleteChore(chore)" :title="t('choresPage.listView.actions.deleteTitle')"
                :aria-label="t('choresPage.listView.actions.deleteLabel')">
                <span class="material-icons">delete</span>
                <span class="btn-text hide-text-on-mobile">{{ t('choresPage.listView.actions.deleteText') }}</span>
              </button>
            </div>
          </div>
        </div>
      </transition-group>
      <div v-if="!isLoading && filteredChores.length === 0" class="empty-state">
        <span class="material-icons empty-icon"> Rtask_alt</span>
        <p>{{ t('choresPage.listView.emptyState.message') }}</p>
        <button v-if="activeView !== 'all'" class="btn btn-sm btn-outline" @click="activeView = 'all'">{{ t('choresPage.listView.emptyState.viewAllButton') }}</button>
      </div>
    </div>

    <!-- Create/Edit Chore Modal -->
    <div v-if="showChoreModal" class="modal-backdrop open" @click.self="showChoreModal = false" role="dialog"
      aria-modal="true" :aria-labelledby="isEditing ? 'editChoreModalTitle' : 'newChoreModalTitle'">
      <div class="modal-container">
        <div class="modal-header">
          <h3 :id="isEditing ? 'editChoreModalTitle' : 'newChoreModalTitle'">{{ isEditing ? t('choresPage.choreModal.editTitle') : t('choresPage.choreModal.newTitle')
          }}</h3>
          <button class="btn btn-icon" @click="showChoreModal = false" :aria-label="t('choresPage.choreModal.closeButtonLabel')">
            <span class="material-icons">close</span>
          </button>
        </div>
        <form @submit.prevent="onSubmit" class="modal-form">
          <div class="form-group">
            <label for="name">{{ t('choresPage.choreModal.nameLabel') }}</label>
            <input id="name" v-model="choreForm.name" type="text" class="form-input" :placeholder="t('choresPage.choreModal.namePlaceholder')"
              required />
          </div>

          <div class="form-group">
            <label>{{ t('choresPage.choreModal.typeLabel') }}</label>
            <div class="type-selector">
              <button type="button" class="type-btn" :class="{ active: choreForm.type === 'personal' }"
                @click="choreForm.type = 'personal'; choreForm.group_id = undefined"
                :aria-pressed="choreForm.type === 'personal' ? 'true' : 'false'">
                <span class="material-icons">person</span>
                {{ t('choresPage.choreModal.typePersonal') }}
              </button>
              <button type="button" class="type-btn" :class="{ active: choreForm.type === 'group' }"
                @click="choreForm.type = 'group'" :aria-pressed="choreForm.type === 'group' ? 'true' : 'false'">
                <span class="material-icons">group</span>
                {{ t('choresPage.choreModal.typeGroup') }}
              </button>
            </div>
          </div>

          <div v-if="choreForm.type === 'group'" class="form-group">
            <label for="group">{{ t('choresPage.choreModal.groupLabel') }}</label>
            <select id="group" v-model="choreForm.group_id" class="form-input" required>
              <option :value="undefined" disabled>{{ t('choresPage.choreModal.groupSelectDefault') }}</option>
              <option v-for="group in groups" :key="group.id" :value="group.id">
                {{ group.name }}
              </option>
            </select>
          </div>

          <div class="form-group">
            <label for="description">{{ t('choresPage.choreModal.descriptionLabel') }}</label>
            <textarea id="description" v-model="choreForm.description" class="form-input" rows="3"
              :placeholder="t('choresPage.choreModal.descriptionPlaceholder')"></textarea>
          </div>

          <div class="form-row">
            <div class="form-group">
              <label for="frequency">{{ t('choresPage.choreModal.frequencyLabel') }}</label>
              <select id="frequency" v-model="choreForm.frequency" class="form-input" required>
                <option v-for="option in frequencyOptions" :key="option.value" :value="option.value">
                  {{ option.label }}
                </option>
              </select>
            </div>

            <div v-if="choreForm.frequency === 'custom'" class="form-group">
              <label for="interval">{{ t('choresPage.choreModal.intervalLabel') }}</label>
              <input id="interval" v-model.number="choreForm.custom_interval_days" type="number" class="form-input"
                min="1" :placeholder="t('choresPage.choreModal.intervalPlaceholder')" required />
            </div>
          </div>

          <div class="form-group">
            <label for="dueDate">{{ t('choresPage.choreModal.dueDateLabel') }}</label>
            <div class="quick-due-dates">
              <button type="button" class="btn btn-sm btn-outline" @click="setQuickDueDate('today')">{{ t('choresPage.choreModal.quickDueDateToday') }}</button>
              <button type="button" class="btn btn-sm btn-outline"
                @click="setQuickDueDate('tomorrow')">{{ t('choresPage.choreModal.quickDueDateTomorrow') }}</button>
              <button type="button" class="btn btn-sm btn-outline" @click="setQuickDueDate('next_week')">{{ t('choresPage.choreModal.quickDueDateNextWeek') }}</button>
            </div>
            <input id="dueDate" v-model="choreForm.next_due_date" type="date" class="form-input" required />
          </div>

          <div class="modal-footer">
            <button type="button" class="btn btn-neutral" @click="showChoreModal = false">{{ t('choresPage.choreModal.cancelButton') }}</button>
            <button type="submit" class="btn btn-primary">{{ t('choresPage.choreModal.saveButton') }}</button>
          </div>
        </form>
      </div>
    </div>

    <!-- Delete Confirmation Dialog -->
    <div v-if="showDeleteDialog" class="modal-backdrop open" @click.self="showDeleteDialog = false" role="dialog"
      aria-modal="true" aria-labelledby="deleteDialogTitle">
      <div class="modal-container delete-confirm">
        <div class="modal-header">
          <h3 id="deleteDialogTitle">{{ t('choresPage.deleteDialog.title') }}</h3>
          <button class="btn btn-icon" @click="showDeleteDialog = false" :aria-label="t('choresPage.choreModal.closeButtonLabel')">
            <span class="material-icons">close</span>
          </button>
        </div>
        <div class="modal-body">
          <p>{{ t('choresPage.deleteDialog.confirmationText') }}</p>
        </div>
        <div class="modal-footer">
          <button class="btn btn-neutral" @click="showDeleteDialog = false">{{ t('choresPage.choreModal.cancelButton') }}</button>
          <button class="btn btn-danger" @click="deleteChore">{{ t('choresPage.deleteDialog.deleteButton') }}</button>
        </div>
      </div>
    </div>

    <!-- Keyboard Shortcuts Modal -->
    <div v-if="showShortcutsModal" class="modal-backdrop open" @click.self="showShortcutsModal = false" role="dialog"
      aria-modal="true" aria-labelledby="shortcutsModalTitle">
      <div class="modal-container shortcuts-modal">
        <div class="modal-header">
          <h3 id="shortcutsModalTitle">{{ t('choresPage.shortcutsModal.title') }}</h3>
          <button class="btn btn-icon" @click="showShortcutsModal = false" :aria-label="t('choresPage.choreModal.closeButtonLabel')">
            <span class="material-icons">close</span>
          </button>
        </div>
        <div class="modal-body">
          <div class="shortcuts-list">
            <div class="shortcut-item">
              <div class="shortcut-keys">
                <kbd>Ctrl/Cmd</kbd> + <kbd>N</kbd>
              </div>
              <div class="shortcut-description">{{ t('choresPage.shortcutsModal.descNewChore') }}</div>
            </div>
            <div class="shortcut-item">
              <div class="shortcut-keys">
                <kbd>Ctrl/Cmd</kbd> + <kbd>/</kbd>
              </div>
              <div class="shortcut-description">{{ t('choresPage.shortcutsModal.descToggleView') }}</div>
            </div>
            <div class="shortcut-item">
              <div class="shortcut-keys">
                <kbd>Ctrl/Cmd</kbd> + <kbd>?</kbd>
              </div>
              <div class="shortcut-description">{{ t('choresPage.shortcutsModal.descToggleShortcuts') }}</div>
            </div>
            <div class="shortcut-item">
              <div class="shortcut-keys">
                <kbd>Esc</kbd>
              </div>
              <div class="shortcut-description">{{ t('choresPage.shortcutsModal.descCloseModal') }}</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </main>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, onUnmounted, watch, onBeforeUnmount } from 'vue'
import { useI18n } from 'vue-i18n'
import { format, startOfDay, addDays, addWeeks, isBefore, isEqual, startOfMonth, endOfMonth, eachDayOfInterval, isSameMonth, isToday as isTodayDate } from 'date-fns'
import { choreService } from '../services/choreService'
import { useNotificationStore } from '../stores/notifications'
import type { Chore, ChoreCreate, ChoreUpdate, ChoreFrequency } from '../types/chore'
import { useRoute } from 'vue-router'
import { groupService } from '../services/groupService'
import { useStorage } from '@vueuse/core'

const { t } = useI18n()

// Types
interface ChoreWithCompletion extends Chore {
  is_completed: boolean;
  completed_at: string | null;
}

interface ChoreCreateWithCompletion extends Omit<ChoreCreate, 'created_by_id' | 'created_at' | 'updated_at'> {
  is_completed: boolean;
  completed_at: string | null;
}

const notificationStore = useNotificationStore()
const route = useRoute()

// State
const chores = ref<ChoreWithCompletion[]>([])
const groups = ref<{ id: number, name: string }[]>([])
const showChoreModal = ref(false)
const showDeleteDialog = ref(false)
const isEditing = ref(false)
const selectedChore = ref<ChoreWithCompletion | null>(null)
const showShortcutsModal = ref(false)

const cachedChores = useStorage<ChoreWithCompletion[]>('cached-chores-v2', [])
const cachedTimestamp = useStorage<number>('cached-chores-timestamp-v2', 0)
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes

const loadCachedData = () => {
  const now = Date.now();
  if (cachedChores.value && cachedChores.value.length > 0 && (now - cachedTimestamp.value) < CACHE_DURATION) {
    chores.value = cachedChores.value;
  }
};

const choreForm = ref<ChoreCreateWithCompletion>({
  name: '',
  description: '',
  frequency: 'daily',
  custom_interval_days: undefined,
  next_due_date: format(new Date(), 'yyyy-MM-dd'),
  type: 'personal',
  group_id: undefined,
  is_completed: false,
  completed_at: null,
})

const getGroupName = (groupId?: number | null): string | undefined => {
  if (!groupId) return undefined;
  return groups.value.find(g => g.id === groupId)?.name;
};

const frequencyOptions = computed(() => [
  { label: t('choresPage.frequencyOptions.oneTime'), value: 'one_time' as ChoreFrequency },
  { label: t('choresPage.frequencyOptions.daily'), value: 'daily' as ChoreFrequency },
  { label: t('choresPage.frequencyOptions.weekly'), value: 'weekly' as ChoreFrequency },
  { label: t('choresPage.frequencyOptions.monthly'), value: 'monthly' as ChoreFrequency },
  { label: t('choresPage.frequencyOptions.custom'), value: 'custom' as ChoreFrequency }
]);

const isLoading = ref(true)

const loadChores = async () => {
  isLoading.value = true
  try {
    const fetchedChores = await choreService.getAllChores()
    chores.value = fetchedChores.map(c => ({
      ...c,
      is_completed: c.is_completed || false,
      completed_at: c.completed_at || null,
    }))
    cachedChores.value = chores.value
    cachedTimestamp.value = Date.now()
  } catch (error) {
    console.error('Failed to load all chores:', error)
    notificationStore.addNotification({ message: t('choresPage.notifications.loadFailed'), type: 'error' })
    if (!cachedChores.value || cachedChores.value.length === 0) chores.value = []
  } finally {
    isLoading.value = false
  }
}

const viewMode = ref<'calendar' | 'list'>('calendar')
const currentDate = ref(new Date())

const weekDayKeys = ['choresPage.calendar.weekdays.sun', 'choresPage.calendar.weekdays.mon', 'choresPage.calendar.weekdays.tue', 'choresPage.calendar.weekdays.wed', 'choresPage.calendar.weekdays.thu', 'choresPage.calendar.weekdays.fri', 'choresPage.calendar.weekdays.sat']
// For smaller screens, you might use: const weekDayKeys = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];


const currentMonthYear = computed(() => {
  return format(currentDate.value, 'MMMM yyyy')
})

const calendarDays = computed(() => {
  if (isLoading.value) return []; // Don't compute if chores are not loaded
  const start = startOfMonth(currentDate.value)
  const end = endOfMonth(currentDate.value)

  const firstDayOfMonth = start.getDay()
  const startDate = addDays(start, -firstDayOfMonth)

  const lastDayOfMonth = end.getDay()
  const endDate = addDays(end, 6 - lastDayOfMonth)

  const days = eachDayOfInterval({ start: startDate, end: endDate })

  return days.map(date => {
    const dayChores = chores.value.filter(chore => {
      if (chore.is_completed && activeView.value !== 'completed') return false; // Don't show completed in calendar unless completed view is active (edge case)
      if (!chore.next_due_date) return false;
      try {
        const choreDate = startOfDay(new Date(chore.next_due_date.replace(/-/g, '/'))); // More robust date parsing
        return isEqual(choreDate, startOfDay(date))
      } catch (e) {
        console.warn("Invalid date for chore:", chore.name, chore.next_due_date);
        return false;
      }
    })

    return {
      date,
      isCurrentMonth: isSameMonth(date, currentDate.value),
      isToday: isTodayDate(date),
      isOtherMonth: !isSameMonth(date, currentDate.value),
      chores: dayChores
    }
  })
})

const previousMonth = () => {
  currentDate.value = addDays(startOfMonth(currentDate.value), -1)
}

const nextMonth = () => {
  currentDate.value = addDays(endOfMonth(currentDate.value), 1)
}

const openCreateChoreModal = (groupId: number | null, date?: Date) => {
  isEditing.value = false
  selectedChore.value = null
  choreForm.value = {
    name: '',
    description: '',
    frequency: 'daily',
    custom_interval_days: undefined,
    next_due_date: date ? format(startOfDay(date), 'yyyy-MM-dd') : format(new Date(), 'yyyy-MM-dd'),
    type: groupId ? 'group' : 'personal',
    group_id: groupId ?? undefined,
    is_completed: false,
    completed_at: null,
  }
  showChoreModal.value = true
}

const openEditChoreModal = (chore: ChoreWithCompletion) => {
  isEditing.value = true
  selectedChore.value = chore
  choreForm.value = {
    name: chore.name,
    description: chore.description || '',
    frequency: chore.frequency,
    custom_interval_days: chore.custom_interval_days,
    next_due_date: chore.next_due_date ? format(new Date(chore.next_due_date.replace(/-/g, '/')), 'yyyy-MM-dd') : format(new Date(), 'yyyy-MM-dd'),
    type: chore.type,
    group_id: chore.group_id,
    is_completed: chore.is_completed,
    completed_at: chore.completed_at,
  }
  showChoreModal.value = true
}

const onSubmit = async () => {
  if (!validateForm()) return

  isLoading.value = true;
  try {
    const choreDataSubmit: Partial<ChoreCreateWithCompletion> = { ...choreForm.value }

    if (choreDataSubmit.frequency !== 'custom') {
      choreDataSubmit.custom_interval_days = undefined
    }
    if (choreDataSubmit.next_due_date) {
      choreDataSubmit.next_due_date = format(new Date(choreDataSubmit.next_due_date.replace(/-/g, '/')), 'yyyy-MM-dd');
    }

    let notificationMessage = ''

    if (isEditing.value && selectedChore.value) {
      await choreService.updateChore(selectedChore.value.id, choreDataSubmit as ChoreUpdate)
      notificationMessage = t('choresPage.notifications.updateSuccess', { name: choreForm.value.name })
    } else {
      await choreService.createChore(choreDataSubmit as ChoreCreate)
      notificationMessage = t('choresPage.notifications.createSuccess', { name: choreForm.value.name })
    }

    notificationStore.addNotification({ message: notificationMessage, type: 'success' })
    showChoreModal.value = false
    hasUnsavedChanges.value = false;
    await loadChores()
  } catch (error) {
    console.error('Failed to save chore:', error)
    notificationStore.addNotification({ message: t(isEditing.value ? 'choresPage.notifications.updateFailed' : 'choresPage.notifications.createFailed'), type: 'error' })
  } finally {
    isLoading.value = false;
  }
}

const confirmDeleteChore = (chore: ChoreWithCompletion) => {
  selectedChore.value = chore
  showDeleteDialog.value = true
}

const deleteChore = async () => {
  if (!selectedChore.value) return;
  isLoading.value = true;
  try {
    await choreService.deleteChore(
      selectedChore.value.id,
      selectedChore.value.type,
      selectedChore.value.group_id ?? undefined
    );
    showDeleteDialog.value = false;
    notificationStore.addNotification({ message: t('choresPage.notifications.deleteSuccess', { name: selectedChore.value.name }), type: 'success' })
    await loadChores()
  } catch (error) {
    console.error('Failed to delete chore:', error);
    notificationStore.addNotification({ message: t('choresPage.notifications.deleteFailed'), type: 'error' })
  } finally {
    isLoading.value = false;
    selectedChore.value = null;
  }
}

const formatDate = (dateString: string | null): string => {
  if (!dateString) return 'N/A';
  try {
    return format(new Date(dateString.replace(/-/g, '/')), 'MMM d, yyyy');
  } catch (e) {
    return 'Invalid Date';
  }
}

const formatFrequency = (frequency?: ChoreFrequency) => {
  if (!frequency) return '';
  const option = frequencyOptions.find(opt => opt.value === frequency)
  return option ? option.label : frequency.charAt(0).toUpperCase() + frequency.slice(1);
}

const loadGroups = async () => {
  try {
    groups.value = await groupService.getUserGroups();
  } catch (error) {
    console.error('Failed to load groups:', error);
    // notificationStore.addNotification({ message: 'Failed to load groups', type: 'error' }); // Optional: can be noisy
  }
};

const activeView = ref('today')
const today = computed(() => startOfDay(new Date()));

const isOverdue = (chore: ChoreWithCompletion) => {
  if (chore.is_completed || !chore.next_due_date) return false;
  try {
    const dueDate = startOfDay(new Date(chore.next_due_date.replace(/-/g, '/')));
    return isBefore(dueDate, today.value);
  } catch { return false; }
};

const filteredChores = computed(() => {
  let result: ChoreWithCompletion[];
  const pendingChores = chores.value
    .filter(c => !c.is_completed)
    .sort((a, b) => {
      try { return new Date(a.next_due_date.replace(/-/g, '/')).getTime() - new Date(b.next_due_date.replace(/-/g, '/')).getTime(); }
      catch { return 0; }
    });
  const completedChoresList = chores.value
    .filter(c => c.is_completed)
    .sort((a, b) => {
      try { return new Date(b.completed_at || 0).getTime() - new Date(a.completed_at || 0).getTime(); }
      catch { return 0; }
    });


  switch (activeView.value) {
    case 'overdue':
      result = pendingChores.filter(chore => isOverdue(chore));
      break;
    case 'today':
      result = pendingChores.filter(chore => {
        if (!chore.next_due_date) return false;
        try {
          const dueDate = startOfDay(new Date(chore.next_due_date.replace(/-/g, '/')));
          return isEqual(dueDate, today.value);
        } catch { return false; }
      });
      break;
    case 'upcoming':
      result = pendingChores.filter(chore => {
        if (!chore.next_due_date) return false;
        try {
          const dueDate = startOfDay(new Date(chore.next_due_date.replace(/-/g, '/')));
          return isBefore(today.value, dueDate);
        } catch { return false; }
      });
      break;
    case 'completed':
      result = completedChoresList;
      break;
    default: // 'all' (all pending)
      result = pendingChores;
  }
  return result;
});

const counts = computed(() => {
  const pending = chores.value.filter(c => !c.is_completed);
  return {
    overdue: pending.filter(chore => isOverdue(chore)).length,
    today: pending.filter(chore => {
      if (!chore.next_due_date) return false;
      try {
        const dueDate = startOfDay(new Date(chore.next_due_date.replace(/-/g, '/')));
        return isEqual(dueDate, today.value);
      } catch { return false; }
    }).length,
  };
});

const getStatusClass = (chore: ChoreWithCompletion) => {
  if (chore.is_completed) return 'completed';
  if (isOverdue(chore)) return 'overdue';
  if (!chore.next_due_date) return 'upcoming'; // Default if no due date
  try {
    const dueDate = startOfDay(new Date(chore.next_due_date.replace(/-/g, '/')));
    if (isEqual(dueDate, today.value)) return 'today';
  } catch { /* fall through */ }
  return 'upcoming';
}

const getDueDateClass = (chore: ChoreWithCompletion) => {
  if (chore.is_completed) return '';
  if (isOverdue(chore)) return 'overdue-text'; // Use a different class for text color if needed
  if (!chore.next_due_date) return '';
  try {
    const dueDate = startOfDay(new Date(chore.next_due_date.replace(/-/g, '/')));
    if (isEqual(dueDate, today.value)) return 'today-text';
  } catch { /* fall through */ }
  return 'upcoming-text';
}

const formatDueDate = (dateString: string | null) => {
  if (!dateString) return t('choresPage.formatters.noDueDate');
  try {
    const dueDate = startOfDay(new Date(dateString.replace(/-/g, '/')));
    if (isEqual(dueDate, today.value)) return t('choresPage.formatters.dueToday');

    const tomorrow = addDays(today.value, 1);
    if (isEqual(dueDate, tomorrow)) return t('choresPage.formatters.dueTomorrow');

    if (isBefore(dueDate, today.value)) return t('choresPage.formatters.overdueFull', { date: formatDate(dateString) });

    return t('choresPage.formatters.dueFull', { date: formatDate(dateString) });
  } catch {
    return t('choresPage.formatters.invalidDate')
  }
}

const toggleChoreCompletion = async (choreToToggle: ChoreWithCompletion) => {
  const originalStatus = choreToToggle.is_completed;
  const originalCompletedAt = choreToToggle.completed_at;

  choreToToggle.is_completed = !choreToToggle.is_completed;
  choreToToggle.completed_at = choreToToggle.is_completed ? new Date().toISOString() : null;

  // Optimistic update locally
  const index = chores.value.findIndex(c => c.id === choreToToggle.id);
  if (index !== -1) {
    chores.value.splice(index, 1, { ...choreToToggle });
  }
  cachedChores.value = [...chores.value];

  try {
    await choreService.updateChore(choreToToggle.id, {
      is_completed: choreToToggle.is_completed,
      completed_at: choreToToggle.completed_at,
    } as ChoreUpdate);

    notificationStore.addNotification({
      message: t(choreToToggle.is_completed ? 'choresPage.notifications.markedDone' : 'choresPage.notifications.markedNotDone', { name: choreToToggle.name }),
      type: choreToToggle.is_completed ? 'success' : 'info'
    });
  } catch (error) {
    console.error("Failed to update chore completion status:", error);
    // Revert optimistic update on error
    choreToToggle.is_completed = originalStatus;
    choreToToggle.completed_at = originalCompletedAt;
    if (index !== -1) chores.value.splice(index, 1, { ...choreToToggle });
    cachedChores.value = [...chores.value];

    notificationStore.addNotification({ message: t('choresPage.notifications.statusUpdateFailed'), type: 'error' });
  }
};


const setQuickDueDate = (when: 'today' | 'tomorrow' | 'next_week') => {
  let date = startOfDay(new Date());
  if (when === 'tomorrow') date = addDays(date, 1);
  if (when === 'next_week') date = addWeeks(date, 1);
  choreForm.value.next_due_date = format(date, 'yyyy-MM-dd');
};

const handleKeyPress = (event: KeyboardEvent) => {
  const target = event.target as HTMLElement;
  if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.tagName === 'SELECT') {
    return;
  }

  if ((event.ctrlKey || event.metaKey) && event.key === 'n') {
    event.preventDefault();
    if (!showChoreModal.value) openCreateChoreModal(null);
  }
  if ((event.ctrlKey || event.metaKey) && event.key === '/') {
    event.preventDefault();
    viewMode.value = viewMode.value === 'calendar' ? 'list' : 'calendar';
  }
  if ((event.ctrlKey || event.metaKey) && (event.key === '?' || event.key === '-')) { // Often ? is Shift + /
    event.preventDefault();
    showShortcutsModal.value = !showShortcutsModal.value;
  }
  if (event.key === 'Escape') {
    if (showChoreModal.value) showChoreModal.value = false;
    else if (showDeleteDialog.value) showDeleteDialog.value = false;
    else if (showShortcutsModal.value) showShortcutsModal.value = false;
  }
};

onMounted(() => {
  window.addEventListener('keydown', handleKeyPress)
  loadCachedData() // Load from cache first for perceived speed
  Promise.all([loadChores(), loadGroups()]); // Then fetch fresh data
})

onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyPress)
})

const validateForm = () => {
  if (!choreForm.value.name.trim()) {
    notificationStore.addNotification({ message: t('choresPage.validation.nameRequired'), type: 'error' }); return false;
  }
  if (choreForm.value.type === 'group' && !choreForm.value.group_id) {
    notificationStore.addNotification({ message: t('choresPage.validation.groupRequired'), type: 'error' }); return false;
  }
  if (choreForm.value.frequency === 'custom' && (!choreForm.value.custom_interval_days || choreForm.value.custom_interval_days < 1)) {
    notificationStore.addNotification({ message: t('choresPage.validation.intervalRequired'), type: 'error' }); return false;
  }
  if (!choreForm.value.next_due_date) {
    notificationStore.addNotification({ message: t('choresPage.validation.dueDateRequired'), type: 'error' }); return false;
  }
  try {
    new Date(choreForm.value.next_due_date.replace(/-/g, '/')); // check if valid date
  } catch {
    notificationStore.addNotification({ message: t('choresPage.validation.invalidDueDate'), type: 'error' }); return false;
  }
  return true;
}

// Auto-save functionality (commented out as the previous implementation was risky)
// A more robust auto-save would save to localStorage/drafts, not directly submit.
/*
let autoSaveTimeout: number | null = null
const autoSaveForm = () => {
  if (autoSaveTimeout) {
    clearTimeout(autoSaveTimeout)
  }
  autoSaveTimeout = window.setTimeout(() => {
    // This logic should be revised. Auto-submitting a form is usually not desired.
    // Consider saving to a local draft instead.
    // if (isEditing.value && selectedChore.value) {
    //   console.log("Attempting auto-save (currently disabled logic)");
    //   // onSubmit() // This is risky; onSubmit usually makes an API call
    // }
  }, 3000) // Auto-save after 3 seconds of inactivity
}

watch(choreForm, () => {
  if (isEditing.value) {
    hasUnsavedChanges.value = true; // Mark changes for onBeforeUnload prompt
    // autoSaveForm() // Trigger auto-save logic if re-enabled
  }
}, { deep: true })
*/

const hasUnsavedChanges = ref(false)

watch(choreForm, (newValue, oldValue) => {
  // Set hasUnsavedChanges only if the modal is open and it's not the initial population
  if (showChoreModal.value && oldValue.name !== '') { // Basic check to avoid triggering on modal open
    hasUnsavedChanges.value = true;
  }
}, { deep: true });

watch(showChoreModal, (isOpen) => {
  if (!isOpen) {
    hasUnsavedChanges.value = false; // Reset when modal is closed
  } else {
    // When modal opens for a new chore, or for editing,
    // we don't consider it "unsaved" until the user makes a change.
    // The watch on choreForm handles detecting actual changes.
    // Resetting here might be too early if form is pre-filled.
  }
});


onBeforeUnmount(() => {
  if (hasUnsavedChanges.value && showChoreModal.value) { // Only prompt if modal is open with changes
    const confirmLeave = window.confirm(t('choresPage.unsavedChangesConfirmation'))
    if (!confirmLeave) {
      return false // This typically doesn't prevent component unmount in Vue 3 composition API directly
      // but is a common pattern. For SPA, router guards are better.
    }
  }
})

</script>

<style>
/* Modal styles - (global, as before) */
.modal-backdrop {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  /* Slightly darker backdrop */
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 1rem;
  /* Add padding for small screens so modal doesn't touch edges */
}

.modal-container {
  background: white;
  border-radius: 12px;
  border: 3px solid #111;
  box-shadow: 6px 6px 0 #111;
  width: 100%;
  /* Let padding on backdrop control spacing */
  max-width: 600px;
  max-height: 90vh;
  overflow-y: auto;
  display: flex;
  /* Added for flex column layout */
  flex-direction: column;
  /* Added */
}

.modal-header {
  padding: 1rem 1.5rem;
  border-bottom: 2px solid #111;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
  /* Prevent shrinking */
}

.modal-header h3 {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 700;
}

.modal-body {
  padding: 1.5rem;
  overflow-y: auto;
  /* Allow body to scroll if content overflows */
  flex-grow: 1;
  /* Allow body to take available space */
}

.modal-footer {
  padding: 1rem 1.5rem;
  border-top: 2px solid #111;
  display: flex;
  justify-content: flex-end;
  gap: 1rem;
  flex-shrink: 0;
  /* Prevent shrinking */
}

/* Form styles (global, as before) */
.modal-form {
  /* padding: 1.5rem; No longer needed if modal-body has padding */
}

.form-group {
  margin-bottom: 1.5rem;
}

.form-row {
  display: flex;
  flex-wrap: wrap;
  /* Allow wrapping on small screens */
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.form-row .form-group {
  flex: 1 1 200px;
  /* Allow items to grow and shrink, base size 200px */
  margin-bottom: 0;
}

.form-group label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: 600;
  color: #333;
}

.form-input {
  width: 100%;
  padding: 0.75rem;
  border: 2px solid #111;
  border-radius: 8px;
  font-size: 1rem;
  transition: all 0.2s ease;
  background: white;
  box-sizing: border-box;
  /* Ensure padding and border are inside width */
}

.form-input:focus {
  outline: none;
  border-color: #007bff;
  box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.2);
  /* Softer focus */
}

.form-input::placeholder {
  color: #999;
}

/* Type selector styles */
.type-selector {
  display: flex;
  gap: 1rem;
  margin-bottom: 1rem;
  /* Was form-group, consistent */
}

.type-btn {
  flex: 1;
  padding: 0.75rem;
  border: 2px solid #111;
  border-radius: 8px;
  background: white;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  transition: all 0.2s ease;
  min-width: 120px;
  /* Ensure buttons don't get too small */
}

.type-btn:hover {
  background: #f8f9fa;
}

.type-btn.active {
  background: #111;
  color: white;
}

/* Quick due dates styles */
.quick-due-dates {
  display: flex;
  flex-wrap: wrap;
  /* Allow wrapping */
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  /* Increased margin */
}

.btn-outline {
  padding: 0.5rem 1rem;
  border: 2px solid #111;
  border-radius: 6px;
  background: white;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 0.9rem;
  /* Slightly smaller for tertiary actions */
}

.btn-outline:hover {
  background: #f8f9fa;
}

/* Button styles (global, as before) */
.btn {
  padding: 0.75rem 1.5rem;
  border-radius: 8px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border: 2px solid transparent;
  /* Base border */
}

.btn-primary {
  background: #111;
  color: white;
  border-color: #111;
}

.btn-primary:hover {
  background: #333;
  border-color: #333;
}

.btn-neutral {
  background: white;
  color: #333;
  border-color: #111;
}

.btn-neutral:hover {
  background: #f8f9fa;
}

.btn-icon {
  padding: 0.5rem;
  border: none;
  background: transparent;
  color: #666;
  cursor: pointer;
  border-radius: 50%;
  /* Make icon buttons round for better touch target */
  transition: all 0.2s ease;
  line-height: 1;
  /* Ensure icon is centered */
}

.btn-icon .material-icons {
  font-size: 1.5rem;
  /* Slightly larger icons */
}

.btn-icon:hover {
  color: #333;
  background-color: rgba(0, 0, 0, 0.05);
  /* Subtle hover background */
}

.btn-danger {
  background-color: #dc3545;
  color: white;
  border-color: #dc3545;
}

.btn-danger:hover {
  background-color: #c82333;
  border-color: #bd2130;
}

.btn-danger-icon {
  /* For icon buttons that are dangerous */
  color: #dc3545;
}

.btn-danger-icon:hover {
  color: #c82333;
  background-color: rgba(220, 53, 69, 0.1);
}


/* Dark mode support for modals and forms (as before, with minor tweaks if needed) */
@media (prefers-color-scheme: dark) {
  .modal-container {
    background: #1e1e1e;
    /* Slightly different dark */
    border-color: #f0f0f0;
    /* Lighter border for dark */
    box-shadow: 6px 6px 0 #f0f0f0;
  }

  .modal-header,
  .modal-footer {
    border-color: #444;
    /* Darker separator */
  }

  .modal-header h3 {
    color: #f0f0f0;
  }

  .form-group label {
    color: #ccc;
    /* Lighter label */
  }

  .form-input {
    background: #2a2a2a;
    border-color: #555;
    /* Mid-tone border */
    color: #f0f0f0;
  }

  .form-input:focus {
    border-color: #0095ff;
    /* Brighter focus for dark */
    box-shadow: 0 0 0 3px rgba(0, 149, 255, 0.25);
  }

  .form-input::placeholder {
    color: #777;
  }

  .type-btn {
    background: #2a2a2a;
    border-color: #555;
    color: #ccc;
  }

  .type-btn:hover {
    background: #333;
  }

  .type-btn.active {
    background: #f0f0f0;
    color: #111;
    border-color: #f0f0f0;
  }

  .btn-outline {
    background: #2a2a2a;
    border-color: #555;
    color: #ccc;
  }

  .btn-outline:hover {
    background: #333;
  }

  .btn-neutral {
    background: #2a2a2a;
    color: #ccc;
    border-color: #555;
  }

  .btn-neutral:hover {
    background: #333;
  }

  .btn-primary {
    /* Ensure primary button is distinct in dark mode */
    background: #007bff;
    color: white;
    border-color: #007bff;
  }

  .btn-primary:hover {
    background: #0056b3;
    border-color: #0056b3;
  }

  .btn-icon {
    color: #999;
  }

  .btn-icon:hover {
    color: #f0f0f0;
    background-color: rgba(255, 255, 255, 0.08);
  }

  .btn-danger {
    background-color: #d9534f;
    border-color: #d9534f;
  }

  .btn-danger:hover {
    background-color: #c9302c;
    border-color: #c9302c;
  }

  .btn-danger-icon {
    color: #d9534f;
  }

  .btn-danger-icon:hover {
    color: #c9302c;
    background-color: rgba(217, 83, 79, 0.1);
  }
}
</style>

<style scoped>
/* Utility classes */
.hide-text-on-mobile {
  display: inline;
}

.hide-text-on-mobile-sm {
  display: inline;
}

@media (max-width: 480px) {

  /* Stricter breakpoint for hiding text */
  .hide-text-on-mobile {
    display: none;
  }
}

@media (max-width: 380px) {

  /* Even Stricter breakpoint for New Chore */
  .hide-text-on-mobile-sm {
    display: none;
  }
}


/* Base container styles (as before) */
.neo-container {
  padding: 1rem;
  max-width: 1200px;
  margin: 0 auto;
}

.page-padding {
  /* This class seems redundant if neo-container is always used */
  /* padding: 1rem; max-width: 1200px; margin: 0 auto; */
}

/* Header styles */
.neo-list-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  /* Align items to the start of the cross axis */
  flex-wrap: wrap;
  /* Allow wrapping for very narrow screens if necessary */
  gap: 1.5rem;
  /* Adjusted gap */
  margin-bottom: 2rem;
  padding: 1.5rem;
  background: white;
  border-radius: 18px;
  border: 3px solid #111;
  box-shadow: 6px 6px 0 #111;
}

.header-left {
  flex: 1;
  min-width: 280px;
  /* Ensure it has some minimum width before wrapping */
}

.header-right {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-shrink: 0;
}

.neo-title {
  font-size: 2.5rem;
  font-weight: 900;
  margin: 0 0 1rem 0;
  line-height: 1.2;
  color: #111;
}

/* Tab styles */
.view-tabs {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  /* Allow tabs to wrap if they don't fit */
  /* Removed overflow-x: auto; flex-wrap is usually preferred if space allows items to stack */
  /* If horizontal scrolling is desired over wrapping:
  overflow-x: auto;
  white-space: nowrap;
  padding-bottom: 8px; // for scrollbar visibility
  flex-wrap: nowrap;
  */
  margin-bottom: 0.5rem;
  /* if wrapped, needs some margin */
}

.neo-tab-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 1rem;
  border: 2px solid #111;
  background: #f5f5f5;
  color: #333;
  font-weight: 600;
  font-size: 0.9rem;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s ease;
  box-shadow: 2px 2px 0 #111;
}

.neo-tab-btn .material-icons {
  font-size: 1.1rem;
}

.neo-tab-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 3px 3px 0 #111;
}

.neo-tab-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.neo-tab-btn.active {
  background: #111;
  color: white;
  box-shadow: 3px 3px 0 #111;
  /* Ensure active shadow is consistent */
}

.neo-tab-count {
  background: rgba(255, 255, 255, 0.2);
  color: white;
  /* Assuming active tab has dark background */
  padding: 0.1em 0.5em;
  border-radius: 1rem;
  font-size: 0.8rem;
  font-weight: 600;
  min-width: 1.5rem;
  /* Ensure it's circular even for 1 digit */
  text-align: center;
  line-height: normal;
  /* Adjust if text is not centered vertically */
}

.neo-tab-btn:not(.active) .neo-tab-count {
  background: #e0e0e0;
  color: #333;
}

/* View toggle styles */
.neo-view-toggle {
  display: flex;
  gap: 0.25rem;
  /* Reduced gap for tighter packing */
  background: #f5f5f5;
  padding: 0.25rem;
  border-radius: 8px;
  border: 2px solid #111;
}

.neo-toggle-btn {
  border: none;
  background: transparent;
  color: #333;
  padding: 0.5rem 0.75rem;
  /* Adjusted padding */
  font-weight: 600;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.neo-toggle-btn .material-icons {
  font-size: 1.2rem;
}


.neo-toggle-btn:hover:not(.active):not(:disabled) {
  background: #e9ecef;
}

.neo-toggle-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.neo-toggle-btn.active {
  background: #111;
  color: white;
}

/* Action button styles */
.neo-action-button {
  background: #fff;
  border: 3px solid #111;
  border-radius: 8px;
  padding: 0.6rem 1rem;
  font-weight: 700;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  box-shadow: 3px 3px 0 #111;
  transition: transform 0.1s ease-in-out, box-shadow 0.1s ease-in-out;
}

.neo-action-button .material-icons {
  font-size: 1.2rem;
}


.neo-action-button:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 3px 5px 0 #111;
}

.neo-action-button:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: 2px 2px 0 #111;
}

.neo-action-button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
  box-shadow: 3px 3px 0 #111;
}

/* Loading state styles (as before) */
.neo-loading-state {
  text-align: center;
  padding: 3rem 1rem;
  margin: 2rem 0;
  border: 3px solid #111;
  border-radius: 18px;
  background: #fff;
  box-shadow: 6px 6px 0 #111;
}

.loading-spinner {
  /* Basic spinner */
  border: 4px solid #f3f3f3;
  border-top: 4px solid #111;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  animation: spin 1s linear infinite;
  margin: 0 auto 1rem;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

/* Empty State Styles */
.empty-state {
  text-align: center;
  padding: 2rem 1rem;
  margin: 2rem auto;
  /* Centered if inside a flex/grid container */
  border: 2px dashed #ccc;
  border-radius: 12px;
  background: #f9f9f9;
  color: #555;
  max-width: 500px;
}

.empty-state .empty-icon {
  font-size: 3rem;
  margin-bottom: 0.5rem;
  color: #aaa;
}

.empty-state p {
  font-size: 1.1rem;
  margin-bottom: 1rem;
}


/* Responsive styles for header */
@media (max-width: 768px) {
  .neo-list-header {
    flex-direction: column;
    gap: 1.5rem;
    /* Consistent gap */
    padding: 1rem;
  }

  .header-left {
    width: 100%;
    /* Take full width when stacked */
  }

  .header-right {
    width: 100%;
    justify-content: space-between;
    /* Spread items */
  }

  .neo-title {
    font-size: 2rem;
    /* Slightly smaller title on mobile */
  }

  .view-tabs {
    /* If choosing scroll over wrap for tabs: */
    /* overflow-x: auto; white-space: nowrap; padding-bottom: 8px; flex-wrap: nowrap; */
    /* -webkit-overflow-scrolling: touch; scrollbar-width: thin; */
  }

  /* .view-tabs::-webkit-scrollbar { display: block; height: 5px; } */
  /* .view-tabs::-webkit-scrollbar-thumb { background: #ccc; border-radius: 3px;} */


  .neo-tab-btn {
    font-size: 0.85rem;
    /* Slightly smaller tab text */
    padding: 0.5rem 0.75rem;
  }

  .neo-view-toggle {
    /* flex: 1; Ensure it can take space if New Chore btn shrinks more */
  }

  .neo-toggle-btn {
    padding: 0.5rem 0.6rem;
  }

  /* More compact toggle buttons */


  .neo-action-button {
    /* flex-grow: 1; /* Allows it to grow if space available */
    /* justify-content: center; /* Center content if text is hidden */
    padding: 0.6rem 0.8rem;
    /* More compact */
  }
}

/* Dark mode support (as before) */
@media (prefers-color-scheme: dark) {
  .neo-list-header {
    background: #1a1a1a;
    border-color: #fff;
    box-shadow: 6px 6px 0 #fff;
  }

  .neo-title {
    color: #fff;
  }

  .neo-tab-btn {
    background: #2a2a2a;
    border-color: #fff;
    color: #fff;
    box-shadow: 2px 2px 0 #fff;
  }

  .neo-tab-btn:hover:not(:disabled) {
    box-shadow: 3px 3px 0 #fff;
  }

  .neo-tab-btn.active {
    background: #fff;
    color: #111;
  }

  .neo-tab-btn:not(.active) .neo-tab-count {
    background: #333;
    color: #fff;
  }

  .neo-view-toggle {
    background: #2a2a2a;
    border-color: #fff;
  }

  .neo-toggle-btn {
    color: #fff;
  }

  .neo-toggle-btn:hover:not(.active):not(:disabled) {
    background: #333;
  }

  .neo-toggle-btn.active {
    background: #fff;
    color: #111;
  }

  .neo-action-button {
    background: #1a1a1a;
    border-color: #fff;
    color: #fff;
    box-shadow: 3px 3px 0 #fff;
  }

  .neo-action-button:hover:not(:disabled) {
    box-shadow: 3px 5px 0 #fff;
    background: #2c2c2c;
  }

  .empty-state {
    background: #222;
    border-color: #444;
    color: #aaa;
  }

  .empty-state .empty-icon {
    color: #555;
  }

  .loading-spinner {
    border-top-color: #fff;
  }
}

/* Calendar View Styles */
.calendar-view {
  background: white;
  border-radius: 18px;
  border: 3px solid #111;
  box-shadow: 6px 6px 0 #111;
  padding: 1.5rem;
  margin-bottom: 2rem;
}

.calendar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.5rem;
}

.calendar-header h2 {
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0;
  text-align: center;
  flex-grow: 1;
}

.calendar-header .btn-icon {
  flex-shrink: 0;
}


.calendar-grid {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.calendar-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.25rem;
  /* Smaller gap for weekdays */
  margin-bottom: 0.5rem;
}

.weekday {
  text-align: center;
  font-weight: 600;
  color: #666;
  padding: 0.5rem 0.25rem;
  font-size: 0.85rem;
}

.calendar-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.5rem;
}

.calendar-day {
  /* aspect-ratio: 1; /* Can make cells too large or small. Consider min-height. */
  min-height: 100px;
  /* Ensure a minimum height for usability */
  border: 2px solid #111;
  border-radius: 12px;
  padding: 0.5rem;
  background: #f5f5f5;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  /* Reduced gap inside day cell */
  transition: all 0.2s ease;
  position: relative;
  /* For positioning add button */
  overflow: hidden;
  /* Prevent content overflow */
}

.calendar-day:focus-within {
  /* Highlight when day or its content is focused */
  border-color: #007bff;
  box-shadow: 0 0 0 2px rgba(0, 123, 255, .25), 3px 3px 0 #111;
}


.calendar-day:hover:not(:focus-within) {
  transform: translateY(-2px);
  box-shadow: 3px 3px 0 #111;
}

.calendar-day.other-month {
  opacity: 0.6;
  background: #eee;
}

.calendar-day.today {
  background: #fff0b3;
  border-color: #ffc107;
}

/* Highlight today */
.calendar-day.has-chores:not(.today) {
  background: #e9f5ff;
}

/* Subtle bg for days with chores */


.day-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.day-number {
  font-weight: 600;
  font-size: 1rem;
}

.add-chore-indicator {
  /* visibility: hidden; Replaced with subtle always visible */
  opacity: 0.6;
  padding: 0.1rem;
  background: transparent;
  border: none;
  color: #007bff;
  cursor: pointer;
  border-radius: 50%;
  transition: all 0.2s ease;
  line-height: 1;
}

.add-chore-indicator .material-icons {
  font-size: 1.3rem;
}

.calendar-day:hover .add-chore-indicator,
.calendar-day:focus-within .add-chore-indicator,
/* Show on focus as well */
.add-chore-indicator:focus {
  opacity: 1;
  color: #0056b3;
  transform: scale(1.1);
}

.add-chore-indicator:hover {
  color: #f57c00;
  /* Distinct hover for the button itself */
}


.day-chores {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  scrollbar-width: thin;
  /* For Firefox */
}

.day-chores::-webkit-scrollbar {
  width: 5px;
}

.day-chores::-webkit-scrollbar-thumb {
  background: #ccc;
  border-radius: 3px;
}


.calendar-chore-item {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  /* Smaller gap */
  padding: 0.2rem 0.4rem;
  /* Compact padding */
  background: white;
  border: 1px solid #ddd;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 0.8rem;
  /* Smaller font for chore items */
  line-height: 1.3;
}

.calendar-chore-item:hover {
  background: #f0f8ff;
  transform: translateX(2px);
}

.calendar-chore-item.is-completed {
  opacity: 0.6;
  text-decoration: line-through;
}

.calendar-chore-item .chore-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-grow: 1;
}


.chore-status {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

.chore-status.overdue {
  background: #dc3545;
}

.chore-status.today {
  background: #007bff;
}

.chore-status.upcoming {
  background: #28a745;
}

.chore-status.completed {
  background: #6c757d;
}

@media (max-width: 768px) {
  .calendar-view {
    padding: 1rem;
  }

  .calendar-header h2 {
    font-size: 1.25rem;
  }

  .calendar-days {
    gap: 0.25rem;
  }

  .calendar-day {
    min-height: 80px;
    padding: 0.3rem;
  }

  .day-number {
    font-size: 0.9rem;
  }

  .add-chore-indicator .material-icons {
    font-size: 1.1rem;
  }

  .calendar-chore-item {
    font-size: 0.75rem;
    padding: 0.15rem 0.3rem;
  }

  .weekday {
    font-size: 0.75rem;
    padding: 0.3rem 0.1rem;
  }
}

@media (max-width: 480px) {
  .weekday {
    font-size: 0.6rem;
    /* Abbreviate to S, M, T... if needed */
  }

  .calendar-day {
    min-height: 70px;
  }

  .day-chores {
    gap: 0.15rem;
  }
}

/* Dark Mode Calendar */
@media (prefers-color-scheme: dark) {
  .calendar-view {
    background: #1a1a1a;
    border-color: #fff;
    box-shadow: 6px 6px 0 #fff;
  }

  .calendar-header h2 {
    color: #fff;
  }

  .weekday {
    color: #aaa;
  }

  .calendar-day {
    background: #2a2a2a;
    border-color: #555;
  }

  .calendar-day:hover:not(:focus-within) {
    box-shadow: 3px 3px 0 #fff;
  }

  .calendar-day.other-month {
    background: #222;
    opacity: 0.5;
  }

  .calendar-day.today {
    background: #4a3a00;
    border-color: #ffc107;
  }

  .calendar-day.has-chores:not(.today) {
    background: #1c2a3e;
  }

  .day-number {
    color: #f0f0f0;
  }

  .add-chore-indicator {
    color: #0095ff;
  }

  .add-chore-indicator:hover,
  .calendar-day:hover .add-chore-indicator,
  .add-chore-indicator:focus {
    color: #66c0ff;
  }

  .calendar-chore-item {
    background: #333;
    border-color: #444;
    color: #ccc;
  }

  .calendar-chore-item:hover {
    background: #3a4a5a;
  }

  .calendar-chore-item.is-completed {
    opacity: 0.5;
  }

  .chore-status.overdue {
    background: #d9534f;
  }

  .chore-status.today {
    background: #0095ff;
  }

  .chore-status.upcoming {
    background: #5cb85c;
  }

  .chore-status.completed {
    background: #777;
  }

  .day-chores::-webkit-scrollbar-thumb {
    background: #555;
  }

  .calendar-day:focus-within {
    border-color: #0095ff;
    box-shadow: 0 0 0 2px rgba(0, 149, 255, .25), 3px 3px 0 #fff;
  }
}


/* List View Styles */
.chores-list-container {}

/* Wrapper for list and empty state */
.chores-grid {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  /* Increased gap */
  margin-bottom: 2rem;
  width: 100%;
}

.chore-card {
  background: white;
  border-radius: 12px;
  border: 2px solid #111;
  box-shadow: 3px 3px 0 #111;
  padding: 1.25rem 1.5rem;
  /* Slightly more padding */
  display: flex;
  gap: 1rem;
  transition: all 0.2s ease;
  align-items: flex-start;
  /* Align status dot with top of content */
}

.chore-card:hover {
  transform: translateY(-1px);
  box-shadow: 4px 4px 0 #111;
}

.chore-card.is-overdue {
  border-left: 5px solid #dc3545;
  /* Use left border for overdue emphasis */
  /* border-color: #dc3545; // This changes all borders */
}

.chore-card.is-completed {
  opacity: 0.7;
  background: #f9f9f9;
  /* Slightly different bg for completed */
}

.chore-card.is-completed .chore-header h3 {
  text-decoration: line-through;
  color: #555;
}

.chore-status {
  margin-top: 0.25rem;
  /* Align with first line of text */
}


.chore-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* Stack main info and actions vertically */
  gap: 0.75rem;
}

.chore-main-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* Header and meta stacked */
  gap: 0.5rem;
}

.chore-header {
  display: flex;
  justify-content: space-between;
  /* Push tags to the right */
  align-items: flex-start;
  /* Align items at the start */
  gap: 1rem;
  width: 100%;
}

.chore-header h3 {
  margin: 0;
  font-size: 1.2rem;
  /* Slightly larger chore name */
  font-weight: 600;
  /* white-space: nowrap; // Removed to allow wrapping */
  /* overflow: hidden; text-overflow: ellipsis; // Removed */
  word-break: break-word;
  /* Allow long names to wrap */
  flex-grow: 1;
}

.chore-tags {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  /* Allow tags to wrap */
  flex-shrink: 0;
  /* Prevent tags from shrinking too much */
  margin-top: 2px;
  /* Align better with h3 */
}

.chore-type-tag,
.chore-frequency-tag {
  padding: 0.2rem 0.6rem;
  border-radius: 1rem;
  font-size: 0.75rem;
  /* Smaller tags */
  font-weight: 600;
  white-space: nowrap;
  border: 1px solid transparent;
  /* For consistency */
}

.chore-type-tag.personal {
  background: #e3f2fd;
  color: #1976d2;
  border-color: #b3e5fc;
}

.chore-type-tag.group {
  background: #f3e5f5;
  color: #7b1fa2;
  border-color: #e1bee7;
}

.chore-frequency-tag {
  background: #e8f5e9;
  color: #2e7d32;
  border-color: #c8e6c9;
}


.chore-meta {
  display: flex;
  flex-direction: column;
  /* Stack meta items */
  gap: 0.5rem;
  font-size: 0.9rem;
  /* Slightly larger meta text */
  color: #555;
}

.chore-meta>div {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

/* For icon and text alignment */
.chore-meta .material-icons {
  font-size: 1.1rem;
  color: #777;
}


.chore-due-date.overdue-text,
.chore-due-date .overdue {
  /* For overdue text specifically */
  color: #dc3545;
  font-weight: 500;
}

.chore-due-date.today-text {
  color: #007bff;
  font-weight: 500;
}

.chore-description {
  font-size: 0.9rem;
  color: #666;
  line-height: 1.4;
  /* white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 200px; // Removed for better readability, allow wrapping */
}

.chore-card-actions {
  display: flex;
  flex-wrap: wrap;
  /* Allow actions to wrap */
  gap: 0.5rem;
  align-items: center;
  /* Align items vertically */
  /* margin-left: auto; // No longer needed with flex-column parent */
  align-self: flex-end;
  /* Align actions to the right */
}

.chore-card-actions .btn {
  font-size: 0.85rem;
  padding: 0.4rem 0.8rem;
}

.chore-card-actions .btn-icon .material-icons {
  font-size: 1.2rem;
}

/* Ensure icon size is consistent */
.chore-card-actions .btn-icon .btn-text {
  font-size: 0.85rem;
}

/* Match text size if shown */


/* Dark Mode Support for List View */
@media (prefers-color-scheme: dark) {
  .chore-card {
    background: #1a1a1a;
    border-color: #fff;
    box-shadow: 3px 3px 0 #fff;
  }

  .chore-card:hover {
    box-shadow: 4px 4px 0 #fff;
    background: #202020;
  }

  .chore-card.is-completed {
    background: #222;
    opacity: 0.6;
  }

  .chore-card.is-completed .chore-header h3 {
    color: #888;
  }

  .chore-header h3 {
    color: #f0f0f0;
  }

  .chore-meta {
    color: #aaa;
  }

  .chore-meta .material-icons {
    color: #888;
  }

  .chore-description {
    color: #bbb;
  }

  .chore-type-tag.personal {
    background: #1c2a3e;
    color: #82cfff;
    border-color: #2a587f;
  }

  .chore-type-tag.group {
    background: #301c30;
    color: #e1a9f0;
    border-color: #5c2a5c;
  }

  .chore-frequency-tag {
    background: #1c301d;
    color: #9fec9f;
    border-color: #2a5c2b;
  }

  .chore-due-date.overdue-text {
    color: #ff8a80;
  }

  .chore-due-date.today-text {
    color: #80d8ff;
  }
}

/* Responsive Styles for List View */
@media (max-width: 768px) {
  .chores-grid {
    padding: 0;
    gap: 0.75rem;
  }

  .chore-card {
    padding: 1rem;
  }

  .chore-header h3 {
    font-size: 1.1rem;
  }

  .chore-tags {
    justify-content: flex-start;
  }

  /* Align tags to start on mobile */
  .chore-card-actions {
    align-self: stretch;
    justify-content: flex-end;
  }

  /* Full width for actions row, content to right */
}

@media (max-width: 480px) {

  /* On very small screens, hide text for Edit/Delete buttons in list view */
  .chore-card-actions .btn-icon .hide-text-on-mobile {
    display: none;
  }

  .chore-card-actions .btn-icon {
    /* Ensure padding is just for icon */
    padding: 0.5rem;
  }

  .chore-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
  }

  .chore-header h3 {
    font-size: 1rem;
  }
}


/* Transition Animations (as before) */
.chore-list-enter-active,
.chore-list-leave-active {
  transition: all 0.3s ease;
}

.chore-list-enter-from,
.chore-list-leave-to {
  opacity: 0;
  transform: translateY(20px) scale(0.95);
  /* Slightly different animation */
}

.chore-list-move {
  transition: transform 0.3s ease;
}

/* Keyboard Shortcuts Modal Styles (as before) */
.shortcuts-modal {
  max-width: 500px;
}

.shortcuts-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.shortcut-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  /* Reduced gap */
  padding: 0.75rem;
  background: #f5f5f5;
  border-radius: 8px;
  border: 2px solid #111;
}

.shortcut-keys {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  min-width: 110px;
  /* Adjusted min-width */
}

.shortcut-description {
  font-weight: 500;
  color: #333;
  font-size: 0.9rem;
}

kbd {
  background: white;
  border: 2px solid #111;
  border-radius: 4px;
  padding: 0.2rem 0.5rem;
  font-family: monospace;
  font-size: 0.9rem;
  box-shadow: 1px 1px 0 #111;
  /* Softer shadow for kbd */
  color: #111;
}

/* Dark Mode Support for Shortcuts Modal (as before) */
@media (prefers-color-scheme: dark) {
  .shortcut-item {
    background: #2a2a2a;
    border-color: #fff;
  }

  .shortcut-description {
    color: #fff;
  }

  kbd {
    background: #1a1a1a;
    border-color: #fff;
    box-shadow: 1px 1px 0 #fff;
    color: #fff;
  }
}

/* Remove old keyboard shortcuts help styles (as before) */
.keyboard-shortcuts-help,
.shortcuts-tooltip {
  display: none;
}
</style>