"use client"

import { useMutation, useQueryClient } from "@tanstack/react-query"
import { apiClient } from "@/lib/api/client"
import { formatICSDateOnly, formatICSDateTimeUTC } from "@/lib/agenda/agenda-date"
import type { AgendaApiEvent, AgendaEventDraft } from "@/lib/agenda/agenda-types"
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"

function uidFromEventPath(path?: string): string | undefined {
  if (!path) return undefined
  const match = /\/([^/]+)\.ics$/i.exec(path.trim())
  return match?.[1]
}

function eventApiPath(davPath: string): string {
  return `/calendar/events/${davPath.replace(/^\/+/, "")}`
}

/** Convertit un brouillon UI en payload API (dates ICS). */
export function draftToApiEvent(
  draft: AgendaEventDraft,
  existing?: AgendaApiEvent,
  opts?: { uid?: string; meetUrl?: string | null },
): Partial<AgendaApiEvent> {
  const start = draft.allDay
    ? formatICSDateOnly(draft.start)
    : formatICSDateTimeUTC(draft.start)
  const end = draft.allDay
    ? formatICSDateOnly(draft.end)
    : formatICSDateTimeUTC(draft.end)
  let meet_url = existing?.meet_url ?? ""
  if (opts?.meetUrl !== undefined) {
    meet_url = opts.meetUrl ?? ""
  }
  return {
    uid: opts?.uid ?? existing?.uid ?? uidFromEventPath(existing?.path),
    summary: draft.title.trim() || "(Sans titre)",
    description: draft.description ?? existing?.description ?? "",
    location: draft.location ?? existing?.location ?? "",
    start,
    end,
    all_day: draft.allDay,
    attendees: draft.attendees ?? existing?.attendees ?? [],
    organizer: existing?.organizer,
    meet_url,
    color: draft.color ?? existing?.color,
    rrule: draft.rrule ?? existing?.rrule ?? "",
    exdates: existing?.exdates,
  }
}

function useInvalidateAgenda() {
  const queryClient = useQueryClient()
  const isDemoAgenda = useIsDemoAgenda()
  return () => {
    if (isDemoAgenda) {
      useDemoAgendaStore.getState().bump()
      void queryClient.invalidateQueries({ queryKey: DEMO_AGENDA_QUERY_ROOT })
      return
    }
    void queryClient.invalidateQueries({ queryKey: ["agenda", "events"] })
  }
}

export function useCreateAgendaEvent() {
  const invalidate = useInvalidateAgenda()
  const isDemoAgenda = useIsDemoAgenda()
  return useMutation({
    mutationFn: async ({
      calendarId,
      event,
    }: {
      calendarId: string
      event: Partial<AgendaApiEvent>
    }) => {
      if (isDemoAgenda) {
        const uid = event.uid ?? `demo-event-${crypto.randomUUID().slice(0, 8)}`
        useDemoAgendaStore.getState().upsertEvent(calendarId, {
          ...event,
          uid,
        } as AgendaApiEvent)
        return
      }
      return apiClient.post(`/calendar/${encodeURIComponent(calendarId)}/events`, event)
    },
    onSuccess: invalidate,
  })
}

export function useUpdateAgendaEvent() {
  const invalidate = useInvalidateAgenda()
  const isDemoAgenda = useIsDemoAgenda()
  return useMutation({
    mutationFn: async ({
      path,
      etag,
      event,
    }: {
      path: string
      etag: string
      event: Partial<AgendaApiEvent>
    }) => {
      if (isDemoAgenda) {
        const calendarId = path.match(/\/calendars\/([^/]+)\//)?.[1] ?? "personal"
        useDemoAgendaStore.getState().upsertEvent(calendarId, {
          ...event,
          path,
          etag: etag || `"demo-${event.uid ?? path}"`,
        } as AgendaApiEvent)
        return { etag: `"demo-v2"` }
      }
      return apiClient.put<{ etag: string }>(eventApiPath(path), event, {
        "If-Match": etag || "*",
      })
    },
    onSuccess: invalidate,
  })
}

export function useDeleteAgendaEvent() {
  const invalidate = useInvalidateAgenda()
  const isDemoAgenda = useIsDemoAgenda()
  return useMutation({
    mutationFn: async ({ path }: { path: string }) => {
      if (isDemoAgenda) {
        useDemoAgendaStore.getState().deleteEvent(path)
        return
      }
      return apiClient.delete(eventApiPath(path))
    },
    onSuccess: invalidate,
  })
}

export function useRespondAgendaInvitation() {
  const invalidate = useInvalidateAgenda()
  return useMutation({
    mutationFn: ({
      path,
      response,
      etag,
    }: {
      path: string
      response: "accepted" | "declined" | "tentative"
      etag?: string
    }) =>
      apiClient.post<{ etag: string }>(
        `/calendar/events/response/${path.replace(/^\/+/, "")}`,
        { response, if_match: etag ?? "" },
      ),
    onSuccess: invalidate,
  })
}

export function useCreateAgendaMeetLink() {
  const invalidate = useInvalidateAgenda()
  const isDemoAgenda = useIsDemoAgenda()
  return useMutation({
    mutationFn: async ({ path, etag }: { path: string; etag?: string }) => {
      if (isDemoAgenda) {
        const meetUrl = `https://meet.demo.ulti/${path.split("/").pop()?.replace(".ics", "") ?? "room"}`
        const calendarId = path.match(/\/calendars\/([^/]+)\//)?.[1] ?? "personal"
        useDemoAgendaStore.getState().upsertEvent(calendarId, {
          path,
          etag: etag ?? `"demo-meet"`,
          meet_url: meetUrl,
        } as AgendaApiEvent)
        return { meet_url: meetUrl, etag: `"demo-meet"` }
      }
      return apiClient.post<{ meet_url: string; etag: string }>(
        `/calendar/events/meet-link/${path.replace(/^\/+/, "")}`,
        { if_match: etag ?? "" },
      )
    },
    onSuccess: invalidate,
  })
}

export function useCreateAgendaCalendar() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: (input: { display_name: string; color?: string }) =>
      apiClient.post<{ id: string }>("/calendar", input),
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ["agenda", "calendars"] })
    },
  })
}

export function useUpdateAgendaCalendar() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: ({
      id,
      ...input
    }: {
      id: string
      display_name?: string
      color?: string
    }) => apiClient.patch(`/calendar/${encodeURIComponent(id)}`, input),
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ["agenda"] })
    },
  })
}

export function useDeleteAgendaCalendar() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: ({ id }: { id: string }) =>
      apiClient.delete(`/calendar/${encodeURIComponent(id)}`),
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ["agenda"] })
    },
  })
}
