"use client"

import { useMemo, useState } from "react"
import { toast } from "sonner"
import { MoreVertical, Pencil, Plus, Trash2 } from "lucide-react"
import { AgendaCalendarDialog } from "@/components/agenda/agenda-calendar-dialog"
import {
  CalendarViewDialog,
  ExternalCalendarDialog,
} from "@/components/agenda/agenda-calendars-settings"
import { AgendaMiniMonth } from "@/components/agenda/agenda-mini-month"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog"
import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Skeleton } from "@/components/ui/skeleton"
import { useDeleteAgendaCalendar } from "@/lib/api/hooks/use-calendar-mutations"
import { useLabels } from "@/lib/api/hooks/use-folder-label-queries"
import { useMailAccounts } from "@/lib/api/hooks/use-mail-queries"
import { ALL_AGENDAS_VIEW_LABEL, isExternalCalendarId, isReservedAgendaViewName } from "@/lib/agenda/agenda-calendar-visibility"
import { calendarColor } from "@/lib/agenda/agenda-events"
import { useAgendaSettingsStore, useAgendaUIStore } from "@/lib/agenda/agenda-store"
import type { AgendaCalendar } from "@/lib/agenda/agenda-types"
import { useMergedAgendaCalendars } from "@/lib/agenda/use-visible-agenda-calendars"
import { useIsMobile } from "@/hooks/use-mobile"
import { cn } from "@/lib/utils"

export function AgendaSidebar({
  selectedDate,
  onSelectDate,
  onCreateEvent,
}: {
  selectedDate: Date
  onSelectDate: (date: Date) => void
  onCreateEvent: () => void
}) {
  const isMobile = useIsMobile()
  const sidebarCollapsed = useAgendaUIStore((s) => s.sidebarCollapsed)
  const setSidebarCollapsed = useAgendaUIStore((s) => s.setSidebarCollapsed)
  const hiddenIds = useAgendaSettingsStore((s) => s.hiddenCalendarIds)
  const weekStart = useAgendaSettingsStore((s) => s.weekStart)
  const calendarViews = useAgendaSettingsStore((s) => s.calendarViews)
  const activeCalendarViewId = useAgendaSettingsStore((s) => s.activeCalendarViewId)
  const setActiveCalendarViewId = useAgendaSettingsStore((s) => s.setActiveCalendarViewId)
  const toggleCalendar = useAgendaSettingsStore((s) => s.toggleCalendarVisible)
  const { data: accounts = [] } = useMailAccounts()
  const { data: labels = [] } = useLabels()
  const { calendars, isLoading } = useMergedAgendaCalendars()
  const deleteMutation = useDeleteAgendaCalendar()

  const [calendarDialogOpen, setCalendarDialogOpen] = useState(false)
  const [editingCalendar, setEditingCalendar] = useState<AgendaCalendar | null>(null)
  const [deletingCalendar, setDeletingCalendar] = useState<AgendaCalendar | null>(null)
  const [externalDialogOpen, setExternalDialogOpen] = useState(false)
  const [viewDialogOpen, setViewDialogOpen] = useState(false)

  const calendarOptions = useMemo(
    () =>
      (calendars ?? []).map((calendar) => ({
        id: calendar.id,
        label: calendar.display_name,
        color: calendarColor(calendar),
      })),
    [calendars],
  )

  const labelOptions = useMemo(
    () => labels.map((label) => ({ id: label.id, label: label.name })),
    [labels],
  )

  const open = !sidebarCollapsed

  const confirmDelete = async () => {
    if (!deletingCalendar) return
    try {
      await deleteMutation.mutateAsync({ id: deletingCalendar.id })
      toast.success(`Agenda « ${deletingCalendar.display_name} » supprimé`)
    } catch {
      toast.error("Impossible de supprimer cet agenda")
    } finally {
      setDeletingCalendar(null)
    }
  }

  return (
    <>
      <aside
        className={cn(
          "flex h-full w-64 shrink-0 flex-col gap-4 overflow-y-auto bg-app-canvas px-3 pt-3 pb-4",
          isMobile
            ? cn(
                "fixed inset-y-0 left-0 z-50 shadow-xl transition-transform duration-200 ease-linear",
                open ? "translate-x-0" : "-translate-x-full pointer-events-none",
              )
            : cn(!open && "hidden"),
        )}
        aria-hidden={isMobile && !open}
      >
        <Button
          className="h-13 w-fit gap-3 rounded-2xl border border-border/60 bg-card px-5 text-[0.95rem] font-medium text-foreground shadow-md hover:bg-mail-nav-hover hover:shadow-lg"
          variant="ghost"
          onClick={() => {
            onCreateEvent()
            if (isMobile) setSidebarCollapsed(true)
          }}
        >
          <Plus className="size-6 text-primary" />
          Nouvel événement
        </Button>

        <AgendaMiniMonth
          selected={selectedDate}
          weekStart={weekStart}
          onSelect={(d) => {
            onSelectDate(d)
            if (isMobile) setSidebarCollapsed(true)
          }}
        />

        <div className="flex min-h-0 flex-col gap-0.5">
          <div className="flex items-center justify-between pr-1 pl-2">
            <span className="py-1 text-sm font-medium text-foreground/90">Vues</span>
            <Button
              variant="ghost"
              size="icon"
              className="size-7 rounded-full text-muted-foreground"
              aria-label="Créer une vue"
              onClick={() => setViewDialogOpen(true)}
            >
              <Plus className="size-4" />
            </Button>
          </div>
          {calendarViews.length > 0 ? (
            <>
              <button
                type="button"
                onClick={() => setActiveCalendarViewId(null)}
                className={cn(
                  "rounded-lg px-2 py-1 text-left text-sm transition-colors hover:bg-mail-nav-hover",
                  activeCalendarViewId === null
                    ? "bg-mail-nav-selected font-medium text-foreground"
                    : "text-foreground/85",
                )}
              >
                {ALL_AGENDAS_VIEW_LABEL}
              </button>
              {calendarViews
                .filter((view) => !isReservedAgendaViewName(view.name))
                .map((view) => (
                  <button
                    key={view.id}
                    type="button"
                    onClick={() => setActiveCalendarViewId(view.id)}
                    className={cn(
                      "rounded-lg px-2 py-1 text-left text-sm transition-colors hover:bg-mail-nav-hover",
                      activeCalendarViewId === view.id
                        ? "bg-mail-nav-selected font-medium text-foreground"
                        : "text-foreground/85",
                    )}
                  >
                    {view.name}
                  </button>
                ))}
            </>
          ) : null}

          <div className="mt-2 flex items-center justify-between border-t border-border/60 pr-1 pl-2 pt-2">
            <span className="py-0.5 text-sm font-medium text-foreground/90">
              Mes agendas
            </span>
            <Button
              variant="ghost"
              size="icon"
              className="size-7 rounded-full text-muted-foreground"
              aria-label="Créer un agenda"
              onClick={() => {
                setEditingCalendar(null)
                setCalendarDialogOpen(true)
              }}
            >
              <Plus className="size-4" />
            </Button>
          </div>

          {isLoading && (
            <div className="flex flex-col gap-1.5 px-2 py-0.5">
              <Skeleton className="h-5 w-40" />
              <Skeleton className="h-5 w-32" />
            </div>
          )}

          {(calendars ?? []).map((cal) => {
            const color = calendarColor(cal)
            const visible = !hiddenIds.includes(cal.id)
            const isExternal = isExternalCalendarId(cal.id)
            return (
              <div
                key={cal.id}
                className="group flex items-center gap-2 rounded-lg px-2 py-0.5 hover:bg-mail-nav-hover"
              >
                <label className="flex min-w-0 flex-1 cursor-pointer items-center gap-2.5">
                  <input
                    type="checkbox"
                    checked={visible}
                    onChange={() => toggleCalendar(cal.id)}
                    className="peer sr-only"
                  />
                  <span
                    aria-hidden
                    className={cn(
                      "flex size-4.5 shrink-0 items-center justify-center rounded-[5px] border-2 transition-colors",
                    )}
                    style={{
                      borderColor: color,
                      backgroundColor: visible ? color : "transparent",
                    }}
                  >
                    {visible && (
                      <svg viewBox="0 0 24 24" className="size-3.5 text-white" fill="none">
                        <path
                          d="M5 13l4 4L19 7"
                          stroke="currentColor"
                          strokeWidth="3"
                          strokeLinecap="round"
                          strokeLinejoin="round"
                        />
                      </svg>
                    )}
                  </span>
                  <span className="truncate text-sm text-foreground/85">
                    {cal.display_name}
                    {isExternal ? (
                      <span className="ml-1 text-[10px] text-muted-foreground">(iCal)</span>
                    ) : null}
                  </span>
                </label>
                {!isExternal ? (
                <DropdownMenu>
                  <DropdownMenuTrigger asChild>
                    <Button
                      variant="ghost"
                      size="icon"
                      className="size-7 shrink-0 rounded-full text-muted-foreground opacity-0 group-hover:opacity-100 data-[state=open]:opacity-100"
                      aria-label={`Options de ${cal.display_name}`}
                    >
                      <MoreVertical className="size-4" />
                    </Button>
                  </DropdownMenuTrigger>
                  <DropdownMenuContent align="start" className="w-44">
                    <DropdownMenuItem
                      onSelect={() => {
                        setEditingCalendar(cal)
                        setCalendarDialogOpen(true)
                      }}
                    >
                      <Pencil className="size-4" /> Modifier
                    </DropdownMenuItem>
                    <DropdownMenuItem
                      variant="destructive"
                      onSelect={() => setDeletingCalendar(cal)}
                    >
                      <Trash2 className="size-4" /> Supprimer
                    </DropdownMenuItem>
                  </DropdownMenuContent>
                </DropdownMenu>
                ) : null}
              </div>
            )
          })}
        </div>
      </aside>

      <AgendaCalendarDialog
        open={calendarDialogOpen}
        onOpenChange={setCalendarDialogOpen}
        calendar={editingCalendar}
        onAddExternalICal={
          editingCalendar
            ? undefined
            : () => {
                setCalendarDialogOpen(false)
                setExternalDialogOpen(true)
              }
        }
      />

      <ExternalCalendarDialog
        open={externalDialogOpen}
        onOpenChange={setExternalDialogOpen}
        calendar={null}
        accounts={accounts}
      />

      <CalendarViewDialog
        open={viewDialogOpen}
        onOpenChange={setViewDialogOpen}
        view={null}
        calendarOptions={calendarOptions}
        labelOptions={labelOptions}
      />

      <AlertDialog
        open={deletingCalendar !== null}
        onOpenChange={(o) => {
          if (!o) setDeletingCalendar(null)
        }}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>
              Supprimer « {deletingCalendar?.display_name} » ?
            </AlertDialogTitle>
            <AlertDialogDescription>
              Tous les événements de cet agenda seront définitivement supprimés.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Annuler</AlertDialogCancel>
            <AlertDialogAction
              className="bg-destructive text-white hover:bg-destructive/90"
              onClick={() => void confirmDelete()}
            >
              Supprimer
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  )
}
