<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { format, startOfDay, isEqual, isToday as isTodayDate } from 'date-fns'
import { choreService } from '../services/choreService'
import { useNotificationStore } from '../stores/notifications'
import type { Chore, ChoreCreate, ChoreUpdate, ChoreFrequency, ChoreAssignmentUpdate } from '../types/chore'
import { groupService } from '../services/groupService'
import { useStorage } from '@vueuse/core'

const { t } = useI18n()

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

interface ChoreFormData {
  name: string;
  description: string;
  frequency: ChoreFrequency;
  custom_interval_days: number | undefined;
  next_due_date: string;
  type: 'personal' | 'group';
  group_id: number | undefined;
}

const notificationStore = useNotificationStore()

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

const initialChoreFormState: ChoreFormData = {
  name: '',
  description: '',
  frequency: 'daily',
  custom_interval_days: undefined,
  next_due_date: format(new Date(), 'yyyy-MM-dd'),
  type: 'personal',
  group_id: undefined,
}

const choreForm = ref({ ...initialChoreFormState })
const isLoading = ref(true)

const loadChores = async () => {
  const now = Date.now();
  if (cachedChores.value && cachedChores.value.length > 0 && (now - cachedTimestamp.value) < CACHE_DURATION) {
    chores.value = cachedChores.value;
    isLoading.value = false;
  } else {
    isLoading.value = true;
  }

  try {
    const fetchedChores = await choreService.getAllChores()
    const mappedChores = fetchedChores.map(c => {
      const currentAssignment = c.assignments && c.assignments.length > 0 ? c.assignments[0] : null;
      return {
        ...c,
        current_assignment_id: currentAssignment?.id ?? null,
        is_completed: currentAssignment?.is_complete ?? c.is_completed ?? false,
        completed_at: currentAssignment?.completed_at ?? c.completed_at ?? null,
        updating: false,
      }
    });
    chores.value = mappedChores;
    cachedChores.value = mappedChores;
    cachedTimestamp.value = Date.now()
  } catch (error) {
    console.error(t('choresPage.consoleErrors.loadFailed'), error)
    notificationStore.addNotification({ message: t('choresPage.notifications.loadFailed', 'Failed to load chores.'), type: 'error' })
  } finally {
    isLoading.value = false
  }
}

const loadGroups = async () => {
  try {
    groups.value = await groupService.getUserGroups();
  } catch (error) {
    console.error(t('choresPage.consoleErrors.loadGroupsFailed'), error);
    notificationStore.addNotification({ message: t('choresPage.notifications.loadGroupsFailed', 'Failed to load groups.'), type: 'error' });
  }
}

onMounted(() => {
  loadChores()
  loadGroups()
})

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 getChoreSubtext = (chore: ChoreWithCompletion): string => {
  if (chore.is_completed && chore.completed_at) {
    const completedDate = new Date(chore.completed_at);
    if (isTodayDate(completedDate)) {
      return t('choresPage.completedToday');
    }
    return t('choresPage.completedOn', { date: format(completedDate, 'd MMM') });
  }

  const parts: string[] = [];

  if (chore.frequency && chore.frequency !== 'one_time') {
    const freqOption = frequencyOptions.value.find(f => f.value === chore.frequency);
    if (freqOption) {
      if (chore.frequency === 'custom' && chore.custom_interval_days) {
        parts.push(t('choresPage.frequency.customInterval', { n: chore.custom_interval_days }));
      } else {
        parts.push(freqOption.label);
      }
    }
  }

  if (chore.type === 'group' && chore.group_id) {
    const group = groups.value.find(g => g.id === chore.group_id);
    if (group) {
      parts.push(group.name);
    }
  }

  return parts.join(' · ');
};

const groupedChores = computed(() => {
  if (!chores.value) return []

  const choresByDate = chores.value.reduce((acc, chore) => {
    const dueDate = format(startOfDay(new Date(chore.next_due_date)), 'yyyy-MM-dd')
    if (!acc[dueDate]) {
      acc[dueDate] = []
    }
    acc[dueDate].push(chore)
    return acc
  }, {} as Record<string, ChoreWithCompletion[]>)

  return Object.keys(choresByDate)
    .sort((a, b) => new Date(a).getTime() - new Date(b).getTime())
    .map(dateStr => {
      // Create a new Date object and ensure it's interpreted as local time, not UTC
      const dateParts = dateStr.split('-').map(Number);
      const date = new Date(dateParts[0], dateParts[1] - 1, dateParts[2]);
      return {
        date,
        chores: choresByDate[dateStr]
          .sort((a, b) => a.name.localeCompare(b.name))
          .map(chore => ({
            ...chore,
            subtext: getChoreSubtext(chore)
          }))
      }
    });
})

const formatDateHeader = (date: Date) => {
  const today = startOfDay(new Date())
  const itemDate = startOfDay(date)

  if (isEqual(itemDate, today)) {
    return `${t('choresPage.today', 'Today')}, ${format(itemDate, 'eee, d MMM')}`
  }
  return format(itemDate, 'eee, d MMM')
}

const resetChoreForm = () => {
  choreForm.value = { ...initialChoreFormState, next_due_date: format(new Date(), 'yyyy-MM-dd') };
  isEditing.value = false
  selectedChore.value = null
}

const openCreateChoreModal = () => {
  resetChoreForm()
  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 ?? undefined,
    next_due_date: chore.next_due_date,
    type: chore.type,
    group_id: chore.group_id ?? undefined,
  }
  showChoreModal.value = true
}

const handleFormSubmit = async () => {
  try {
    let createdChore;
    if (isEditing.value && selectedChore.value) {
      const updateData: ChoreUpdate = { ...choreForm.value };
      createdChore = await choreService.updateChore(selectedChore.value.id, updateData);
      notificationStore.addNotification({ message: t('choresPage.notifications.updateSuccess', 'Chore updated successfully!'), type: 'success' });
    } else {
      const createData = { ...choreForm.value };
      createdChore = await choreService.createChore(createData as ChoreCreate);

      // Create an assignment for the new chore
      if (createdChore) {
        try {
          await choreService.createAssignment({
            chore_id: createdChore.id,
            assigned_to_user_id: createdChore.created_by_id,
            due_date: createdChore.next_due_date
          });
        } catch (assignmentError) {
          console.error(t('choresPage.consoleErrors.createAssignmentForNewChoreFailed'), assignmentError);
          // Continue anyway since the chore was created
        }
      }

      notificationStore.addNotification({ message: t('choresPage.notifications.createSuccess', 'Chore created successfully!'), type: 'success' });
    }
    showChoreModal.value = false;
    await loadChores();
  } catch (error) {
    console.error(t('choresPage.consoleErrors.saveFailed'), error);
    notificationStore.addNotification({ message: t('choresPage.notifications.saveFailed', 'Failed to save the chore.'), type: 'error' });
  }
}

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

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

const toggleCompletion = async (chore: ChoreWithCompletion) => {
  if (chore.current_assignment_id === null) {
    // If no assignment exists, create one
    try {
      const assignment = await choreService.createAssignment({
        chore_id: chore.id,
        assigned_to_user_id: chore.created_by_id,
        due_date: chore.next_due_date
      });
      chore.current_assignment_id = assignment.id;
    } catch (error) {
      console.error(t('choresPage.consoleErrors.createAssignmentFailed'), error);
      notificationStore.addNotification({
        message: t('choresPage.notifications.createAssignmentFailed', 'Failed to create assignment for chore.'),
        type: 'error'
      });
      return;
    }
  }

  const originalCompleted = chore.is_completed;
  chore.updating = true;
  const newCompletedStatus = !chore.is_completed;
  chore.is_completed = newCompletedStatus;

  try {
    if (newCompletedStatus) {
      await choreService.completeAssignment(chore.current_assignment_id);
    } else {
      const assignmentUpdate: ChoreAssignmentUpdate = { is_complete: false };
      await choreService.updateAssignment(chore.current_assignment_id, assignmentUpdate);
    }

    notificationStore.addNotification({
      message: newCompletedStatus ? t('choresPage.notifications.completed', 'Chore marked as complete!') : t('choresPage.notifications.uncompleted', 'Chore marked as incomplete.'),
      type: 'success'
    });
    await loadChores();
  } catch (error) {
    console.error(t('choresPage.consoleErrors.updateCompletionStatusFailed'), error);
    notificationStore.addNotification({ message: t('choresPage.notifications.updateFailed', 'Failed to update chore status.'), type: 'error' });
    chore.is_completed = originalCompleted;
  } finally {
    chore.updating = false;
  }
};
</script>

<template>
  <div class="container">
    <header class="flex justify-between items-center">
      <h1 style="margin-block-start: 0;">{{ t('choresPage.title') }}</h1>
      <button class="btn btn-primary" @click="openCreateChoreModal">
        {{ t('choresPage.addChore', '+') }}
      </button>
    </header>

    <div v-if="isLoading" class="flex justify-center mt-4">
      <div class="spinner-dots">
        <span></span>
        <span></span>
        <span></span>
      </div>
    </div>

    <div v-else-if="groupedChores.length === 0" class="empty-state-card">
      <h3>{{ t('choresPage.empty.title', 'No Chores Yet') }}</h3>
      <p>{{ t('choresPage.empty.message', 'Get started by adding your first chore!') }}</p>
      <button class="btn btn-primary" @click="openCreateChoreModal">
        {{ t('choresPage.addFirstChore', 'Add First Chore') }}
      </button>
    </div>

    <div v-else class="schedule-list">
      <div v-for="group in groupedChores" :key="group.date.toISOString()" class="schedule-group">
        <h2 class="date-header">{{ formatDateHeader(group.date) }}</h2>
        <div class="neo-item-list-container">
          <ul class="neo-item-list">
            <li v-for="chore in group.chores" :key="chore.id" class="neo-list-item">
              <div class="neo-item-content">
                <label class="neo-checkbox-label">
                  <input type="checkbox" :checked="chore.is_completed" @change="toggleCompletion(chore)">
                  <div class="checkbox-content">
                    <span class="checkbox-text-span"
                      :class="{ 'neo-completed-static': chore.is_completed && !chore.updating }">
                      {{ chore.name }}
                    </span>
                    <span v-if="chore.subtext" class="item-time">{{ chore.subtext }}</span>
                  </div>
                </label>
                <div class="neo-item-actions">
                  <button class="btn btn-sm btn-neutral" @click="openEditChoreModal(chore)">
                    {{ t('choresPage.edit', 'Edit') }}
                  </button>
                  <button class="btn btn-sm btn-danger" @click="confirmDelete(chore)">
                    {{ t('choresPage.delete', 'Delete') }}
                  </button>
                </div>
              </div>
            </li>
          </ul>
        </div>
      </div>
    </div>

    <!-- Chore Form Modal -->
    <div v-if="showChoreModal" class="modal-backdrop open" @click.self="showChoreModal = false">
      <div class="modal-container">
        <form @submit.prevent="handleFormSubmit">
          <div class="modal-header">
            <h3>{{ isEditing ? t('choresPage.editChore', 'Edit Chore') : t('choresPage.createChore', 'Create Chore') }}
            </h3>
            <button type="button" @click="showChoreModal = false" class="close-button">
              &times;
            </button>
          </div>
          <div class="modal-body">
            <div class="form-group">
              <label class="form-label" for="chore-name">{{ t('choresPage.form.name', 'Name') }}</label>
              <input id="chore-name" type="text" v-model="choreForm.name" class="form-input" required>
            </div>
            <div class="form-group">
              <label class="form-label" for="chore-desc">{{ t('choresPage.form.description', 'Description') }}</label>
              <textarea id="chore-desc" v-model="choreForm.description" class="form-input"></textarea>
            </div>
            <div class="form-group">
              <label class="form-label" for="chore-date">{{ t('choresPage.form.dueDate', 'Due Date') }}</label>
              <input id="chore-date" type="date" v-model="choreForm.next_due_date" class="form-input" required>
            </div>
            <div class="form-group">
              <label class="form-label">{{ t('choresPage.form.frequency', 'Frequency') }}</label>
              <div class="radio-group">
                <label v-for="option in frequencyOptions" :key="option.value" class="radio-label">
                  <input type="radio" v-model="choreForm.frequency" :value="option.value">
                  <span class="checkmark radio-mark"></span>
                  <span>{{ option.label }}</span>
                </label>
              </div>
            </div>
            <div v-if="choreForm.frequency === 'custom'" class="form-group">
              <label class="form-label" for="chore-interval">{{ t('choresPage.form.interval', 'Interval (days)')
                }}</label>
              <input id="chore-interval" type="number" v-model.number="choreForm.custom_interval_days"
                class="form-input" :placeholder="t('choresPage.form.intervalPlaceholder')" min="1">
            </div>
            <div class="form-group">
              <label class="form-label">{{ t('choresPage.form.type', 'Type') }}</label>
              <div class="radio-group">
                <label class="radio-label">
                  <input type="radio" v-model="choreForm.type" value="personal">
                  <span class="checkmark radio-mark"></span>
                  <span>{{ t('choresPage.form.personal', 'Personal') }}</span>
                </label>
                <label class="radio-label">
                  <input type="radio" v-model="choreForm.type" value="group">
                  <span class="checkmark radio-mark"></span>
                  <span>{{ t('choresPage.form.group', 'Group') }}</span>
                </label>
              </div>
            </div>
            <div v-if="choreForm.type === 'group'" class="form-group">
              <label class="form-label" for="chore-group">{{ t('choresPage.form.assignGroup', 'Assign to Group')
                }}</label>
              <select id="chore-group" v-model="choreForm.group_id" class="form-input">
                <option v-for="group in groups" :key="group.id" :value="group.id">{{ group.name }}</option>
              </select>
            </div>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-neutral" @click="showChoreModal = false">{{
              t('choresPage.form.cancel', 'Cancel')
              }}</button>
            <button type="submit" class="btn btn-primary">{{ isEditing ? t('choresPage.form.save', 'Save Changes') :
              t('choresPage.form.create', 'Create') }}</button>
          </div>
        </form>
      </div>
    </div>

    <!-- Delete Confirmation Dialog -->
    <div v-if="showDeleteDialog" class="modal-backdrop open" @click.self="showDeleteDialog = false">
      <div class="modal-container confirm-modal">
        <div class="modal-header">
          <h3>{{ t('choresPage.deleteConfirm.title', 'Confirm Deletion') }}</h3>
          <button type="button" @click="showDeleteDialog = false" class="close-button">
            &times;
          </button>
        </div>
        <div class="modal-body">
          <p>{{ t('choresPage.deleteConfirm.message', 'Really want to delete? This action cannot be undone.') }}</p>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-neutral" @click="showDeleteDialog = false">{{
            t('choresPage.deleteConfirm.cancel', 'Cancel') }}</button>
          <button type="button" class="btn btn-danger" @click="deleteChore">{{
            t('choresPage.deleteConfirm.delete', 'Delete')
            }}</button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.schedule-group {
  margin-bottom: 2rem;
  position: relative;
}

.date-header {
  font-size: clamp(1rem, 4vw, 1.2rem);
  font-weight: bold;
  color: var(--dark);
  text-transform: none;
  letter-spacing: normal;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid var(--dark);
  position: sticky;
  top: 0;
  background-color: var(--light);
  z-index: 10;

  &::after {
    display: none; // Hides the default h-tag underline from valerie-ui
  }
}

.item-time {
  font-size: 0.9rem;
  color: var(--dark);
  opacity: 0.7;
  margin-left: 1rem;
}

.neo-item-list-container {
  border: 3px solid #111;
  border-radius: 18px;
  background: var(--light);
  box-shadow: 6px 6px 0 #111;
  overflow: hidden;
}

/* Neo-style list items from ListDetailPage */
.neo-item-list {
  list-style: none;
  padding: 0.5rem 1rem;
  margin: 0;
}

.neo-list-item {
  display: flex;
  align-items: center;
  padding: 0.75rem 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  position: relative;
  transition: background-color 0.2s ease;
}

.neo-list-item:hover {
  background-color: #f8f8f8;
}

.neo-list-item:last-child {
  border-bottom: none;
}

.neo-item-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  gap: 0.5rem;
}

.neo-item-actions {
  display: flex;
  gap: 0.25rem;
  opacity: 0;
  transition: opacity 0.2s ease;
  margin-left: auto;

  .btn {
    margin-left: 0.25rem;
  }
}

.neo-list-item:hover .neo-item-actions {
  opacity: 1;
}

/* Custom Checkbox Styles from ListDetailPage */
.neo-checkbox-label {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 0.8em;
  cursor: pointer;
  position: relative;
  width: 100%;
  font-weight: 500;
  color: #414856;
  transition: color 0.3s ease;
  margin-bottom: 0;
}

.neo-checkbox-label input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  position: relative;
  height: 20px;
  width: 20px;
  outline: none;
  border: 2px solid #b8c1d1;
  margin: 0;
  cursor: pointer;
  background: transparent;
  border-radius: 6px;
  display: grid;
  align-items: center;
  justify-content: center;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.neo-checkbox-label input[type="checkbox"]:hover {
  border-color: var(--secondary);
  transform: scale(1.05);
}

.neo-checkbox-label input[type="checkbox"]::before,
.neo-checkbox-label input[type="checkbox"]::after {
  content: none;
}

.neo-checkbox-label input[type="checkbox"]::after {
  content: "";
  position: absolute;
  opacity: 0;
  left: 5px;
  top: 1px;
  width: 6px;
  height: 12px;
  border: solid var(--primary);
  border-width: 0 3px 3px 0;
  transform: rotate(45deg) scale(0);
  transition: all 0.2s cubic-bezier(0.18, 0.89, 0.32, 1.28);
  transition-property: transform, opacity;
}

.neo-checkbox-label input[type="checkbox"]:checked {
  border-color: var(--primary);
}

.neo-checkbox-label input[type="checkbox"]:checked::after {
  opacity: 1;
  transform: rotate(45deg) scale(1);
}

.checkbox-content {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
}

.checkbox-text-span {
  position: relative;
  transition: color 0.4s ease, opacity 0.4s ease;
  width: fit-content;
  font-weight: 500;
  color: var(--dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Animated strikethrough line */
.checkbox-text-span::before {
  content: '';
  position: absolute;
  top: 50%;
  left: -0.1em;
  right: -0.1em;
  height: 2px;
  background: var(--dark);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.4s cubic-bezier(0.77, 0, .18, 1);
}

.neo-checkbox-label input[type="checkbox"]:checked~.checkbox-content .checkbox-text-span {
  color: var(--dark);
  opacity: 0.6;
}

.neo-checkbox-label input[type="checkbox"]:checked~.checkbox-content .checkbox-text-span::before {
  transform: scaleX(1);
  transform-origin: left;
  transition: transform 0.4s cubic-bezier(0.77, 0, .18, 1) 0.1s;
}

.neo-completed-static {
  color: var(--dark);
  opacity: 0.6;
  position: relative;
}

.neo-completed-static::before {
  content: '';
  position: absolute;
  top: 50%;
  left: -0.1em;
  right: -0.1em;
  height: 2px;
  background: var(--dark);
  transform: scaleX(1);
  transform-origin: left;
}
</style>
