"use client"

import { useMemo } from "react"
import { useQueries } from "@tanstack/react-query"
import { format } from "date-fns"
import { expandApiEvents } from "@/lib/agenda/agenda-events"
import { parseIcsFeed } from "@/lib/agenda/agenda-ical-parser"
import type { AgendaEvent } from "@/lib/agenda/agenda-types"
import type { AgendaExternalCalendar as ExternalCalendarConfig } from "@/lib/agenda/agenda-settings-types"
import { externalCalendarToAgendaCalendar } from "@/lib/agenda/agenda-calendar-visibility"

export function externalIcsQueryKey(calendarId: string, from: string, to: string) {
  return ["agenda", "external-ics", calendarId, from, to] as const
}

async function fetchExternalIcs(url: string): Promise<string> {
  const res = await fetch(`/api/agenda/ical?url=${encodeURIComponent(url)}`)
  if (!res.ok) {
    throw new Error("Impossible de charger le calendrier externe")
  }
  return res.text()
}

export function useExternalAgendaEvents(
  externalCalendars: ExternalCalendarConfig[],
  rangeStart: Date,
  rangeEnd: Date,
) {
  const from = format(rangeStart, "yyyy-MM-dd")
  const to = format(rangeEnd, "yyyy-MM-dd")

  const results = useQueries({
    queries: externalCalendars.map((cal) => ({
      queryKey: externalIcsQueryKey(cal.id, from, to),
      staleTime: 5 * 60_000,
      queryFn: async () => {
        const raw = await fetchExternalIcs(cal.url)
        return parseIcsFeed(raw)
      },
    })),
  })

  const isLoading = results.some((r) => r.isLoading)
  const isError = results.some((r) => r.isError)

  const rangeStartMs = rangeStart.getTime()
  const rangeEndMs = rangeEnd.getTime()

  const resultsFingerprint = useMemo(
    () =>
      externalCalendars
        .map((cal, i) => {
          const r = results[i]
          return `${cal.id}:${r?.dataUpdatedAt ?? 0}:${r?.fetchStatus ?? "idle"}`
        })
        .join("|"),
    [externalCalendars, results],
  )

  const events: AgendaEvent[] = useMemo(() => {
    const all: AgendaEvent[] = []
    externalCalendars.forEach((config, i) => {
      const data = results[i]?.data
      if (!data) return
      const calendar = externalCalendarToAgendaCalendar(config)
      all.push(...expandApiEvents(calendar, data, rangeStart, rangeEnd))
    })
    return all.sort((a, b) => a.start.getTime() - b.start.getTime())
  }, [externalCalendars, results, rangeStartMs, rangeEndMs, resultsFingerprint])

  return { events, isLoading, isError }
}
