"use client"

import { useEffect, useMemo, useState } from "react"
import { Link2, Pencil, Plus, Trash2 } from "lucide-react"
import { toast } from "sonner"
import { AccountAvatar } from "@/components/gmail/account-avatar"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { AGENDA_COLOR_PALETTE } from "@/lib/agenda/agenda-colors"
import { isCalendarEnabledForAccount, isReservedAgendaViewName } from "@/lib/agenda/agenda-calendar-visibility"
import { calendarColor } from "@/lib/agenda/agenda-events"
import { useAgendaSettingsStore } from "@/lib/agenda/agenda-store"
import type { AgendaCalendarView, AgendaExternalCalendar } from "@/lib/agenda/agenda-settings-types"
import { useMergedAgendaCalendars } from "@/lib/agenda/use-visible-agenda-calendars"
import { useLabels } from "@/lib/api/hooks/use-folder-label-queries"
import { useMailAccounts } from "@/lib/api/hooks/use-mail-queries"
import { MAIL_SETTINGS_PAGE_MASONRY_SECTION_CLASS } from "@/lib/mail-chrome-classes"
import { MAIL_SETTINGS_BASE_PATH } from "@/lib/mail-settings/settings-nav"
import { cn } from "@/lib/utils"

function CalendarCheckboxRow({
  calendarId,
  label,
  color,
  checked,
  onToggle,
}: {
  calendarId: string
  label: string
  color: string
  checked: boolean
  onToggle: () => void
}) {
  return (
    <label className="flex cursor-pointer items-center gap-2.5 rounded-lg px-2 py-1.5 hover:bg-mail-nav-hover">
      <Checkbox checked={checked} onCheckedChange={onToggle} />
      <span
        aria-hidden
        className="size-3.5 shrink-0 rounded-[4px]"
        style={{ backgroundColor: color }}
      />
      <span className="min-w-0 truncate text-sm text-foreground/85">{label}</span>
      <span className="sr-only">{calendarId}</span>
    </label>
  )
}

export function ExternalCalendarDialog({
  open,
  onOpenChange,
  calendar,
  accounts,
}: {
  open: boolean
  onOpenChange: (open: boolean) => void
  calendar: AgendaExternalCalendar | null
  accounts: { id: string; name: string; email: string }[]
}) {
  const addExternalCalendar = useAgendaSettingsStore((s) => s.addExternalCalendar)
  const updateExternalCalendar = useAgendaSettingsStore((s) => s.updateExternalCalendar)
  const [name, setName] = useState("")
  const [url, setUrl] = useState("")
  const [color, setColor] = useState(AGENDA_COLOR_PALETTE[0].value)
  const [accountId, setAccountId] = useState<string>("all")

  useEffect(() => {
    if (!open) return
    setName(calendar?.display_name ?? "")
    setUrl(calendar?.url ?? "")
    setColor(calendar?.color ?? AGENDA_COLOR_PALETTE[0].value)
    setAccountId(calendar?.account_id ?? "all")
  }, [open, calendar])

  const submit = () => {
    const displayName = name.trim()
    const feedUrl = url.trim()
    if (!displayName || !feedUrl) return
    try {
      const parsed = new URL(feedUrl)
      if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
        toast.error("L'URL doit commencer par http:// ou https://")
        return
      }
    } catch {
      toast.error("URL iCal invalide")
      return
    }

    const payload = {
      display_name: displayName,
      url: feedUrl,
      color,
      account_id: accountId === "all" ? null : accountId,
    }

    if (calendar) {
      updateExternalCalendar(calendar.id, payload)
      toast.success("Calendrier externe mis à jour")
    } else {
      addExternalCalendar(payload)
      toast.success("Calendrier externe ajouté")
    }
    onOpenChange(false)
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-md" aria-describedby={undefined}>
        <DialogHeader>
          <DialogTitle>
            {calendar ? "Modifier le calendrier externe" : "Ajouter un calendrier iCal"}
          </DialogTitle>
        </DialogHeader>
        <div className="flex flex-col gap-4">
          <div className="space-y-2">
            <Label htmlFor="ext-cal-name">Nom</Label>
            <Input
              id="ext-cal-name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="Calendrier externe"
            />
          </div>
          <div className="space-y-2">
            <Label htmlFor="ext-cal-url">Lien iCal</Label>
            <Input
              id="ext-cal-url"
              value={url}
              onChange={(e) => setUrl(e.target.value)}
              placeholder="https://…/calendar.ics"
            />
          </div>
          <div className="space-y-2">
            <Label>Compte mail</Label>
            <Select value={accountId} onValueChange={setAccountId}>
              <SelectTrigger className="h-9">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">Tous les comptes</SelectItem>
                {accounts.map((account) => (
                  <SelectItem key={account.id} value={account.id}>
                    {account.email}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="space-y-2">
            <Label>Couleur</Label>
            <div className="flex flex-wrap gap-2">
              {AGENDA_COLOR_PALETTE.map((entry) => (
                <button
                  key={entry.value}
                  type="button"
                  title={entry.label}
                  aria-label={entry.label}
                  onClick={() => setColor(entry.value)}
                  className={cn(
                    "size-7 rounded-full transition-transform hover:scale-110",
                    color === entry.value &&
                      "ring-2 ring-foreground/70 ring-offset-2 ring-offset-background",
                  )}
                  style={{ backgroundColor: entry.value }}
                />
              ))}
            </div>
          </div>
        </div>
        <DialogFooter>
          <Button variant="ghost" onClick={() => onOpenChange(false)}>
            Annuler
          </Button>
          <Button onClick={submit} disabled={!name.trim() || !url.trim()}>
            {calendar ? "Enregistrer" : "Ajouter"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

export function CalendarViewDialog({
  open,
  onOpenChange,
  view,
  calendarOptions,
  labelOptions,
}: {
  open: boolean
  onOpenChange: (open: boolean) => void
  view: AgendaCalendarView | null
  calendarOptions: { id: string; label: string; color: string }[]
  labelOptions: { id: string; label: string }[]
}) {
  const addCalendarView = useAgendaSettingsStore((s) => s.addCalendarView)
  const updateCalendarView = useAgendaSettingsStore((s) => s.updateCalendarView)
  const [name, setName] = useState("")
  const [calendarIds, setCalendarIds] = useState<string[]>([])
  const [labelIds, setLabelIds] = useState<string[]>([])

  useEffect(() => {
    if (!open) return
    setName(view?.name ?? "")
    setCalendarIds(view?.calendar_ids ?? [])
    setLabelIds(view?.label_ids ?? [])
  }, [open, view])

  const toggleCalendar = (calendarId: string) => {
    setCalendarIds((current) =>
      current.includes(calendarId)
        ? current.filter((id) => id !== calendarId)
        : [...current, calendarId],
    )
  }

  const toggleLabel = (labelId: string) => {
    setLabelIds((current) =>
      current.includes(labelId)
        ? current.filter((id) => id !== labelId)
        : [...current, labelId],
    )
  }

  const submit = () => {
    const trimmed = name.trim()
    if (!trimmed) return
    if (isReservedAgendaViewName(trimmed)) {
      toast.error('« Tous les agendas » est réservé à l\'affichage sans vue.')
      return
    }
    if (calendarIds.length === 0) {
      toast.error("Sélectionnez au moins un agenda")
      return
    }
    const payload = {
      name: trimmed,
      calendar_ids: calendarIds,
      label_ids: labelIds,
    }
    if (view) {
      updateCalendarView(view.id, payload)
      toast.success("Vue mise à jour")
    } else {
      addCalendarView(payload)
      toast.success("Vue créée")
    }
    onOpenChange(false)
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-lg" aria-describedby={undefined}>
        <DialogHeader>
          <DialogTitle>{view ? "Modifier la vue" : "Nouvelle vue d'agendas"}</DialogTitle>
        </DialogHeader>
        <div className="flex max-h-[min(70vh,520px)] flex-col gap-4 overflow-y-auto pr-1">
          <div className="space-y-2">
            <Label htmlFor="view-name">Nom de la vue</Label>
            <Input
              id="view-name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="Travail, Perso…"
            />
          </div>
          <div className="space-y-2">
            <Label>Agendas inclus</Label>
            <div className="max-h-44 space-y-0.5 overflow-y-auto rounded-lg border border-border p-1">
              {calendarOptions.length === 0 ? (
                <p className="px-2 py-3 text-xs text-muted-foreground">
                  Aucun agenda disponible.
                </p>
              ) : (
                calendarOptions.map((calendar) => (
                  <CalendarCheckboxRow
                    key={calendar.id}
                    calendarId={calendar.id}
                    label={calendar.label}
                    color={calendar.color}
                    checked={calendarIds.includes(calendar.id)}
                    onToggle={() => toggleCalendar(calendar.id)}
                  />
                ))
              )}
            </div>
          </div>
          <div className="space-y-2">
            <Label>Libellés associés</Label>
            <p className="text-[11px] text-muted-foreground">
              Pour filtrer les invitations importées depuis le mail (optionnel).
            </p>
            <div className="max-h-36 space-y-0.5 overflow-y-auto rounded-lg border border-border p-1">
              {labelOptions.length === 0 ? (
                <p className="px-2 py-3 text-xs text-muted-foreground">Aucun libellé.</p>
              ) : (
                labelOptions.map((label) => (
                  <label
                    key={label.id}
                    className="flex cursor-pointer items-center gap-2.5 rounded-lg px-2 py-1.5 hover:bg-mail-nav-hover"
                  >
                    <Checkbox
                      checked={labelIds.includes(label.id)}
                      onCheckedChange={() => toggleLabel(label.id)}
                    />
                    <span className="truncate text-sm">{label.label}</span>
                  </label>
                ))
              )}
            </div>
          </div>
        </div>
        <DialogFooter>
          <Button variant="ghost" onClick={() => onOpenChange(false)}>
            Annuler
          </Button>
          <Button onClick={submit} disabled={!name.trim()}>
            {view ? "Enregistrer" : "Créer"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

export function AgendaCalendarsSettingsFields({
  variant = "panel",
}: {
  variant?: "panel" | "page"
}) {
  const { data: accounts = [] } = useMailAccounts()
  const { data: labels = [] } = useLabels()
  const { calendars, externalCalendars } = useMergedAgendaCalendars()
  const accountEnabledCalendarIds = useAgendaSettingsStore(
    (s) => s.accountEnabledCalendarIds,
  )
  const toggleAccountCalendar = useAgendaSettingsStore((s) => s.toggleAccountCalendar)
  const removeExternalCalendar = useAgendaSettingsStore((s) => s.removeExternalCalendar)
  const calendarViews = useAgendaSettingsStore((s) => s.calendarViews)
  const defaultCalendarViewId = useAgendaSettingsStore((s) => s.defaultCalendarViewId)
  const setDefaultCalendarViewId = useAgendaSettingsStore((s) => s.setDefaultCalendarViewId)
  const removeCalendarView = useAgendaSettingsStore((s) => s.removeCalendarView)

  const [externalDialogOpen, setExternalDialogOpen] = useState(false)
  const [editingExternal, setEditingExternal] = useState<AgendaExternalCalendar | null>(
    null,
  )
  const [viewDialogOpen, setViewDialogOpen] = useState(false)
  const [editingView, setEditingView] = useState<AgendaCalendarView | null>(null)

  const allCalendarIds = useMemo(
    () => calendars.map((calendar) => calendar.id),
    [calendars],
  )

  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 isPage = variant === "page"

  const sectionShell = (position: "first" | "rest") =>
    cn(
      "space-y-3",
      isPage
        ? MAIL_SETTINGS_PAGE_MASONRY_SECTION_CLASS
        : cn("px-4 py-3", position === "rest" && "border-t border-border"),
    )

  return (
    <>
      <section className={sectionShell("first")}>
        <div>
          <h2 className="text-sm font-medium text-foreground">Agendas par compte mail</h2>
          <p className="mt-0.5 text-[11px] leading-snug text-muted-foreground">
            Choisissez les agendas visibles pour chaque compte Ultimail.
          </p>
        </div>
        {accounts.length === 0 ? (
          <p className="text-xs text-muted-foreground">
            Aucun compte mail connecté.{" "}
            <a href={`${MAIL_SETTINGS_BASE_PATH}/accounts`} className="text-[#1a73e8] hover:underline">
              Ajouter un compte
            </a>
          </p>
        ) : (
          <div className="divide-y divide-border overflow-hidden rounded-lg border border-border">
            {accounts.map((account) => (
              <div key={account.id} className="p-3">
                <div className="mb-2 flex items-center gap-2">
                  <AccountAvatar account={account} size="sm" />
                  <div className="min-w-0">
                    <p className="truncate text-sm font-medium">{account.name}</p>
                    <p className="truncate text-xs text-muted-foreground">{account.email}</p>
                  </div>
                </div>
                <div className="space-y-0.5">
                  {calendars.length === 0 ? (
                    <p className="text-xs text-muted-foreground">Aucun agenda.</p>
                  ) : (
                    calendars.map((calendar) => (
                      <CalendarCheckboxRow
                        key={`${account.id}-${calendar.id}`}
                        calendarId={calendar.id}
                        label={calendar.display_name}
                        color={calendarColor(calendar)}
                        checked={isCalendarEnabledForAccount(
                          calendar.id,
                          account.id,
                          accountEnabledCalendarIds,
                        )}
                        onToggle={() =>
                          toggleAccountCalendar(account.id, calendar.id, allCalendarIds)
                        }
                      />
                    ))
                  )}
                </div>
              </div>
            ))}
          </div>
        )}
      </section>

      <section className={sectionShell("rest")}>
        <div className="flex items-start justify-between gap-2">
          <div>
            <h2 className="text-sm font-medium text-foreground">Calendriers externes</h2>
            <p className="mt-0.5 text-[11px] leading-snug text-muted-foreground">
              Abonnez un flux iCal (Google, Outlook, etc.).
            </p>
          </div>
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="h-8 shrink-0 gap-1 rounded-full"
            onClick={() => {
              setEditingExternal(null)
              setExternalDialogOpen(true)
            }}
          >
            <Plus className="size-3.5" />
            Ajouter
          </Button>
        </div>
        {externalCalendars.length === 0 ? (
          <p className="text-xs text-muted-foreground">Aucun calendrier externe.</p>
        ) : (
          <ul className="space-y-2">
            {externalCalendars.map((calendar) => (
              <li
                key={calendar.id}
                className="flex items-center gap-2 rounded-lg border border-border px-2 py-2"
              >
                <Link2 className="size-4 shrink-0 text-muted-foreground" />
                <span
                  aria-hidden
                  className="size-3 shrink-0 rounded-full"
                  style={{ backgroundColor: calendar.color }}
                />
                <div className="min-w-0 flex-1">
                  <p className="truncate text-sm">{calendar.display_name}</p>
                  <p className="truncate text-[11px] text-muted-foreground">{calendar.url}</p>
                </div>
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className="size-8 shrink-0"
                  aria-label={`Modifier ${calendar.display_name}`}
                  onClick={() => {
                    setEditingExternal(calendar)
                    setExternalDialogOpen(true)
                  }}
                >
                  <Pencil className="size-4" />
                </Button>
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className="size-8 shrink-0 text-destructive"
                  aria-label={`Supprimer ${calendar.display_name}`}
                  onClick={() => removeExternalCalendar(calendar.id)}
                >
                  <Trash2 className="size-4" />
                </Button>
              </li>
            ))}
          </ul>
        )}
      </section>

      <section className={sectionShell("rest")}>
        <div className="flex items-start justify-between gap-2">
          <div>
            <h2 className="text-sm font-medium text-foreground">Vues d&apos;agendas</h2>
            <p className="mt-0.5 text-[11px] leading-snug text-muted-foreground">
              Regroupez des agendas et libellés, puis ouvrez une vue depuis la barre latérale.
            </p>
          </div>
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="h-8 shrink-0 gap-1 rounded-full"
            onClick={() => {
              setEditingView(null)
              setViewDialogOpen(true)
            }}
          >
            <Plus className="size-3.5" />
            Nouvelle vue
          </Button>
        </div>

        <div className="grid grid-cols-[minmax(0,0.72fr)_minmax(9.75rem,1.18fr)] items-center gap-2 py-1">
          <Label className="text-xs font-normal text-muted-foreground">Vue par défaut</Label>
          <Select
            value={defaultCalendarViewId ?? "none"}
            onValueChange={(value) =>
              setDefaultCalendarViewId(value === "none" ? null : value)
            }
          >
            <SelectTrigger className="h-8 w-full text-xs">
              <SelectValue placeholder="Aucune vue" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="none">Aucune vue</SelectItem>
              {calendarViews.map((view) => (
                <SelectItem key={view.id} value={view.id}>
                  {view.name}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        {calendarViews.length === 0 ? (
          <p className="text-xs text-muted-foreground">Aucune vue enregistrée.</p>
        ) : (
          <ul className="space-y-2">
            {calendarViews.map((view) => (
              <li
                key={view.id}
                className="flex items-center gap-2 rounded-lg border border-border px-2 py-2"
              >
                <div className="min-w-0 flex-1">
                  <p className="truncate text-sm font-medium">{view.name}</p>
                  <p className="text-[11px] text-muted-foreground">
                    {view.calendar_ids.length} agenda
                    {view.calendar_ids.length > 1 ? "s" : ""}
                    {view.label_ids.length > 0
                      ? ` · ${view.label_ids.length} libellé${view.label_ids.length > 1 ? "s" : ""}`
                      : ""}
                  </p>
                </div>
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className="size-8 shrink-0"
                  aria-label={`Modifier ${view.name}`}
                  onClick={() => {
                    setEditingView(view)
                    setViewDialogOpen(true)
                  }}
                >
                  <Pencil className="size-4" />
                </Button>
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className="size-8 shrink-0 text-destructive"
                  aria-label={`Supprimer ${view.name}`}
                  onClick={() => removeCalendarView(view.id)}
                >
                  <Trash2 className="size-4" />
                </Button>
              </li>
            ))}
          </ul>
        )}
      </section>

      <ExternalCalendarDialog
        open={externalDialogOpen}
        onOpenChange={setExternalDialogOpen}
        calendar={editingExternal}
        accounts={accounts}
      />
      <CalendarViewDialog
        open={viewDialogOpen}
        onOpenChange={setViewDialogOpen}
        view={editingView}
        calendarOptions={calendarOptions}
        labelOptions={labelOptions}
      />
    </>
  )
}
