<script lang="ts">
  import { Calendar, DayGrid, TimeGrid, Interaction } from "@event-calendar/core";
  import "@event-calendar/core/index.css";
  import "../../styles/calendar.css";

  type CalendarEvent = {
    id: string;
    start: string | Date;
    end: string | Date;
    title: string;
    color?: string;
    allDay?: boolean;
  };

  type EC = {
    prev(): EC;
    next(): EC;
    setOption(name: string, value: unknown): EC;
    getOption(name: string): unknown;
    getView(): { type: string; title: string };
  };

  let loading = $state(false);
  let currentView = $state("dayGridMonth");
  let titleText = $state("");
  let cal = $state<EC | null>(null);
  let calBody = $state<HTMLElement | null>(null);

  // Move the all-day strip from inside the sticky header to the bottom of the
  // scrollable ec-main so it appears below the time slots.
  function repositionAllDay() {
    const main = calBody?.querySelector<HTMLElement>('.ec-time-grid .ec-main');
    if (!main) return; // not a time-grid view
    const allDay = main.querySelector<HTMLElement>(':scope > .ec-header > .ec-all-day');
    if (!allDay) return;
    main.appendChild(allDay);
  }

  const views = [
    { id: "dayGridMonth", label: "Month" },
    { id: "timeGridWeek", label: "Week" },
    { id: "timeGridDay", label: "Day" },
  ];

  function goToToday() {
    cal?.setOption("date", new Date());
  }

  function goPrev() {
    cal?.prev();
  }

  function goNext() {
    cal?.next();
  }

  function switchView(viewId: string) {
    cal?.setOption("view", viewId);
  }

  async function loadEvents(start: Date, end: Date): Promise<void> {
    loading = true;
    try {
      const params = new URLSearchParams({
        start: start.toISOString(),
        end: end.toISOString(),
      });
      const res = await fetch(`/calendar/events?${params}`);
      if (!res.ok) return;
      const body = await res.json();
      const entries: Array<Record<string, unknown>> = body?.data ?? [];
      options.events = entries
        .filter((e) => e.startDate && e.endDate)
        .map((e) => ({
          id: e.id as string,
          title: (e.name as string) || "(No title)",
          start: new Date(e.startDate as string),
          end: new Date(e.endDate as string),
          allDay: (e.allDayFlag as boolean) ?? false,
          color:
            ((e.type as Record<string, unknown> | null)?.displayColor as string | undefined) ||
            ((e.status as Record<string, unknown> | null)?.color as string | undefined) ||
            undefined,
        })) satisfies CalendarEvent[];
    } finally {
      loading = false;
    }
  }

  let options = $state({
    view: "dayGridMonth",
    headerToolbar: false,
    editable: false,
    selectable: true,
    nowIndicator: true,
    dayMaxEvents: true,
    slotEventOverlap: false,
    eventTimeFormat: () => '',
    height: "100%",
    events: [] as CalendarEvent[],
    datesSet: (info: { start: Date; end: Date; view: { type: string; title: string } }) => {
      titleText = info.view.title;
      currentView = info.view.type;
      loadEvents(info.start, info.end);
    },
    viewDidMount: () => {
      // viewDidMount fires each time the view component is mounted (on view-type
      // switches). Use setTimeout to let the DOM fully paint first.
      setTimeout(repositionAllDay, 0);
    },
  });
</script>

<svelte:head>
  <title>Calendar — Project Optima</title>
</svelte:head>

<div class="calendar-page">
  <div class="calendar-pane">
    <div class="calendar-header">
      <div class="calendar-header-left">
        <svg
          class="calendar-header-icon"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
        >
          <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
          <line x1="16" y1="2" x2="16" y2="6"></line>
          <line x1="8" y1="2" x2="8" y2="6"></line>
          <line x1="3" y1="10" x2="21" y2="10"></line>
        </svg>
        <h2 class="calendar-title">Calendar</h2>
      </div>

      <div class="calendar-header-controls">
        <div class="calendar-nav">
          <button class="calendar-nav-btn" onclick={goPrev} aria-label="Previous">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
              <polyline points="15 18 9 12 15 6"></polyline>
            </svg>
          </button>
          <button class="calendar-nav-btn calendar-today-btn" onclick={goToToday}>Today</button>
          <button class="calendar-nav-btn" onclick={goNext} aria-label="Next">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
              <polyline points="9 18 15 12 9 6"></polyline>
            </svg>
          </button>
        </div>

        <span class="calendar-range-title">{titleText}</span>

        <div class="calendar-view-switcher">
          {#each views as v}
            <button
              class="calendar-view-btn"
              class:active={currentView === v.id}
              onclick={() => switchView(v.id)}
            >{v.label}</button>
          {/each}
        </div>
      </div>
    </div>

    <div class="calendar-body" bind:this={calBody}>
      <Calendar bind:this={cal} plugins={[DayGrid, TimeGrid, Interaction]} {options} />
    </div>
  </div>
</div>
