<template>
  <div class="dashboard">
    <div v-if="isAuthenticated && user">
      <h2>My Habits for {{ user.nickname }}</h2>
      
      <div v-if="loading" class="loading-message">
        <p>Loading habits...</p>
      </div>

      <div v-else-if="processedHabits.length > 0" class="habits-list">
        <div v-for="habit in processedHabits" :key="habit.id" class="habit-card">
          <div class="habit-details">
            <div class="habit-header">
              <div class="habit-title-area">
                <span class="habit-name">{{ habit.name }}</span>
                <span class="habit-schedule">{{ formatDaysOfWeek(habit.daysOfWeek) }}</span>
              </div>
              <button
                v-if="isActionableToday(habit) && !isCompleteToday(habit)"
                @click="completeHabit(habit.id)"
                :disabled="completing === habit.id"
                class="complete-btn"
              >
                {{ completing === habit.id ? '...' : 'Complete' }}
              </button>
              <span v-else-if="isCompleteToday(habit)" class="completed-text">✅ Done!</span>
            </div>
            <div class="calendar-grid">
              <div 
                v-for="day in calendarDays" 
                :key="day.getTime()"
                :class="['calendar-cell', getDayStatus(habit, day), { 'is-scheduled': isScheduledDay(habit, day) }]"
              >
                <span class="date-label">{{ formatDate(day) }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div v-else class="empty-state">
        <p>You haven't created any habits yet.</p>
        <NuxtLink to="/habits">Manage Habits</NuxtLink>
      </div>

    </div>
    <div v-else>
       <p>Loading session...</p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue';

// --- Type Definitions ---
interface Habit {
  id: number;
  name: string;
  daysOfWeek: number[]; // Backend: 0 = Monday, 6 = Sunday
  completions: { id: number; date: string }[];
  createdAt: string;
}
// Internal type for easier lookup
interface HabitWithCompletionSet extends Habit {
  completionDates: Set<number>; // Set of timestamps for O(1) lookup
  createdAtTimestamp: number;
}

// --- Composables ---
const { user, isAuthenticated } = useAuth();
const api = useApi();

// --- State ---
const allHabits = ref<Habit[]>([]);
const loading = ref(true);
const completing = ref<number | null>(null);

// --- Helpers: Date Normalization & Formatting ---
/**
 * Normalizes a date to the start of the day in UTC.
 */
const normalizeDateUTC = (date: Date): Date => {
  return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
};

/**
 * Normalizes a JS Date's getDay() result (0=Sun) to the backend's format (0=Mon).
 * @param jsDay The result of date.getUTCDay()
 * @returns A number where 0 = Monday, ..., 6 = Sunday.
 */
const normalizeJsDay = (jsDay: number): number => {
  return jsDay === 0 ? 6 : jsDay - 1;
};

const today = normalizeDateUTC(new Date());

const formatDate = (date: Date): string => {
  return date.toLocaleDateString('ru-RU', { day: 'numeric', month: 'short' });
};


// --- Computed Properties ---
const processedHabits = computed((): HabitWithCompletionSet[] => {
  return allHabits.value
    .map(habit => ({
      ...habit,
      completionDates: new Set(habit.completions.map(c => normalizeDateUTC(new Date(c.date)).getTime())),
      createdAtTimestamp: normalizeDateUTC(new Date(habit.createdAt)).getTime(),
    }));
});

const calendarDays = computed(() => {
  const dates = [];
  // JS day is 0=Sun, so we normalize it to backend's 0=Mon format.
  const todayBackendDay = normalizeJsDay(today.getUTCDay());

  // Start date is the Monday of the previous week.
  const startDate = normalizeDateUTC(new Date(today));
  startDate.setUTCDate(startDate.getUTCDate() - todayBackendDay - 7);
  
  for (let i = 0; i < 14; i++) {
    const d = new Date(startDate);
    d.setUTCDate(d.getUTCDate() + i);
    dates.push(d);
  }
  return dates;
});


// --- Methods: Status and Actions ---

const dayLabels = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'];

const formatDaysOfWeek = (days: number[]): string => {
  if (days.length === 7) {
    return 'Каждый день';
  }
  return [...days]
    .sort((a, b) => a - b) // Sort numerically (0=Mon, 1=Tue, etc.)
    .map(dayIndex => dayLabels[dayIndex])
    .join(', ');
};

const isScheduledDay = (habit: HabitWithCompletionSet, date: Date): boolean => {
  const backendDay = normalizeJsDay(normalizeDateUTC(date).getUTCDay());
  return habit.daysOfWeek.includes(backendDay);
};

const isActionableToday = (habit: HabitWithCompletionSet): boolean => {
  const todayBackendDay = normalizeJsDay(today.getUTCDay());
  return habit.daysOfWeek.includes(todayBackendDay);
};

const getDayStatus = (habit: HabitWithCompletionSet, date: Date): string => {
  const normalizedDate = normalizeDateUTC(date);
  const normalizedTimestamp = normalizedDate.getTime();
  
  if (normalizedTimestamp > today.getTime()) {
    return 'NEUTRAL';
  }
  
  if (normalizedTimestamp < habit.createdAtTimestamp) {
    return 'NEUTRAL';
  }

  if (!isScheduledDay(habit, date)) {
    return 'NEUTRAL';
  }
  
  if (habit.completionDates.has(normalizedTimestamp)) {
    return 'COMPLETED';
  }
  
  return 'MISSED';
};

const isCompleteToday = (habit: HabitWithCompletionSet) => {
  return habit.completionDates.has(today.getTime());
};

const fetchHabits = async () => {
  loading.value = true;
  try {
    allHabits.value = await api<Habit[]>('/habits');
  } catch (error) {
    console.error("Failed to fetch habits:", error);
    allHabits.value = [];
  } finally {
    loading.value = false;
  }
};

const completeHabit = async (habitId: number) => {
  completing.value = habitId;
  try {
    await api(`/habits/${habitId}/complete`, { method: 'POST' });
    await fetchHabits(); // Re-fetch the list to update UI
  } catch (error) {
    console.error(`Failed to complete habit ${habitId}:`, error);
  } finally {
    completing.value = null;
  }
};


// --- Lifecycle ---
onMounted(() => {
  if (isAuthenticated.value) {
    fetchHabits();
  }
  watch(isAuthenticated, (isAuth) => {
    if (isAuth && allHabits.value.length === 0) {
      fetchHabits();
    }
  });
});
</script>

<style scoped>
.dashboard {
  max-width: 600px;
  margin: 0 auto;
  text-align: center;
}
.habits-list {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-top: 20px;
}
.habit-card {
  padding: 15px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.05);
  text-align: left;
}
.habit-details {
  width: 100%;
}
.habit-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start; /* Align items to the top */
  margin-bottom: 15px;
  gap: 10px; /* Add gap between title area and button */
}
.habit-title-area {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.habit-name {
  font-size: 1.2em;
  font-weight: bold;
}
.habit-schedule {
  font-size: 0.85em;
  color: #666;
  font-style: italic;
}
.complete-btn {
  padding: 8px 12px;
  border: none;
  border-radius: 5px;
  background-color: #88c0d0;
  color: #2e3440;
  cursor: pointer;
  flex-shrink: 0;
}
.completed-text {
  color: #a3be8c;
  font-weight: bold;
  flex-shrink: 0;
}
.empty-state {
  margin-top: 40px;
  color: #666;
}
.empty-state a {
  margin-top: 10px;
  display: inline-block;
}

/* Calendar Grid Styles */
.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 5px; /* Slightly more gap */
}
.calendar-cell {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 4px;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid transparent; /* Default transparent border */
}
.calendar-cell.is-scheduled {
  border-color: #d8dee9; /* Neutral border for scheduled days */
}
.date-label {
  font-size: 0.75em;
  color: #4c566a;
}
.calendar-cell.COMPLETED .date-label,
.calendar-cell.MISSED .date-label {
  color: white;
}
.calendar-cell.NEUTRAL {
  background-color: #eceff4; /* Gray */
}
.calendar-cell.COMPLETED {
  background-color: #a3be8c; /* Green */
  border-color: #a3be8c;
}
.calendar-cell.MISSED {
  background-color: #bf616a; /* Red */
  border-color: #bf616a;
}
</style>
