"use client"

import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { useParams, useRouter, useSearchParams } from "next/navigation"
import { addDays, addHours, addMonths, startOfHour } from "date-fns"
import { AgendaEventDialog, type AgendaEventDialogState } from "@/components/agenda/agenda-event-dialog"
import { AgendaEventPopover, type AgendaEventPopoverState } from "@/components/agenda/agenda-event-popover"
import type { AnchorRect } from "@/components/agenda/agenda-floating-card"
import { AgendaHeader } from "@/components/agenda/agenda-header"
import { AgendaQuickCreate, type AgendaQuickCreateState } from "@/components/agenda/agenda-quick-create"
import { AgendaSidebar } from "@/components/agenda/agenda-sidebar"
import { AgendaViewMonth } from "@/components/agenda/agenda-view-month"
import { AgendaViewWeek } from "@/components/agenda/agenda-view-week"
import { Skeleton } from "@/components/ui/skeleton"
import { useAgendaCalendars, useAgendaEvents } from "@/lib/api/hooks/use-calendar-queries"
import { parseICSDate, viewDays, viewRange } from "@/lib/agenda/agenda-date"
import { useAgendaSettingsStore } from "@/lib/agenda/agenda-store"
import type { AgendaEvent, AgendaEventDraft } from "@/lib/agenda/agenda-types"
import {
  buildAgendaPath,
  parseAgendaSegments,
  type AgendaView,
} from "@/lib/agenda/agenda-url"
import { useChromeIdentity } from "@/lib/hooks/use-chrome-identity"
import { useIsMobile } from "@/hooks/use-mobile"

export function AgendaPage() {
  const router = useRouter()
  const params = useParams()
  const searchParams = useSearchParams()
  const isMobile = useIsMobile()
  const identity = useChromeIdentity()

  const route = useMemo(
    () => parseAgendaSegments(params.segments as string[] | undefined),
    [params.segments],
  )
  const lastView = useAgendaSettingsStore((s) => s.lastView)
  const setLastView = useAgendaSettingsStore((s) => s.setLastView)
  const hiddenIds = useAgendaSettingsStore((s) => s.hiddenCalendarIds)

  const view: AgendaView = route.view ?? (isMobile ? "day" : lastView)
  const date = route.date

  // Normalise l'URL quand la vue est implicite.
  useEffect(() => {
    if (!route.view) {
      router.replace(buildAgendaPath(view, date) + window.location.search)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [route.view])

  useEffect(() => {
    if (route.view) setLastView(route.view)
  }, [route.view, setLastView])

  const navigate = useCallback(
    (nextView: AgendaView, nextDate: Date) => {
      router.push(buildAgendaPath(nextView, nextDate))
    },
    [router],
  )

  const step = useCallback(
    (delta: 1 | -1) => {
      const next =
        view === "month"
          ? addMonths(date, delta)
          : addDays(date, view === "week" ? delta * 7 : delta)
      navigate(view, next)
    },
    [view, date, navigate],
  )

  // Données
  const { data: calendars = [], isLoading: calendarsLoading } = useAgendaCalendars()
  const visibleCalendars = useMemo(
    () => calendars.filter((c) => !hiddenIds.includes(c.id)),
    [calendars, hiddenIds],
  )
  const fetchRange = useMemo(() => viewRange("month", date), [date])
  const { events } = useAgendaEvents(visibleCalendars, fetchRange.start, fetchRange.end)

  // UI : création rapide / dialog / détails
  const [quickCreate, setQuickCreate] = useState<AgendaQuickCreateState | null>(null)
  const [dialogState, setDialogState] = useState<AgendaEventDialogState | null>(null)
  const [popover, setPopover] = useState<AgendaEventPopoverState | null>(null)

  const defaultCalendarId = visibleCalendars[0]?.id ?? calendars[0]?.id ?? ""
  const userEmail = identity?.email

  const closeOverlays = useCallback(() => {
    setQuickCreate(null)
    setPopover(null)
  }, [])

  const openCreateDialog = useCallback(
    (base?: Partial<AgendaEventDraft>) => {
      closeOverlays()
      const start = base?.start ?? addHours(startOfHour(new Date()), 1)
      const end = base?.end ?? addHours(start, 1)
      setDialogState({
        mode: "create",
        draft: {
          title: "",
          start,
          end,
          allDay: false,
          calendarId: defaultCalendarId,
          ...base,
        },
      })
    },
    [closeOverlays, defaultCalendarId],
  )

  const openEditDialog = useCallback(
    (event: AgendaEvent) => {
      closeOverlays()
      const masterStart = parseICSDate(event.master.start) ?? event.start
      const masterEnd = parseICSDate(event.master.end) ?? event.end
      setDialogState({
        mode: "edit",
        event,
        draft: {
          title: event.title === "(Sans titre)" ? "" : event.title,
          start: masterStart,
          end: masterEnd,
          allDay: event.allDay,
          calendarId: event.calendarId,
          description: event.description,
          location: event.location,
          attendees: event.attendees,
          rrule: event.rrule,
          color: event.master.color,
        },
      })
    },
    [closeOverlays],
  )

  // Interop : /agenda?new=1&guest=…&title=…
  const handledNewParam = useRef(false)
  useEffect(() => {
    if (handledNewParam.current || !route.view) return
    if (searchParams.get("new") !== "1") return
    handledNewParam.current = true
    const guest = searchParams.get("guest")?.trim()
    const guestName = searchParams.get("guest_name")?.trim()
    openCreateDialog({
      title: searchParams.get("title")?.trim() ?? "",
      attendees: guest
        ? [{ email: guest, name: guestName || guest, status: "NEEDS-ACTION" }]
        : [],
    })
    router.replace(buildAgendaPath(view, date))
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchParams, route.view])

  // Raccourcis clavier façon Google Calendar.
  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      const target = e.target as HTMLElement
      if (
        e.metaKey ||
        e.ctrlKey ||
        e.altKey ||
        target.closest("input, textarea, select, [contenteditable], [role=dialog]")
      )
        return
      switch (e.key.toLowerCase()) {
        case "j":
        case "d":
          navigate("day", date)
          break
        case "s":
        case "w":
          navigate("week", date)
          break
        case "m":
          navigate("month", date)
          break
        case "t":
          navigate(view, new Date())
          break
        case "c":
          openCreateDialog()
          break
        default:
          return
      }
      e.preventDefault()
    }
    window.addEventListener("keydown", onKey)
    return () => window.removeEventListener("keydown", onKey)
  }, [navigate, view, date, openCreateDialog])

  const handleEventClick = useCallback((event: AgendaEvent, anchor: AnchorRect) => {
    setQuickCreate(null)
    setPopover({ event, anchor })
  }, [])

  const handleCreateRange = useCallback(
    (start: Date, end: Date, allDay: boolean, anchor: AnchorRect) => {
      setPopover(null)
      setQuickCreate({ start, end, allDay, anchor })
    },
    [],
  )

  const days = useMemo(() => viewDays(view, date), [view, date])

  return (
    <>
      <AgendaHeader
        view={view}
        date={date}
        onToday={() => navigate(view, new Date())}
        onStep={step}
        onViewChange={(v) => navigate(v, date)}
      />
      <div className="flex min-h-0 flex-1">
        <AgendaSidebar
          selectedDate={date}
          onSelectDate={(d) => navigate(view, d)}
          onCreateEvent={() => openCreateDialog()}
        />
        <main className="flex min-w-0 flex-1 flex-col">
          {calendarsLoading ? (
            <div className="flex h-full flex-col gap-3 p-6">
              <Skeleton className="h-8 w-64" />
              <Skeleton className="min-h-0 flex-1" />
            </div>
          ) : view === "month" ? (
            <AgendaViewMonth
              date={date}
              events={events}
              onCreateAt={(day, anchor) =>
                handleCreateRange(day, addDays(day, 1), true, anchor)
              }
              onEventClick={handleEventClick}
              onOpenDay={(day) => navigate("day", day)}
            />
          ) : (
            <AgendaViewWeek
              days={days}
              events={events}
              onCreateRange={handleCreateRange}
              onEventClick={handleEventClick}
              onOpenDay={(day) => navigate("day", day)}
            />
          )}
        </main>
      </div>

      <AgendaQuickCreate
        state={quickCreate}
        calendars={visibleCalendars.length > 0 ? visibleCalendars : calendars}
        defaultCalendarId={defaultCalendarId}
        userEmail={userEmail}
        onClose={() => setQuickCreate(null)}
        onMoreOptions={(draft) => {
          setQuickCreate(null)
          setDialogState({ mode: "create", draft })
        }}
      />

      <AgendaEventPopover
        state={popover}
        calendars={calendars}
        userEmail={userEmail}
        onClose={() => setPopover(null)}
        onEdit={openEditDialog}
      />

      <AgendaEventDialog
        state={dialogState}
        onClose={() => setDialogState(null)}
        calendars={calendars}
        userEmail={userEmail}
      />
    </>
  )
}
