"use client";

import { useQueryState, parseAsStringLiteral, parseAsString } from "nuqs";
import { EventItem } from "./EventItem";
import { EventFilter } from "./EventFilter";
import {
  EventFragment,
  EventCategory,
  SingularEvent,
  getSingularEvents,
  organizeEventsByDate,
} from "@/lib/event";
import { isTodayOrFuture } from "@/lib/date";
import styles from "./eventContainer.module.scss";
import { formatDate, formatYearMonth } from "@/lib/date";
import { parse } from "date-fns";

/*
  TODO: canonical / alternate URLs https://github.com/47ng/nuqs?tab=readme-ov-file#seo
*/

export const EventContainer = ({
  events,
  eventCategories,
}: {
  events: EventFragment[];
  eventCategories: EventCategory[];
}) => {
  const [mode, setMode] = useQueryState(
    "mode",
    parseAsStringLiteral(["list", "calendar"]).withDefault("list")
  );

  const filterableCategories = eventCategories.filter((x) => x.showInFilters);
  const [category, setCategory] = useQueryState("category", parseAsString);

  const filteredEvents = events.filter(
    (x) =>
      !category ||
      x.categories.map((eventCategory) => eventCategory.slug).includes(category)
  );

  return (
    <div className={styles.events}>
      <EventFilter
        eventCategories={filterableCategories}
        setCategory={setCategory}
        activeCategory={category}
      />
      <div className={styles.eventWrapper}>
        <div className={styles.displayOptions}>
          <button onClick={() => setMode(null)}>Vis liste</button>
          <button onClick={() => setMode("calendar")}>Vis kalender</button>
        </div>
        {mode === "list" && <EventList events={filteredEvents} />}
        {mode === "calendar" && <EventCalendar events={filteredEvents} />}
      </div>
    </div>
  );
};

const EventList = ({ events }: { events: EventFragment[] }) => {
  return (
    <ul className={styles.eventList}>
      {events.map((event) => (
        <EventItem key={event.id} event={event} mode="list" />
      ))}
    </ul>
  );
};

const CalendarDay = ({
  day,
  events,
}: {
  day: string;
  events: SingularEvent[];
}) => (
  <div
    className={`${styles.calendarDay} ${events.length === 0 && styles.empty}`}
  >
    <h3>{formatDate(parse(day, "yyyy-MM-dd", new Date()), "eeee dd.MM.")}</h3>
    <ul>
      {events.map((event) => (
        <EventItem key={event.id} event={event} mode="calendar" size="small" />
      ))}
    </ul>
  </div>
);

const EventCalendar = ({ events }: { events: EventFragment[] }) => {
  const futureSingularEvents = getSingularEvents(events).filter(
    (x) => x.occurrence?.start && isTodayOrFuture(x.occurrence.start)
  );

  const eventsByDate = organizeEventsByDate(futureSingularEvents);

  return (
    <div className={styles.eventCalendar}>
      {Object.keys(eventsByDate).map((yearMonth) => (
        <div key={yearMonth} className={styles.calendarYearMonth}>
          <h2>{formatYearMonth(yearMonth)}</h2>
          {Object.keys(eventsByDate[yearMonth]).map((week) => (
            <div key={week} className={styles.calendarWeek}>
              {Object.keys(eventsByDate[yearMonth][week]).map((day) => (
                <CalendarDay
                  key={day}
                  day={day}
                  events={eventsByDate[yearMonth][week][day]}
                />
              ))}
            </div>
          ))}
        </div>
      ))}
    </div>
  );
};
