<script setup>
import { ref, computed, onMounted, watch } from "vue";
import AddHoursModal from "../components/AddHoursModal.vue";
import { fetchMonthEntries, fetchRegistry } from "../composables/useHoursApi.js";
import { apiErrorDetail } from "../../../services/api.js";
import { useBaseToast } from "../../../composables/useBaseToast.js";
import { todayIsoLocal, monthFirstIso, addMonthsIso, daysInMonthYm } from "../composables/useHourWeekNavigate.js";

const toast = useBaseToast();

const today = todayIsoLocal();
const currentMonthFirst = ref(monthFirstIso(today));
const loading = ref(true);
const showModal = ref(false);
const modalDate = ref(null);

/** @type {import('vue').Ref<Record<string, Array<{ line_id: number, hours: number, label: string, description: string }>>>} */
const entriesByDate = ref({});

const registry = ref({ internalCategories: [], customers: [], projects: [] });

// ─── Month display helpers ────────────────────────────────────────────────────
const NL_MONTHS = [
  "januari", "februari", "maart", "april", "mei", "juni",
  "juli", "augustus", "september", "oktober", "november", "december",
];
const NL_WEEKDAYS_SHORT = ["Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"];

const monthLabel = computed(() => {
  const [y, m] = currentMonthFirst.value.split("-").map(Number);
  return `${NL_MONTHS[m - 1]} ${y}`;
});

const pageTitle = computed(() => `Uren - ${monthLabel.value}`);

// ─── Calendar grid cells ──────────────────────────────────────────────────────
const calendarCells = computed(() => {
  const [y, m] = currentMonthFirst.value.split("-").map(Number);
  const firstDay = new Date(y, m - 1, 1);
  const daysInMonth = daysInMonthYm(currentMonthFirst.value);
  // Monday = 0 in our grid
  const leadingBlanks = (firstDay.getDay() + 6) % 7;
  const totalSlots = Math.ceil((leadingBlanks + daysInMonth) / 7) * 7;

  const cells = [];
  for (let i = 0; i < totalSlots; i++) {
    const dayNum = i - leadingBlanks + 1;
    if (dayNum < 1 || dayNum > daysInMonth) {
      // Prev/next month padding
      let paddingDate = null;
      if (dayNum < 1) {
        const d = new Date(y, m - 1, dayNum, 12, 0, 0);
        paddingDate = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
      }
      cells.push({ iso: paddingDate, day: paddingDate ? new Date(y, m - 1, dayNum).getDate() : null, inMonth: false, isWeekend: i % 7 >= 5 });
    } else {
      const iso = `${y}-${String(m).padStart(2, "0")}-${String(dayNum).padStart(2, "0")}`;
      cells.push({ iso, day: dayNum, inMonth: true, isWeekend: i % 7 >= 5 });
    }
  }
  return cells;
});

// ─── Data loading ─────────────────────────────────────────────────────────────
async function loadMonthData() {
  loading.value = true;
  try {
    const [y, m] = currentMonthFirst.value.split("-").map(Number);
    const dim = daysInMonthYm(currentMonthFirst.value);
    const from = currentMonthFirst.value;
    const to = `${y}-${String(m).padStart(2, "0")}-${String(dim).padStart(2, "0")}`;

    const rows = await fetchMonthEntries(from, to);
    const map = {};
    for (const row of rows) {
      if (row.date) map[row.date] = row.entries ?? [];
    }
    entriesByDate.value = map;
  } catch (e) {
    toast.error(apiErrorDetail(e), "Uren", 7000);
  } finally {
    loading.value = false;
  }
}

onMounted(async () => {
  try {
    registry.value = await fetchRegistry();
  } catch {
    // registry failure is non-fatal
  }
  await loadMonthData();
});

watch(currentMonthFirst, loadMonthData);

// ─── Navigation ───────────────────────────────────────────────────────────────
function prevMonth() {
  currentMonthFirst.value = addMonthsIso(currentMonthFirst.value, -1);
}
function nextMonth() {
  currentMonthFirst.value = addMonthsIso(currentMonthFirst.value, 1);
}
function goToday() {
  currentMonthFirst.value = monthFirstIso(today);
}

// ─── Hover state ──────────────────────────────────────────────────────────────
const hoveredIso = ref(null);

// ─── Modal ────────────────────────────────────────────────────────────────────
function openAddModal(iso = null) {
  modalDate.value = iso;
  showModal.value = true;
}

async function onSaved() {
  showModal.value = false;
  await loadMonthData();
}

// ─── Entry formatting ─────────────────────────────────────────────────────────
function formatHours(h) {
  const totalMinutes = Math.round(h * 60);
  const hours = Math.floor(totalMinutes / 60);
  const minutes = totalMinutes % 60;
  return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
}

function dayEntries(iso) {
  return iso ? (entriesByDate.value[iso] ?? []) : [];
}

const MAX_VISIBLE_ENTRIES = 3;
</script>

<template>
  <div class="flex flex-col h-full">
    <!-- ── Page Header ─────────────────────────────────────────────────── -->
    <div class="flex flex-wrap items-center justify-between gap-3 px-5 py-4 bg-surface-0 dark:bg-surface-900 border-b border-surface-200 dark:border-surface-700">
      <!-- Title -->
      <h1 class="flex items-center gap-2 text-xl font-semibold text-surface-900 dark:text-surface-0 m-0">
        <i class="pi pi-clock text-surface-600 dark:text-surface-400" />
        {{ pageTitle }}
      </h1>

      <!-- Month navigation -->
      <div class="flex items-center border border-surface-200 dark:border-surface-700 rounded-lg overflow-hidden">
        <button
          type="button"
          class="px-3 py-1.5 text-surface-600 dark:text-surface-300 hover:bg-surface-50 dark:hover:bg-surface-800 transition-colors border-r border-surface-200 dark:border-surface-700"
          @click="prevMonth"
        >
          <i class="pi pi-chevron-left text-xs" />
        </button>
        <button
          type="button"
          class="px-4 py-1.5 text-sm font-medium text-surface-700 dark:text-surface-300 hover:bg-surface-50 dark:hover:bg-surface-800 transition-colors"
          @click="goToday"
        >
          Deze maand
        </button>
        <button
          type="button"
          class="px-3 py-1.5 text-surface-600 dark:text-surface-300 hover:bg-surface-50 dark:hover:bg-surface-800 transition-colors border-l border-surface-200 dark:border-surface-700"
          @click="nextMonth"
        >
          <i class="pi pi-chevron-right text-xs" />
        </button>
      </div>
    </div>

    <!-- ── Calendar ───────────────────────────────────────────────────── -->
    <div class="flex-1 overflow-auto p-4 md:p-5">
      <div
        v-if="loading"
        class="flex items-center justify-center h-48 text-surface-400"
      >
        <i class="pi pi-spin pi-spinner text-2xl" />
      </div>

      <div
        v-else
        class="bg-white dark:bg-surface-900 border border-surface-200 dark:border-surface-700 rounded-2xl overflow-hidden"
      >
        <!-- Weekday header row -->
        <div class="grid grid-cols-7 border-b border-surface-200 dark:border-surface-700">
          <div
            v-for="wd in NL_WEEKDAYS_SHORT"
            :key="wd"
            class="py-3 text-center text-xs font-semibold text-surface-500 dark:text-surface-400 border-r border-surface-200 dark:border-surface-700 last:border-r-0"
          >
            {{ wd }}
          </div>
        </div>

        <!-- Calendar rows -->
        <div class="grid grid-cols-7 auto-rows-fr">
          <div
            v-for="(cell, idx) in calendarCells"
            :key="idx"
            class="min-h-[7rem] border-b border-r border-surface-200 dark:border-surface-700 relative group transition-colors"
            :class="[
              idx % 7 === 6 ? 'border-r-0' : '',
              !cell.inMonth ? 'bg-surface-50 dark:bg-surface-800/40' : cell.isWeekend ? 'bg-surface-50/50 dark:bg-surface-800/20' : 'bg-white dark:bg-surface-900',
              cell.inMonth ? 'hover:bg-primary-50/40 dark:hover:bg-primary-950/20' : '',
            ]"
            @mouseenter="hoveredIso = cell.iso"
            @mouseleave="hoveredIso = null"
          >
            <!-- Day number -->
            <div class="flex items-center justify-between px-2 pt-1.5">
              <span
                class="inline-flex items-center justify-center w-6 h-6 text-xs font-semibold rounded-full"
                :class="[
                  !cell.inMonth
                    ? 'text-surface-300 dark:text-surface-600'
                    : cell.iso === today
                      ? 'bg-primary-600 text-white'
                      : 'text-surface-700 dark:text-surface-300',
                ]"
              >
                {{ cell.day }}
              </span>
            </div>

            <!-- Entries -->
            <div v-if="cell.inMonth && cell.iso" class="px-1.5 pb-1 flex flex-col gap-0.5 mt-0.5">
              <template v-for="(entry, ei) in dayEntries(cell.iso)" :key="ei">
                <div
                  v-if="ei < MAX_VISIBLE_ENTRIES"
                  class="flex items-center gap-1 rounded px-1.5 py-0.5 bg-surface-100 dark:bg-surface-700/60 text-xs leading-tight truncate"
                >
                  <span class="font-semibold text-surface-800 dark:text-surface-100 flex-shrink-0">
                    {{ formatHours(entry.hours) }}
                  </span>
                  <span class="text-surface-600 dark:text-surface-300 truncate">
                    {{ entry.label }}
                  </span>
                </div>
              </template>

              <!-- Overflow link -->
              <button
                v-if="dayEntries(cell.iso).length > MAX_VISIBLE_ENTRIES"
                type="button"
                class="text-xs text-primary-600 dark:text-primary-400 hover:underline text-left px-1.5 py-0.5"
                @click.stop="openAddModal(cell.iso)"
              >
                + Toevoegen...
              </button>
            </div>

            <!-- Hover add button -->
            <div
              v-if="cell.inMonth && hoveredIso === cell.iso"
              class="absolute inset-0 flex items-center justify-center pointer-events-none"
            >
              <div class="pointer-events-auto flex flex-col items-center gap-1">
                <div class="bg-surface-900 dark:bg-surface-100 text-white dark:text-surface-900 text-xs font-medium px-2 py-1 rounded-md shadow-md whitespace-nowrap">
                  Uren toevoegen
                </div>
                <button
                  type="button"
                  class="w-8 h-8 bg-primary-600 hover:bg-primary-700 text-white rounded-full flex items-center justify-center shadow-lg transition-colors"
                  @click.stop="openAddModal(cell.iso)"
                >
                  <i class="pi pi-plus text-xs" />
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- ── Add Hours Modal ─────────────────────────────────────────────── -->
    <AddHoursModal
      :visible="showModal"
      :initial-date="modalDate"
      :registry="registry"
      @update:visible="showModal = $event"
      @saved="onSaved"
    />
  </div>
</template>
