"use client"

import { useMemo } from "react"
import { useQueries, useQuery } from "@tanstack/react-query"
import { format } from "date-fns"
import { apiClient } from "@/lib/api/client"
import { useAuthReady } from "@/lib/api/use-auth-ready"
import { expandApiEvents } from "@/lib/agenda/agenda-events"
import { useIsDemoAgenda } from "@/lib/demo/demo-agenda-context"
import { DEMO_AGENDA_QUERY_ROOT } from "@/lib/demo/demo-agenda-bootstrap"
import { useDemoAgendaStore } from "@/lib/demo/demo-agenda-store"
import type {
  AgendaCalendar,
  AgendaCalendarsResponse,
  AgendaEvent,
  AgendaEventsResponse,
} from "@/lib/agenda/agenda-types"

export const agendaCalendarsKey = ["agenda", "calendars"] as const

export function agendaEventsKey(calendarId: string, from: string, to: string) {
  return ["agenda", "events", calendarId, from, to] as const
}

export function useAgendaCalendars() {
  const { ready, authenticated } = useAuthReady()
  const isDemoAgenda = useIsDemoAgenda()
  const demoVersion = useDemoAgendaStore((s) => s.version)
  return useQuery({
    queryKey: isDemoAgenda
      ? [...DEMO_AGENDA_QUERY_ROOT, "calendars", demoVersion]
      : agendaCalendarsKey,
    enabled: ready && authenticated,
    staleTime: 5 * 60_000,
    queryFn: async () => {
      if (isDemoAgenda) {
        return useDemoAgendaStore.getState().listCalendars()
      }
      const res = await apiClient.get<AgendaCalendarsResponse>("/calendar")
      return res.calendars ?? []
    },
    initialData: isDemoAgenda
      ? () => useDemoAgendaStore.getState().listCalendars()
      : undefined,
  })
}

/**
 * Charge et développe les événements de plusieurs agendas sur une fenêtre.
 * La fenêtre est élargie au mois pour profiter du cache entre vues.
 */
export function useAgendaEvents(
  calendars: AgendaCalendar[],
  rangeStart: Date,
  rangeEnd: Date,
) {
  const { ready, authenticated } = useAuthReady()
  const isDemoAgenda = useIsDemoAgenda()
  const demoVersion = useDemoAgendaStore((s) => s.version)
  const from = format(rangeStart, "yyyy-MM-dd")
  const to = format(rangeEnd, "yyyy-MM-dd")

  const results = useQueries({
    queries: calendars.map((cal) => ({
      queryKey: isDemoAgenda
        ? [...DEMO_AGENDA_QUERY_ROOT, "events", cal.id, from, to, demoVersion]
        : agendaEventsKey(cal.id, from, to),
      enabled: ready && authenticated,
      staleTime: 30_000,
      queryFn: async () => {
        if (isDemoAgenda) {
          return useDemoAgendaStore.getState().listEvents(cal.id, from, to)
        }
        const res = await apiClient.get<AgendaEventsResponse>(
          `/calendar/${encodeURIComponent(cal.id)}/events`,
          { from, to, page_size: "500" },
        )
        return res.events ?? []
      },
      initialData: isDemoAgenda
        ? () => useDemoAgendaStore.getState().listEvents(cal.id, from, to)
        : undefined,
    })),
  })

  const isLoading = results.some((r) => r.isLoading)
  const isError = results.every((r) => r.isError) && results.length > 0

  // Empreinte à taille fixe — ne pas spread `results.map(...)` dans les deps de useMemo
  // (la longueur du tableau de dépendances doit rester constante entre les renders).
  const resultsFingerprint = useMemo(
    () =>
      calendars
        .map((cal, i) => {
          const r = results[i]
          return `${cal.id}:${r?.dataUpdatedAt ?? 0}:${r?.fetchStatus ?? "idle"}`
        })
        .join("|"),
    [calendars, results],
  )

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

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

  return { events, isLoading, isError }
}
