<script lang="ts">
  import { onMount } from "svelte";
  import { Button } from "$lib/components/ui/button/index.js";
  import { Spinner } from "$lib/components/ui/spinner/index.js";
  import * as Card from "$lib/components/ui/card/index.js";
  import ThemePlus from "$lib/components/ThemePlus.svelte";
  import IncidentItem from "$lib/components/IncidentItem.svelte";
  import MaintenanceItem from "$lib/components/MaintenanceItem.svelte";
  import ArrowLeft from "@lucide/svelte/icons/arrow-left";
  import ArrowRight from "@lucide/svelte/icons/arrow-right";
  import Check from "@lucide/svelte/icons/check";
  import ICONS from "$lib/icons";
  import { t } from "$lib/stores/i18n";
  import { formatDate } from "$lib/stores/datetime";
  import { resolve } from "$app/paths";
  import clientResolver, { absoluteResolve } from "$lib/client/resolver.js";
  import { format, parse, addMonths, subMonths, getUnixTime, startOfDay, formatDistanceStrict } from "date-fns";
  import { page } from "$app/state";
  import type { IncidentForMonitorListWithComments, MaintenanceEventsMonitorList } from "$lib/server/types/db";

  let { data } = $props();

  const pagePath = $derived(!!page.params.page_path ? `/${page.params.page_path}` : "");

  const MIN_YEAR = 2023;

  // State
  let loading = $state(true);
  let incidents = $state<IncidentForMonitorListWithComments[]>([]);
  let maintenances = $state<MaintenanceEventsMonitorList[]>([]);

  // Parse the current month from params (derived from reactive data)
  const parsedDate = $derived(parse(data.monthParam, "MMMM-yyyy", new Date()));
  const currentMonth = $derived(format(parsedDate, "MMMM yyyy"));

  // Navigation (derived from reactive parsedDate)
  const prevMonth = $derived(subMonths(parsedDate, 1));
  const nextMonth = $derived(addMonths(parsedDate, 1));
  const prevMonthPath = $derived(format(prevMonth, "MMMM-yyyy"));
  const nextMonthPath = $derived(format(nextMonth, "MMMM-yyyy"));

  // Determine if navigation buttons should show
  const currentDate = new Date();
  const maxDate = addMonths(currentDate, 12);
  const minDate = new Date(MIN_YEAR, 0, 1);
  const showPrevButton = $derived(prevMonth >= minDate);
  const showNextButton = $derived(nextMonth <= maxDate);

  // Counts
  let numberOfIncidents = $derived(incidents.length);
  let numberOfMaintenances = $derived(maintenances.length);

  // Unified event type for display
  interface DisplayEvent {
    id: number;
    title: string;
    description?: string | null;
    start_date_time: number;
    end_date_time: number | null;
    type: "incident" | "maintenance";
    incident?: IncidentForMonitorListWithComments;
    maintenance?: MaintenanceEventsMonitorList;
    monitors?: Array<{
      monitor_tag: string;
      monitor_impact: string;
      monitor_name: string;
      monitor_image: string | null;
    }>;
  }

  // Group events by day
  interface DayEvents {
    date: number; // Unix timestamp of start of day
    events: DisplayEvent[];
  }

  let eventsByDay = $derived.by(() => {
    const allEvents: DisplayEvent[] = [];

    // Add incidents
    for (const incident of incidents) {
      allEvents.push({
        id: incident.id,
        title: incident.title,
        start_date_time: incident.start_date_time,
        end_date_time: incident.end_date_time,
        type: "incident",
        incident,
        monitors: incident.monitors
      });
    }

    // Add maintenances
    for (const maintenance of maintenances) {
      allEvents.push({
        id: maintenance.id,
        title: maintenance.title,
        description: maintenance.description,
        start_date_time: maintenance.start_date_time,
        end_date_time: maintenance.end_date_time,
        type: "maintenance",
        maintenance,
        monitors: maintenance.monitors
      });
    }

    // Group by day
    const dayMap = new Map<number, DisplayEvent[]>();
    for (const event of allEvents) {
      const dayStart = getUnixTime(startOfDay(new Date(event.start_date_time * 1000)));
      if (!dayMap.has(dayStart)) {
        dayMap.set(dayStart, []);
      }
      dayMap.get(dayStart)!.push(event);
    }

    // Sort days descending (newest first)
    const sortedDays = Array.from(dayMap.keys()).sort((a, b) => b - a);

    const result: DayEvents[] = sortedDays.map((dayTs) => ({
      date: dayTs,
      events: dayMap.get(dayTs)!.sort((a, b) => b.start_date_time - a.start_date_time)
    }));

    return result;
  });

  async function fetchEvents() {
    loading = true;
    try {
      const response = await fetch(
        clientResolver(resolve, "/dashboard-apis/events-by-month") + `?page_path=${page.params.page_path}`,
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            start_ts: data.monthStartTs,
            end_ts: data.monthEndTs
          })
        }
      );

      if (response.ok) {
        const result = await response.json();
        incidents = result.incidents || [];
        maintenances = result.maintenances || [];
      }
    } catch (e) {
      console.error("Failed to fetch events:", e);
    } finally {
      loading = false;
    }
  }

  onMount(() => {
    fetchEvents();
  });
</script>

<svelte:head>
  <title>{currentMonth} - Maintenances & Incidents - {data.siteName}</title>
  <meta name="description" content={`${currentMonth} maintenances and incidents for ${data.siteName}`} />
  <meta property="og:title" content={`${currentMonth} - Maintenances & Incidents - ${data.siteName}`} />
  <meta property="og:description" content={`${currentMonth} maintenances and incidents for ${data.siteName}`} />
  <meta property="og:type" content="website" />
  <meta name="twitter:card" content="summary_large_image" />
  {#if data.socialPreviewImage}
    <meta property="og:image" content={absoluteResolve(resolve, data.siteUrl, data.socialPreviewImage)} />
    <meta name="twitter:image" content={absoluteResolve(resolve, data.siteUrl, data.socialPreviewImage)} />
  {/if}
</svelte:head>

<div class="flex flex-col gap-3">
  <!-- Header with back button -->

  <ThemePlus />

  <div class="flex flex-col gap-4 sm:flex-row">
    <div class="flex flex-row justify-start gap-y-3 rounded-3xl border p-4">
      <div class="flex flex-1 flex-row items-center justify-center gap-4">
        <div class="flex w-full flex-row items-center justify-between gap-4">
          <Button
            rel="external"
            variant="outline"
            class="size-8 rounded-full p-0 shadow-none"
            href={clientResolver(resolve, `${pagePath}/events/${prevMonthPath}`)}
          >
            <ICONS.CHEVRON_LEFT class="size-5" />
          </Button>
          <p class="text-2xl">{$formatDate(parsedDate, "MMMM yyyy")}</p>
          <Button
            rel="external"
            href={clientResolver(resolve, `${pagePath}/events/${nextMonthPath}`)}
            variant="outline"
            class="size-8 rounded-full p-0 shadow-none"
          >
            <ICONS.CHEVRON_RIGHT class="size-5" />
          </Button>
        </div>
      </div>
    </div>

    <div class="flex flex-1 flex-col justify-around gap-y-4 rounded-3xl border p-4">
      <div class="flex flex-wrap gap-x-3">
        <!-- Incidents in this page -->
        <div class="flex flex-1 flex-row items-center gap-2">
          {#if numberOfIncidents === 0}
            <Check class="text-up" />
          {:else}
            <p class="text-3xl">
              {numberOfIncidents}
            </p>
          {/if}
          <p class="text-sm leading-4 font-medium">
            {$t("Total Incidents")}
          </p>
        </div>
        <!-- Maintenances in this page -->
        <div class="flex flex-1 flex-row items-center gap-2">
          {#if numberOfMaintenances === 0}
            <Check class="text-up" />
          {:else}
            <p class="text-3xl">
              {numberOfMaintenances}
            </p>
          {/if}
          <p class="text-sm leading-4 font-medium">{$t("Total Maintenances")}</p>
        </div>
      </div>
    </div>
  </div>

  <!-- Loading State -->
  {#if loading}
    <div class="flex items-center justify-center py-12">
      <Spinner class="size-8" />
    </div>
  {:else if eventsByDay.length === 0}
    <!-- No Events -->
    <Card.Root class="rounded-3xl border bg-transparent shadow-none">
      <Card.Content class=" py-12 text-center">
        <div class="mx-auto mb-4 text-4xl">🎉</div>
        <h2 class="text-xl font-semibold">
          {$t("No Events in %currentMonth", { currentMonth })}
        </h2>
        <p class="text-muted-foreground mt-2">
          {$t("There are no incidents or maintenances scheduled for this month.")}
        </p>
      </Card.Content>
    </Card.Root>
  {:else}
    <!-- Events grouped by day -->
    {#each eventsByDay as day}
      <div class="flex flex-col gap-2">
        <div class="bg-secondary mt-4 w-fit rounded-3xl border px-4 py-2 text-xs font-medium">
          {$formatDate(day.date, page.data.dateAndTimeFormat.dateOnly)}
        </div>
        <div class="flex flex-col gap-2">
          {#each day.events as event}
            <div class="flex flex-col gap-2 rounded-3xl border p-4">
              {#if event.type === "incident" && event.incident}
                <IncidentItem incident={event.incident} />
              {:else if event.maintenance}
                <!-- Maintenance -->
                <MaintenanceItem maintenance={event.maintenance} />
              {/if}
            </div>
          {/each}
        </div>
      </div>
    {/each}
  {/if}

  <!-- Navigation buttons -->
  <div class="flex justify-between">
    {#if showPrevButton}
      <Button
        variant="outline"
        rel="external"
        class="rounded-full shadow-none"
        href={clientResolver(resolve, `${pagePath}/events/${prevMonthPath}`)}
      >
        <ArrowLeft class="h-4 w-4" />
        {$formatDate(prevMonth, "MMMM yyyy")}
      </Button>
    {:else}
      <div></div>
    {/if}
    {#if showNextButton}
      <Button
        variant="outline"
        rel="external"
        class="rounded-full shadow-none"
        href={clientResolver(resolve, `${pagePath}/events/${nextMonthPath}`)}
      >
        {$formatDate(nextMonth, "MMMM yyyy")}
        <ArrowRight class="h-4 w-4" />
      </Button>
    {:else}
      <div></div>
    {/if}
  </div>
</div>
