"use client"

import { useEffect, useMemo, useRef, useState } from "react"
import { createClient } from "@/lib/supabase/client"
import { Card, CardContent } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
import { format, isFuture, isPast, isToday } from "date-fns"
import { es } from "date-fns/locale"
import {
  Clock,
  MapPin,
  X,
  CheckCircle,
  Calendar,
  BellRing,
  Pencil,
} from "lucide-react"
import { Empty, EmptyMedia, EmptyTitle, EmptyDescription } from "@/components/ui/empty"
import type { Database } from "@/lib/supabase/database.types"
import { toast } from "sonner"
import { ReservationEditorDialog } from "@/components/reservations/reservation-editor-dialog"
import { getActionCutoff } from "@/lib/reservations/rules"
import { getResourceLocationPathLabel } from "@/lib/resources/location"
import { DynamicIcon } from "@/components/ui/dynamic-icon"
import { isCheckInWindowOpen, resolveCheckInWindowMinutes } from "@/lib/reservations/policies"
import { PolicyDisabledTooltip } from "@/components/reservations/policy-disabled-tooltip"

type Reservation = Database["public"]["Tables"]["reservations"]["Row"] & {
  reconfirmation_status?: string | null
  reminder_sent_at?: string | null
  resources: {
    name: string
    floor: string | null
    metadata: Database["public"]["Tables"]["resources"]["Row"]["metadata"]
    capacity: number | null
    resource_types: ({ name: string; slug: string; icon: string | null } & { reminders_enabled?: boolean | null }) | null
  } | null
}

type PolicyRow = Database["public"]["Tables"]["resource_policies"]["Row"] & {
  cancellation_deadline_minutes?: number | null
  editing_deadline_minutes?: number | null
}

const statusLabels: Record<string, { label: string }> = {
  confirmed: { label: "Confirmada" },
  checked_in: { label: "Check-in" },
  completed: { label: "Completada" },
  cancelled: { label: "Cancelada" },
  no_show: { label: "No-show" },
}

export default function MyReservationsPage() {
  const [reservations, setReservations] = useState<Reservation[]>([])
  const [policies, setPolicies] = useState<PolicyRow[]>([])
  const [loading, setLoading] = useState(true)
  const [checkingInId, setCheckingInId] = useState<string | null>(null)
  const [cancelingId, setCancelingId] = useState<string | null>(null)
  const [reconfirmingId, setReconfirmingId] = useState<string | null>(null)
  const [remindingId, setRemindingId] = useState<string | null>(null)
  const [editorMode, setEditorMode] = useState<"edit" | "rebook" | null>(null)
  const [editorReservation, setEditorReservation] = useState<Reservation | null>(null)
  const attemptedAutoReminderRef = useRef<Set<string>>(new Set())
  const supabase = createClient()

  const fetchReservations = async () => {
    setLoading(true)
    const { data: { user } } = await supabase.auth.getUser()
    if (!user) {
      setLoading(false)
      return
    }

    const { data } = await supabase
      .from("reservations")
      .select(`
        *,
        resources (
          name,
          floor,
          metadata,
          capacity,
          resource_types (*)
        )
      `)
      .eq("user_id", user.id)
      .order("start_at", { ascending: false })

    const { data: policyData } = await supabase
      .from("resource_policies")
      .select("*")
      .not("resource_type_id", "is", null)

    if (data) setReservations(data as Reservation[])
    if (policyData) setPolicies(policyData as PolicyRow[])
    setLoading(false)
  }

  useEffect(() => {
    fetchReservations()
  }, [])

  const policyByTypeId = useMemo(
    () =>
      new Map(
        policies
          .filter((policy) => policy.resource_type_id)
          .map((policy) => [policy.resource_type_id as string, policy]),
      ),
    [policies],
  )

  const upcomingReservations = useMemo(
    () =>
      reservations
        .filter(
          (reservation) =>
            (reservation.status === "confirmed" || reservation.status === "checked_in") &&
            (isFuture(new Date(reservation.start_at)) || isToday(new Date(reservation.start_at))),
        )
        .sort((a, b) => new Date(a.start_at).getTime() - new Date(b.start_at).getTime()),
    [reservations],
  )

  const historyReservations = useMemo(() => {
    const upcomingIds = new Set(upcomingReservations.map((reservation) => reservation.id))
    return reservations
      .filter((reservation) => !upcomingIds.has(reservation.id))
      .sort((a, b) => new Date(b.start_at).getTime() - new Date(a.start_at).getTime())
  }, [reservations, upcomingReservations])

  useEffect(() => {
    const triggerAutoReminder = async (reservationId: string) => {
      attemptedAutoReminderRef.current.add(reservationId)
      const response = await fetch(`/api/reservations/${encodeURIComponent(reservationId)}/send-reminder`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ demo: false }),
      })

      if (!response.ok) return
      fetchReservations()
    }

    for (const reservation of upcomingReservations) {
      if (reservation.status !== "confirmed") continue
      if (reservation.reminder_sent_at) continue
      if (attemptedAutoReminderRef.current.has(reservation.id)) continue

      const type = reservation.resources?.resource_types as { reminders_enabled?: boolean | null } | null
      if (type?.reminders_enabled !== true) continue

      const reminderAt = new Date(new Date(reservation.start_at).getTime() - 24 * 60 * 60 * 1000)
      if (new Date().getTime() < reminderAt.getTime()) continue

      void triggerAutoReminder(reservation.id)
    }
  }, [upcomingReservations])

  const handleCancel = async (id: string) => {
    setCancelingId(id)

    const response = await fetch(`/api/reservations/${encodeURIComponent(id)}/cancel`, {
      method: "POST",
    })
    const payload = (await response.json().catch(() => null)) as { error?: string } | null

    if (!response.ok) {
      toast.error(payload?.error ?? "No se pudo cancelar la reserva")
      setCancelingId(null)
      return
    }

    toast.success("Reserva cancelada")
    setCancelingId(null)
    fetchReservations()
  }

  const handleCheckIn = async (id: string) => {
    setCheckingInId(id)

    const response = await fetch("/api/checkins", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ reservationId: id }),
    })

    const payload = (await response.json().catch(() => null)) as { error?: string } | null

    if (!response.ok) {
      toast.error(payload?.error ?? "No se pudo hacer check-in")
      setCheckingInId(null)
      return
    }

    toast.success("Check-in realizado")
    setCheckingInId(null)
    fetchReservations()
  }

  const handleReconfirm = async (id: string) => {
    setReconfirmingId(id)
    const response = await fetch(`/api/reservations/${encodeURIComponent(id)}/reconfirm`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action: "confirm" }),
    })
    const payload = (await response.json().catch(() => null)) as { error?: string } | null

    if (!response.ok) {
      toast.error(payload?.error ?? "No se pudo confirmar la reserva")
      setReconfirmingId(null)
      return
    }

    toast.success("Reserva confirmada")
    setReconfirmingId(null)
    fetchReservations()
  }

  const handleSendReminder = async (id: string, demo: boolean) => {
    setRemindingId(id)
    const response = await fetch(`/api/reservations/${encodeURIComponent(id)}/send-reminder`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ demo }),
    })
    const payload = (await response.json().catch(() => null)) as { error?: string } | null

    if (!response.ok) {
      toast.error(payload?.error ?? "No se pudo enviar el recordatorio")
      setRemindingId(null)
      return
    }

    toast.success(demo ? "Recordatorio demo enviado" : "Recordatorio enviado")
    setRemindingId(null)
    fetchReservations()
  }

  const canCheckIn = (reservation: Reservation) => {
    if (reservation.status !== "confirmed") return false
    if (!reservation.resource_id) return false

    const resourceTypeId = reservation.resources?.resource_types
      ? ((reservation.resources.resource_types as { id?: string }).id ?? null)
      : null

    const checkInWindowMinutes = resolveCheckInWindowMinutes({
      resourceId: reservation.resource_id,
      resourceTypeId,
      policies,
    })

    return isCheckInWindowOpen({
      startAt: reservation.start_at,
      endAt: reservation.end_at,
      now: new Date(),
      windowMinutes: checkInWindowMinutes,
    })
  }

  const getStatusClassName = (status: string | null) => {
    switch (status) {
      case "confirmed":
        return "rounded-[var(--ds-radius-s)] border-0 bg-[var(--ds-blueprimary-100)] ds-type-global-xxs ds-type-semibold text-[var(--ds-blueprimary-800)]"
      case "checked_in":
        return "rounded-[var(--ds-radius-s)] border-0 bg-[var(--ds-success-100)] ds-type-global-xxs ds-type-semibold text-[var(--ds-success-700)]"
      case "cancelled":
      case "no_show":
        return "rounded-[var(--ds-radius-s)] border-0 bg-[var(--ds-error-100)] ds-type-global-xxs ds-type-semibold text-[var(--ds-error-700)]"
      default:
        return "rounded-[var(--ds-radius-s)] border-0 bg-[var(--ds-neutral-100)] ds-type-global-xxs text-[var(--ds-text-neutral-default)]"
    }
  }

  const ReservationCard = ({
    reservation,
    allowRebook = false,
  }: {
    reservation: Reservation
    allowRebook?: boolean
  }) => {
    const startDate = new Date(reservation.start_at)
    const endDate = new Date(reservation.end_at)
    const isUpcoming = isFuture(startDate) || (isToday(startDate) && !isPast(endDate))
    const showCheckIn = canCheckIn(reservation)
    const resourceTypeId = reservation.resources?.resource_types
      ? (reservation.resources.resource_types as { id?: string }).id
      : null
    const policy = resourceTypeId ? policyByTypeId.get(resourceTypeId) : undefined
    const cancellationDeadlineMinutes =
      typeof policy?.cancellation_deadline_minutes === "number" && policy.cancellation_deadline_minutes > 0
        ? policy.cancellation_deadline_minutes
        : 5 * 60
    const editingDeadlineMinutes =
      typeof policy?.editing_deadline_minutes === "number" && policy.editing_deadline_minutes > 0
        ? policy.editing_deadline_minutes
        : cancellationDeadlineMinutes

    const cancellationCutoff = getActionCutoff({
      startAt: reservation.start_at,
      minutesBeforeStart: cancellationDeadlineMinutes,
    })
    const editingCutoff = getActionCutoff({
      startAt: reservation.start_at,
      minutesBeforeStart: editingDeadlineMinutes,
    })
    const now = new Date()
    const canCancelNow = now.getTime() <= cancellationCutoff.getTime()
    const canEditNow = now.getTime() <= editingCutoff.getTime()
    const editPolicyReason = canEditNow
      ? undefined
      : `La ventana para editar cerró el ${format(editingCutoff, "EEEE d MMM, HH:mm", { locale: es })}.`
    const cancelPolicyReason = canCancelNow
      ? undefined
      : `La ventana para cancelar cerró el ${format(cancellationCutoff, "EEEE d MMM, HH:mm", { locale: es })}.`

    const remindersEnabled = reservation.resources?.resource_types
      ? Boolean((reservation.resources.resource_types as { reminders_enabled?: boolean | null }).reminders_enabled)
      : false
    const reminderAt = new Date(startDate.getTime() - 24 * 60 * 60 * 1000)
    const showReminderBanner =
      remindersEnabled &&
      reservation.status === "confirmed" &&
      now.getTime() >= reminderAt.getTime() &&
      now.getTime() <= cancellationCutoff.getTime()

    return (
      <Card className="rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] bg-white shadow-[var(--ds-shadow-4dp)]">
        <CardContent className="p-[var(--ds-space-2x)]">
          <div className="flex items-start justify-between gap-4">
            <div className="flex items-start gap-3">
              <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-[var(--ds-radius-m)] bg-[var(--ds-blueprimary-100)] text-[var(--ds-brand-400)]">
                <DynamicIcon name={reservation.resources?.resource_types?.icon} className="h-5 w-5" />
              </div>
              <div className="space-y-[var(--ds-space-05x)]">
                <h4 className="ds-type-global-s ds-type-semibold text-[var(--ds-text-neutral-default)]">
                  {reservation.resources?.name}
                </h4>
                <div className="flex flex-wrap gap-x-[var(--ds-space-2x)] gap-y-[var(--ds-space-05x)] ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
                  <span className="flex items-center gap-1">
                    <MapPin className="h-3 w-3" />
                    {getResourceLocationPathLabel(reservation.resources) ?? "Sin ubicación jerárquica"}
                    {reservation.resources?.floor && ` • ${reservation.resources.floor}`}
                  </span>
                  <span className="flex items-center gap-1">
                    <Calendar className="h-3 w-3" />
                    <span className="capitalize">
                      {format(startDate, "EEEE d MMM", { locale: es })}
                    </span>
                  </span>
                  <span className="flex items-center gap-1">
                    <Clock className="h-3 w-3" />
                    {format(startDate, "HH:mm")} - {format(endDate, "HH:mm")}
                  </span>
                </div>
                {reservation.notes && (
                  <p className="ds-type-global-xs italic text-[var(--ds-text-neutral-lighter)]">
                    {reservation.notes}
                  </p>
                )}
              </div>
            </div>
            <div className="flex flex-col items-end gap-2">
              <Badge className={getStatusClassName(reservation.status)}>
                {statusLabels[reservation.status || "confirmed"].label}
              </Badge>
              {isUpcoming && reservation.status === "confirmed" && (
                <div className="flex gap-2">
                  <PolicyDisabledTooltip reason={editPolicyReason}>
                    <Button
                      size="sm"
                      variant="outline"
                      className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]"
                      disabled={!canEditNow}
                      onClick={() => {
                        setEditorMode("edit")
                        setEditorReservation(reservation)
                      }}
                    >
                      <Pencil className="mr-1 h-4 w-4" />
                      Editar
                    </Button>
                  </PolicyDisabledTooltip>
                  {showCheckIn && (
                    <Button
                      size="sm"
                      className="rounded-[var(--ds-radius-m)] bg-[var(--ds-brand-400)] ds-type-global-xs ds-type-semibold text-white hover:bg-[var(--ds-brand-500)]"
                      disabled={checkingInId === reservation.id || cancelingId === reservation.id}
                      onClick={() => handleCheckIn(reservation.id)}
                    >
                      <CheckCircle className="mr-1 h-4 w-4" />
                      Check-in
                    </Button>
                  )}
                  <AlertDialog>
                    <AlertDialogTrigger asChild>
                      <Button
                        size="sm"
                        variant="outline"
                        className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]"
                      >
                        <X className="mr-1 h-4 w-4" />
                        Cancelar
                      </Button>
                    </AlertDialogTrigger>
                    <AlertDialogContent className="rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] shadow-[var(--ds-shadow-8dp)]">
                      <AlertDialogHeader>
                        <AlertDialogTitle className="ds-type-global-m ds-type-semibold text-[var(--ds-text-neutral-default)]">
                          Cancelar reserva
                        </AlertDialogTitle>
                        <AlertDialogDescription className="ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
                          ¿Estás seguro de que quieres cancelar esta reserva? Esta acción no se puede deshacer.
                        </AlertDialogDescription>
                      </AlertDialogHeader>
                      <AlertDialogFooter>
                        <AlertDialogCancel className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]">
                          Volver
                        </AlertDialogCancel>
                        <PolicyDisabledTooltip reason={cancelPolicyReason}>
                          <AlertDialogAction
                            className="rounded-[var(--ds-radius-m)] bg-[var(--ds-error-700)] ds-type-global-xs ds-type-semibold text-white hover:bg-[var(--ds-error-700)]"
                            disabled={
                              cancelingId === reservation.id ||
                              checkingInId === reservation.id ||
                              !canCancelNow
                            }
                            onClick={() => handleCancel(reservation.id)}
                          >
                            Cancelar reserva
                          </AlertDialogAction>
                        </PolicyDisabledTooltip>
                      </AlertDialogFooter>
                    </AlertDialogContent>
                  </AlertDialog>
                </div>
              )}
            </div>
          </div>

          {showReminderBanner && (
            <Alert className="mt-[var(--ds-space-2x)] rounded-[var(--ds-radius-m)] border-[var(--ds-brand-400)] bg-[var(--ds-blueprimary-100)]">
              <BellRing className="h-4 w-4 text-[var(--ds-brand-400)]" />
              <AlertTitle className="ds-type-global-xs ds-type-semibold text-[var(--ds-blueprimary-800)]">
                Recordatorio de reserva
              </AlertTitle>
              <AlertDescription className="space-y-[var(--ds-space-1x)] ds-type-global-xs text-[var(--ds-text-neutral-default)]">
                <p>
                  Tu reserva está cerca. Puedes confirmar, editar o cancelar hasta{" "}
                  <span className="capitalize">
                    {format(cancellationCutoff, "EEEE d MMM, HH:mm", { locale: es })}
                  </span>
                  .
                </p>
                <div className="flex flex-wrap gap-2">
                  <Button
                    size="sm"
                    className="rounded-[var(--ds-radius-m)] bg-[var(--ds-brand-400)] ds-type-global-xs ds-type-semibold text-white hover:bg-[var(--ds-brand-500)]"
                    disabled={reconfirmingId === reservation.id}
                    onClick={() => handleReconfirm(reservation.id)}
                  >
                    Confirmar uso
                  </Button>
                  <PolicyDisabledTooltip reason={editPolicyReason}>
                    <Button
                      size="sm"
                      variant="outline"
                      className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]"
                      disabled={!canEditNow}
                      onClick={() => {
                        setEditorMode("edit")
                        setEditorReservation(reservation)
                      }}
                    >
                      Editar
                    </Button>
                  </PolicyDisabledTooltip>
                  <PolicyDisabledTooltip reason={cancelPolicyReason}>
                    <Button
                      size="sm"
                      variant="outline"
                      className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]"
                      disabled={!canCancelNow || cancelingId === reservation.id}
                      onClick={() => handleCancel(reservation.id)}
                    >
                      Cancelar
                    </Button>
                  </PolicyDisabledTooltip>
                  <Button
                    size="sm"
                    variant="outline"
                    className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]"
                    disabled={remindingId === reservation.id}
                    onClick={() => handleSendReminder(reservation.id, true)}
                  >
                    Enviar email demo
                  </Button>
                </div>
              </AlertDescription>
            </Alert>
          )}
        </CardContent>
      </Card>
    )
  }

  if (loading) {
    return (
      <div className="flex items-center justify-center py-12">
        <div className="h-8 w-8 animate-spin rounded-full border-4 border-[var(--ds-brand-400)] border-t-transparent" />
      </div>
    )
  }

  return (
    <div className="space-y-[var(--ds-space-4x)]">
      <div className="rounded-[var(--ds-radius-l)] bg-[var(--ds-blueprimary-100)] px-[var(--ds-space-4x)] py-[var(--ds-space-3x)] shadow-[var(--ds-shadow-4dp)]">
        <h1 className="ds-type-global-l ds-type-semibold text-[var(--ds-blueprimary-800)]">
          Mis Reservas
        </h1>
        <p className="mt-[var(--ds-space-1x)] ds-type-global-s text-[var(--ds-text-neutral-lighter)]">
          Gestiona tus reservas de espacios
        </p>
      </div>

      <Tabs defaultValue="upcoming">
        <TabsList className="h-11 rounded-[var(--ds-radius-m)] bg-[var(--ds-neutral-100)] p-[var(--ds-space-05x)]">
          <TabsTrigger
            value="upcoming"
            className="rounded-[var(--ds-radius-s)] ds-type-global-xs data-[state=active]:bg-white data-[state=active]:text-[var(--ds-blueprimary-800)] data-[state=active]:shadow-[var(--ds-shadow-4dp)]"
          >
            Próximas ({upcomingReservations.length})
          </TabsTrigger>
          <TabsTrigger
            value="past"
            className="rounded-[var(--ds-radius-s)] ds-type-global-xs data-[state=active]:bg-white data-[state=active]:text-[var(--ds-blueprimary-800)] data-[state=active]:shadow-[var(--ds-shadow-4dp)]"
          >
            Historial ({historyReservations.length})
          </TabsTrigger>
        </TabsList>

        <TabsContent value="upcoming" className="mt-[var(--ds-space-2x)] space-y-[var(--ds-space-2x)]">
          {upcomingReservations.length === 0 ? (
            <Empty className="rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] bg-white py-[var(--ds-space-5x)] shadow-[var(--ds-shadow-4dp)]">
              <EmptyMedia>
                <Calendar className="h-10 w-10" />
              </EmptyMedia>
              <EmptyTitle className="ds-type-global-m ds-type-semibold text-[var(--ds-text-neutral-default)]">
                No tienes reservas próximas
              </EmptyTitle>
              <EmptyDescription className="ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
                Crea una nueva reserva para comenzar
              </EmptyDescription>
              <Button
                className="mt-[var(--ds-space-2x)] rounded-[var(--ds-radius-m)] bg-[var(--ds-brand-400)] ds-type-global-xs ds-type-semibold text-white hover:bg-[var(--ds-brand-500)]"
                asChild
              >
                <a href="/reservations">Nueva reserva</a>
              </Button>
            </Empty>
          ) : (
            upcomingReservations.map((reservation) => (
              <ReservationCard key={reservation.id} reservation={reservation} />
            ))
          )}
        </TabsContent>

        <TabsContent value="past" className="mt-[var(--ds-space-2x)] space-y-[var(--ds-space-2x)]">
          {historyReservations.length === 0 ? (
            <Empty className="rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] bg-white py-[var(--ds-space-5x)] shadow-[var(--ds-shadow-4dp)]">
              <EmptyMedia>
                <Clock className="h-10 w-10" />
              </EmptyMedia>
              <EmptyTitle className="ds-type-global-m ds-type-semibold text-[var(--ds-text-neutral-default)]">
                Sin historial
              </EmptyTitle>
              <EmptyDescription className="ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
                Aquí aparecerán tus reservas completadas
              </EmptyDescription>
            </Empty>
          ) : (
            historyReservations.map((reservation) => (
              <ReservationCard key={reservation.id} reservation={reservation} allowRebook />
            ))
          )}
        </TabsContent>
      </Tabs>

      <ReservationEditorDialog
        open={Boolean(editorMode && editorReservation)}
        mode={editorMode ?? "edit"}
        reservation={editorReservation}
        onClose={() => {
          setEditorMode(null)
          setEditorReservation(null)
        }}
        onSaved={() => {
          fetchReservations()
        }}
      />
    </div>
  )
}
