"use client"

import { useEffect, useMemo, useState } from "react"
import { addDays, addHours, format, parse } from "date-fns"
import { toast } from "sonner"
import { Icon } from "@iconify/react"
import {
  AlignLeft,
  CalendarDays,
  Clock,
  MapPin,
  Repeat,
  Trash2,
  Users,
} from "lucide-react"
import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { Switch } from "@/components/ui/switch"
import { Textarea } from "@/components/ui/textarea"
import { AgendaGuestPicker } from "@/components/agenda/agenda-guest-picker"
import {
  draftToApiEvent,
  useCreateAgendaEvent,
  useCreateAgendaMeetLink,
  useDeleteAgendaEvent,
  useUpdateAgendaEvent,
} from "@/lib/api/hooks/use-calendar-mutations"
import { AGENDA_COLOR_PALETTE } from "@/lib/agenda/agenda-colors"
import { calendarColor } from "@/lib/agenda/agenda-events"
import {
  describeRRule,
  recurrenceOptionsFor,
} from "@/lib/agenda/agenda-recurrence"
import type {
  AgendaCalendar,
  AgendaEvent,
  AgendaEventAttendee,
  AgendaEventDraft,
} from "@/lib/agenda/agenda-types"
import { cn } from "@/lib/utils"

export interface AgendaEventDialogState {
  mode: "create" | "edit"
  draft: AgendaEventDraft
  /** Présent en édition. */
  event?: AgendaEvent
}

function toDateInput(d: Date): string {
  return format(d, "yyyy-MM-dd")
}

function toTimeInput(d: Date): string {
  return format(d, "HH:mm")
}

function fromInputs(date: string, time: string): Date | null {
  const parsed = parse(`${date} ${time}`, "yyyy-MM-dd HH:mm", new Date())
  return Number.isNaN(parsed.getTime()) ? null : parsed
}

export function AgendaEventDialog({
  state,
  onClose,
  calendars,
  userEmail,
}: {
  state: AgendaEventDialogState | null
  onClose: () => void
  calendars: AgendaCalendar[]
  userEmail?: string
}) {
  const createMutation = useCreateAgendaEvent()
  const updateMutation = useUpdateAgendaEvent()
  const deleteMutation = useDeleteAgendaEvent()
  const meetLinkMutation = useCreateAgendaMeetLink()

  const [title, setTitle] = useState("")
  const [allDay, setAllDay] = useState(false)
  const [startDate, setStartDate] = useState("")
  const [startTime, setStartTime] = useState("09:00")
  const [endDate, setEndDate] = useState("")
  const [endTime, setEndTime] = useState("10:00")
  const [calendarId, setCalendarId] = useState("")
  const [rrule, setRRule] = useState("")
  const [color, setColor] = useState("")
  const [location, setLocation] = useState("")
  const [description, setDescription] = useState("")
  const [attendees, setAttendees] = useState<AgendaEventAttendee[]>([])

  const open = state !== null
  const isEdit = state?.mode === "edit"

  useEffect(() => {
    if (!state) return
    const d = state.draft
    setTitle(d.title)
    setAllDay(d.allDay)
    setStartDate(toDateInput(d.start))
    setStartTime(toTimeInput(d.start))
    // ICS : fin exclusive pour les journées entières → réaffiche la date incluse.
    const displayEnd = d.allDay ? addDays(d.end, -1) : d.end
    setEndDate(toDateInput(displayEnd < d.start ? d.start : displayEnd))
    setEndTime(toTimeInput(d.end))
    setCalendarId(d.calendarId || calendars[0]?.id || "")
    setRRule(d.rrule ?? "")
    setColor(d.color ?? "")
    setLocation(d.location ?? "")
    setDescription(d.description ?? "")
    setAttendees(d.attendees ?? [])
  }, [state, calendars])

  const recurrenceOptions = useMemo(() => {
    const start = fromInputs(startDate, startTime) ?? new Date()
    const options = recurrenceOptionsFor(start)
    if (rrule && !options.some((o) => o.value === rrule)) {
      options.push({ value: rrule, label: describeRRule(rrule) })
    }
    return options
  }, [startDate, startTime, rrule])

  const pending =
    createMutation.isPending || updateMutation.isPending || deleteMutation.isPending

  const buildDraft = (): AgendaEventDraft | null => {
    const start = fromInputs(startDate, allDay ? "00:00" : startTime)
    if (!start) return null
    let end = fromInputs(endDate, allDay ? "00:00" : endTime)
    if (!end) return null
    if (allDay) {
      // Fin exclusive : jour affiché inclus + 1.
      end = addDays(end, 1)
      if (end <= start) end = addDays(start, 1)
    } else if (end <= start) {
      end = addHours(start, 1)
    }
    return {
      title,
      start,
      end,
      allDay,
      calendarId,
      description,
      location,
      attendees,
      rrule,
      color: color || undefined,
    }
  }

  const submit = async () => {
    const draft = buildDraft()
    if (!draft || !calendarId) return
    try {
      if (isEdit && state?.event) {
        await updateMutation.mutateAsync({
          path: state.event.path,
          etag: state.event.etag,
          event: draftToApiEvent(draft, state.event.master),
        })
        toast.success("Événement mis à jour")
      } else {
        const apiEvent = draftToApiEvent(draft)
        if (userEmail) apiEvent.organizer = userEmail
        await createMutation.mutateAsync({ calendarId, event: apiEvent })
        toast.success("Événement créé")
      }
      onClose()
    } catch {
      toast.error("Impossible d'enregistrer l'événement")
    }
  }

  const remove = async () => {
    if (!state?.event) return
    try {
      await deleteMutation.mutateAsync({ path: state.event.path })
      toast.success("Événement supprimé")
      onClose()
    } catch {
      toast.error("Impossible de supprimer l'événement")
    }
  }

  const addMeetLink = async () => {
    if (!state?.event) return
    try {
      const res = await meetLinkMutation.mutateAsync({
        path: state.event.path,
        etag: state.event.etag,
      })
      toast.success("Visio UltiMeet ajoutée")
      window.open(res.meet_url, "_blank", "noopener")
      onClose()
    } catch {
      toast.error("Impossible de créer le lien UltiMeet")
    }
  }

  const meetUrl = state?.event?.meetUrl

  return (
    <Dialog
      open={open}
      onOpenChange={(o) => {
        if (!o) onClose()
      }}
    >
      <DialogContent className="flex max-h-[90vh] flex-col gap-0 overflow-hidden p-0 sm:max-w-xl">
        <DialogHeader className="border-b border-border/60 px-5 py-3">
          <DialogTitle className="text-base font-medium">
            {isEdit ? "Modifier l'événement" : "Nouvel événement"}
          </DialogTitle>
        </DialogHeader>

        <div className="flex flex-1 flex-col gap-4 overflow-y-auto px-5 py-4">
          <Input
            value={title}
            autoFocus={!isEdit}
            onChange={(e) => setTitle(e.target.value)}
            placeholder="Ajouter un titre"
            className="h-11 border-0 border-b-2 border-border/60 !bg-transparent px-1 !text-xl shadow-none rounded-none focus-visible:border-primary focus-visible:ring-0"
          />

          {/* Dates */}
          <div className="flex flex-col gap-2">
            <div className="flex items-start gap-3">
              <Clock className="mt-2 size-5 shrink-0 text-muted-foreground" />
              <div className="flex min-w-0 flex-1 flex-col gap-2">
                <div className="flex flex-wrap items-center gap-1.5">
                  <Input
                    type="date"
                    value={startDate}
                    onChange={(e) => {
                      setStartDate(e.target.value)
                      if (e.target.value > endDate) setEndDate(e.target.value)
                    }}
                    className="h-9 w-fit"
                  />
                  {!allDay && (
                    <Input
                      type="time"
                      value={startTime}
                      onChange={(e) => setStartTime(e.target.value)}
                      className="h-9 w-fit"
                    />
                  )}
                  <span className="px-0.5 text-muted-foreground">–</span>
                  {!allDay && (
                    <Input
                      type="time"
                      value={endTime}
                      onChange={(e) => setEndTime(e.target.value)}
                      className="h-9 w-fit"
                    />
                  )}
                  <Input
                    type="date"
                    value={endDate}
                    min={startDate}
                    onChange={(e) => setEndDate(e.target.value)}
                    className="h-9 w-fit"
                  />
                </div>
                <label className="flex w-fit cursor-pointer items-center gap-2 text-sm text-foreground/80">
                  <Switch checked={allDay} onCheckedChange={setAllDay} />
                  Toute la journée
                </label>
              </div>
            </div>

            <div className="flex items-center gap-3">
              <Repeat className="size-5 shrink-0 text-muted-foreground" />
              <Select value={rrule || "none"} onValueChange={(v) => setRRule(v === "none" ? "" : v)}>
                <SelectTrigger className="h-9 w-fit min-w-52 border-0 bg-muted/60 shadow-none">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {recurrenceOptions.map((o) => (
                    <SelectItem key={o.value || "none"} value={o.value || "none"}>
                      {o.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          {/* Invités */}
          <div className="flex items-start gap-3">
            <Users className="mt-2 size-5 shrink-0 text-muted-foreground" />
            <div className="min-w-0 flex-1">
              <AgendaGuestPicker
                attendees={attendees}
                onChange={setAttendees}
                organizerEmail={userEmail}
              />
            </div>
          </div>

          {/* Visio */}
          <div className="flex items-center gap-3">
            <Icon
              icon="simple-icons:jitsi"
              className="size-5 shrink-0 text-muted-foreground"
              aria-hidden
            />
            {meetUrl ? (
              <Button asChild className="h-9 rounded-full">
                <a href={meetUrl} target="_blank" rel="noopener noreferrer">
                  Rejoindre la visio UltiMeet
                </a>
              </Button>
            ) : isEdit ? (
              <Button
                variant="outline"
                className="h-9 rounded-full"
                disabled={meetLinkMutation.isPending}
                onClick={() => void addMeetLink()}
              >
                Ajouter une visio UltiMeet
              </Button>
            ) : (
              <span className="text-sm text-muted-foreground">
                La visio peut être ajoutée après création
              </span>
            )}
          </div>

          {/* Lieu */}
          <div className="flex items-center gap-3">
            <MapPin className="size-5 shrink-0 text-muted-foreground" />
            <Input
              value={location}
              onChange={(e) => setLocation(e.target.value)}
              placeholder="Ajouter un lieu"
              className="h-9 flex-1"
            />
          </div>

          {/* Description */}
          <div className="flex items-start gap-3">
            <AlignLeft className="mt-2 size-5 shrink-0 text-muted-foreground" />
            <Textarea
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="Ajouter une description"
              className="min-h-20 flex-1"
            />
          </div>

          {/* Agenda + couleur */}
          <div className="flex flex-wrap items-center gap-3">
            <CalendarDays className="size-5 shrink-0 text-muted-foreground" />
            <Select
              value={calendarId}
              onValueChange={setCalendarId}
              disabled={isEdit}
            >
              <SelectTrigger className="h-9 w-fit min-w-40 border-0 bg-muted/60 shadow-none">
                <SelectValue placeholder="Agenda" />
              </SelectTrigger>
              <SelectContent>
                {calendars.map((cal) => (
                  <SelectItem key={cal.id} value={cal.id}>
                    <span className="flex items-center gap-2">
                      <span
                        className="size-3 rounded-full"
                        style={{ backgroundColor: calendarColor(cal) }}
                      />
                      {cal.display_name}
                    </span>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <div className="flex items-center gap-1.5">
              {AGENDA_COLOR_PALETTE.slice(0, 8).map((c) => (
                <button
                  key={c.value}
                  type="button"
                  title={c.label}
                  aria-label={`Couleur ${c.label}`}
                  onClick={() => setColor(color === c.value ? "" : c.value)}
                  className={cn(
                    "size-5 rounded-full transition-transform hover:scale-110",
                    color === c.value &&
                      "ring-2 ring-foreground/60 ring-offset-1 ring-offset-background",
                  )}
                  style={{ backgroundColor: c.value }}
                />
              ))}
            </div>
          </div>
        </div>

        <DialogFooter className="flex-row items-center border-t border-border/60 px-5 py-3">
          {isEdit && (
            <Button
              variant="ghost"
              className="mr-auto gap-2 text-destructive hover:text-destructive"
              disabled={pending}
              onClick={() => void remove()}
            >
              <Trash2 className="size-4" /> Supprimer
            </Button>
          )}
          <Button variant="ghost" onClick={onClose} disabled={pending}>
            Annuler
          </Button>
          <Button
            onClick={() => void submit()}
            disabled={pending || !calendarId || !startDate || !endDate}
            className="rounded-full px-6"
          >
            Enregistrer
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
