"use client"

import { useState, useEffect, useMemo, useCallback, useRef } from "react"
import { useParams } from "next/navigation"
import Link from "next/link"
import { createClient } from "@/lib/supabase/client"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Badge } from "@/components/ui/badge"
import { Calendar } from "@/components/ui/calendar"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
import { addDays, format, startOfDay, endOfDay, isBefore, setHours, setMinutes } from "date-fns"
import { es } from "date-fns/locale"
import {
  CalendarIcon,
  MapPin,
  ArrowLeft,
  Clock,
  ListOrdered,
  CalendarClock,
} from "lucide-react"
import { cn } from "@/lib/utils"
import { ReservationDialog } from "@/components/reservations/reservation-dialog"
import {
  bookingFieldsToSlotStarts,
  DEFAULT_BOOKING_FIELDS,
  formatSlotEndLabel,
  isSlotAvailable,
  normalizeResourceTypeBookingFields,
  slotStartIsInTypeWindow,
  timeGranularityToMinutes,
  type ResourceTypeBookingFields,
} from "@/lib/booking"
import type { Database } from "@/lib/supabase/database.types"
import {
  BOOKING_CALENDAR_LOOKAHEAD_DAYS,
  getAdvanceRestriction,
  type PolicyRow,
} from "@/lib/reservations/advance-restriction"
import { buildLocationChildrenMap, getLocationPathIds, type LocationRow } from "@/lib/locations/tree"
import { getResourceLocationPathLabel } from "@/lib/resources/location"
import { DynamicIcon } from "@/components/ui/dynamic-icon"

type Resource = Database["public"]["Tables"]["resources"]["Row"] & {
  resource_types: {
    name: string
    slug: string
    icon: string | null
    booking_window_start?: string | null
    booking_window_end?: string | null
    slot_size?: string | null
    time_granularity?: string | null
  } | null
}
type Reservation = Database["public"]["Tables"]["reservations"]["Row"]

export default function BookByTypePage() {
  const params = useParams()
  const typeSlug = params.typeSlug as string
  const supabase = createClient()

  const [typeName, setTypeName] = useState<string>("")
  const [typeId, setTypeId] = useState<string | null>(null)
  const [typeBookingFields, setTypeBookingFields] =
    useState<ResourceTypeBookingFields>(DEFAULT_BOOKING_FIELDS)
  const [notFound, setNotFound] = useState(false)
  const [resources, setResources] = useState<Resource[]>([])
  const [reservations, setReservations] = useState<Reservation[]>([])
  const [policies, setPolicies] = useState<PolicyRow[]>([])
  const [locations, setLocations] = useState<LocationRow[]>([])
  const [loading, setLoading] = useState(true)
  const didAutoShiftDefaultDateRef = useRef(false)

  const [selectedLocationByDepth, setSelectedLocationByDepth] = useState<string[]>([])
  const [selectedDate, setSelectedDate] = useState<Date>(() => new Date())
  const [filterTag, setFilterTag] = useState("all")
  /** resource-first | time-first */
  const [flow, setFlow] = useState<"resource-first" | "time-first">("resource-first")
  const [expandedResourceId, setExpandedResourceId] = useState<string | null>(null)
  const [pickedSlot, setPickedSlot] = useState<string | null>(null)

  const [dialogOpen, setDialogOpen] = useState(false)
  const [selectedResource, setSelectedResource] = useState<Resource | null>(null)
  const [selectedTimeSlot, setSelectedTimeSlot] = useState<{ start: string; end: string } | null>(null)
  const locationChildrenMap = useMemo(() => buildLocationChildrenMap(locations), [locations])
  const selectedLocationPathIds = useMemo(
    () =>
      getLocationPathIds({
        selectedByDepth: selectedLocationByDepth,
        childrenMap: locationChildrenMap,
      }),
    [selectedLocationByDepth, locationChildrenMap],
  )
  const selectedLocationId =
    selectedLocationPathIds.length > 0 ? selectedLocationPathIds[selectedLocationPathIds.length - 1] : null

  const isDefaultDaySelected = useMemo(
    () => startOfDay(selectedDate).getTime() === startOfDay(new Date()).getTime(),
    [selectedDate],
  )

  const slotStarts = useMemo(() => bookingFieldsToSlotStarts(typeBookingFields), [typeBookingFields])
  const gridStepMinutes = useMemo(
    () => timeGranularityToMinutes(String(typeBookingFields.time_granularity)),
    [typeBookingFields.time_granularity],
  )

  const fetchTypeAndResources = useCallback(async () => {
    setLoading(true)
    const { data: rt } = await supabase
      .from("resource_types")
      .select("id, name, booking_window_start, booking_window_end, slot_size, time_granularity")
      .eq("slug", typeSlug)
      .eq("is_active", true)
      .maybeSingle()

    if (!rt) {
      setNotFound(true)
      setLoading(false)
      return
    }
    setTypeId(rt.id)
    setTypeName(rt.name)
    setTypeBookingFields(normalizeResourceTypeBookingFields(rt as Partial<ResourceTypeBookingFields>))
    setNotFound(false)

    const { data: policiesData } = await supabase.from("resource_policies").select("*")
    setPolicies((policiesData ?? []) as PolicyRow[])

    const { data: resourcesData } = await supabase
      .from("resources")
      .select(
        `*, resource_types (name, slug, icon, booking_window_start, booking_window_end, slot_size, time_granularity)`,
      )
      .eq("resource_type_id", rt.id)
      .eq("is_active", true)
      .order("name")
    if (resourcesData) setResources(resourcesData as Resource[])
    setLoading(false)
  }, [supabase, typeSlug])

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

  useEffect(() => {
    didAutoShiftDefaultDateRef.current = false
    setSelectedDate(startOfDay(new Date()))
  }, [typeSlug])

  useEffect(() => {
    let cancelled = false
    const loadLocations = async () => {
      const response = await fetch("/api/locations")
      const payload = (await response.json().catch(() => null)) as { locations?: LocationRow[] } | null
      if (!response.ok || cancelled) return
      setLocations(payload?.locations ?? [])
    }

    void loadLocations()
    return () => {
      cancelled = true
    }
  }, [])

  const fetchReservations = useCallback(async () => {
    if (!typeId) return
    const dayStart = startOfDay(selectedDate).toISOString()
    const dayEnd = endOfDay(selectedDate).toISOString()
    const { data } = await supabase
      .from("reservations")
      .select("*")
      .gte("start_at", dayStart)
      .lte("start_at", dayEnd)
      .in("status", ["confirmed", "checked_in"])
    if (data) setReservations(data as Reservation[])
  }, [supabase, selectedDate, typeId])

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

  const resourcesBase = useMemo(() => {
    if (!selectedLocationId) return resources
    return resources.filter((resource) => {
      const metadata = (resource.metadata ?? {}) as { locationPathIds?: string[] }
      return Array.isArray(metadata.locationPathIds) && metadata.locationPathIds.includes(selectedLocationId)
    })
  }, [resources, selectedLocationId])

  const tagOptions = useMemo(() => {
    const s = new Set<string>()
    for (const r of resourcesBase) {
      const am = r.amenities as string[] | null
      if (Array.isArray(am)) am.forEach((a) => s.add(a))
    }
    return Array.from(s).sort()
  }, [resourcesBase])

  const filteredResources = useMemo(() => {
    if (filterTag === "all") return resourcesBase
    return resourcesBase.filter((r) => {
      const am = r.amenities as string[] | null
      return Array.isArray(am) && am.includes(filterTag)
    })
  }, [resourcesBase, filterTag])

  const hasBookableSlotsForDate = useCallback(
    (targetDate: Date, dayReservations: Reservation[], scopedResources: Resource[]) => {
      for (const resource of scopedResources) {
        const booking = normalizeResourceTypeBookingFields(
          resource.resource_types as Partial<ResourceTypeBookingFields> | null | undefined,
        )
        const advanceRestriction = getAdvanceRestriction(resource, targetDate, policies, booking)
        if (advanceRestriction.disabled) continue

        const stepMin = timeGranularityToMinutes(String(booking.time_granularity))
        const resourceSlots = bookingFieldsToSlotStarts(booking)

        for (const slot of resourceSlots) {
          if (!slotStartIsInTypeWindow(slot, booking)) continue

          const [slotHour, slotMinute] = slot.split(":").map(Number)
          const slotStart = setMinutes(setHours(targetDate, slotHour), slotMinute)
          const disabledByAdvance =
            !!advanceRestriction.minSlotStart &&
            slotStart.getTime() < advanceRestriction.minSlotStart.getTime()
          if (disabledByAdvance) continue

          if (isSlotAvailable(resource.id, slot, targetDate, dayReservations, stepMin)) {
            return true
          }
        }
      }

      return false
    },
    [policies],
  )

  useEffect(() => {
    if (loading) return
    if (!typeId) return
    if (didAutoShiftDefaultDateRef.current) return
    if (!isDefaultDaySelected) return
    if (filteredResources.length === 0) return
    if (hasBookableSlotsForDate(selectedDate, reservations, filteredResources)) return

    didAutoShiftDefaultDateRef.current = true
    let cancelled = false

    const moveToNextAvailableDate = async () => {
      const today = startOfDay(new Date())
      for (let offset = 1; offset <= BOOKING_CALENDAR_LOOKAHEAD_DAYS; offset += 1) {
        const candidateDate = addDays(today, offset)
        const dayStart = startOfDay(candidateDate).toISOString()
        const dayEnd = endOfDay(candidateDate).toISOString()
        const { data: candidateReservations } = await supabase
          .from("reservations")
          .select("*")
          .gte("start_at", dayStart)
          .lte("start_at", dayEnd)
          .in("status", ["confirmed", "checked_in"])

        if (!candidateReservations) continue

        const hasAvailability = hasBookableSlotsForDate(
          candidateDate,
          candidateReservations as Reservation[],
          filteredResources,
        )
        if (!hasAvailability) continue

        if (!cancelled) {
          setSelectedDate(candidateDate)
        }
        return
      }
    }

    void moveToNextAvailableDate()

    return () => {
      cancelled = true
    }
  }, [
    loading,
    typeId,
    isDefaultDaySelected,
    filteredResources,
    selectedDate,
    reservations,
    supabase,
    hasBookableSlotsForDate,
  ])

  const locationLevelOptions = useMemo(() => {
    const levels: Array<{ depth: number; options: LocationRow[] }> = []
    let parentId: string | null = null
    for (let depth = 0; depth < 20; depth += 1) {
      const options = locationChildrenMap.get(parentId) ?? []
      if (options.length === 0) break
      levels.push({ depth, options })
      const selectedAtDepth = selectedLocationByDepth[depth]
      if (!selectedAtDepth) break
      parentId = selectedAtDepth
    }
    return levels
  }, [locationChildrenMap, selectedLocationByDepth])

  const openBooking = (resource: Resource, slot: string) => {
    setSelectedResource(resource)
    setSelectedTimeSlot({
      start: slot,
      end: formatSlotEndLabel(selectedDate, slot, gridStepMinutes),
    })
    setDialogOpen(true)
  }

  const handleDialogClose = () => {
    setDialogOpen(false)
    setSelectedResource(null)
    setSelectedTimeSlot(null)
    fetchReservations()
    fetchTypeAndResources()
  }

  const slotFreeForResource = useCallback(
    (resource: Resource, slot: string) => {
      const booking = normalizeResourceTypeBookingFields(
        resource.resource_types as Partial<ResourceTypeBookingFields> | null | undefined,
      )
      const advanceRestriction = getAdvanceRestriction(resource, selectedDate, policies, booking)
      if (advanceRestriction.disabled) return false
      if (!slotStartIsInTypeWindow(slot, booking)) return false
      const [slotHour, slotMinute] = slot.split(":").map(Number)
      const slotStart = setMinutes(setHours(selectedDate, slotHour), slotMinute)
      if (
        advanceRestriction.minSlotStart &&
        slotStart.getTime() < advanceRestriction.minSlotStart.getTime()
      ) {
        return false
      }
      return isSlotAvailable(resource.id, slot, selectedDate, reservations, gridStepMinutes)
    },
    [selectedDate, reservations, policies, gridStepMinutes],
  )

  const availableResourcesForPickedSlot = useMemo(() => {
    if (!pickedSlot) return []
    return filteredResources.filter((r) => slotFreeForResource(r, pickedSlot))
  }, [filteredResources, pickedSlot, slotFreeForResource])

  if (notFound) {
    return (
      <div className="space-y-[var(--ds-space-3x)]">
        <Button
          variant="ghost"
          asChild
          className="w-fit rounded-[var(--ds-radius-m)] ds-type-global-xs text-[var(--ds-text-neutral-default)] hover:bg-[var(--ds-neutral-100)]"
        >
          <Link href="/dashboard">
            <ArrowLeft className="mr-[var(--ds-space-1x)] h-[var(--ds-space-2x)] w-[var(--ds-space-2x)]" />
            Volver al inicio
          </Link>
        </Button>
        <Card className="rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] bg-[var(--background)] py-[var(--ds-space-3x)] shadow-[var(--ds-shadow-4dp)]">
          <CardContent className="py-[var(--ds-space-5x)] text-center ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
            No existe el tipo de recurso &quot;{typeSlug}&quot;.
          </CardContent>
        </Card>
      </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)]">
        <div>
          <Button
            variant="ghost"
            size="sm"
            asChild
            className="mb-[var(--ds-space-1x)] -ml-[var(--ds-space-1x)] rounded-[var(--ds-radius-m)] ds-type-global-xs text-[var(--ds-blueprimary-800)] hover:bg-[var(--background)]"
          >
            <Link href="/dashboard">
              <ArrowLeft className="mr-[var(--ds-space-1x)] h-[var(--ds-space-2x)] w-[var(--ds-space-2x)]" />
              Otro tipo
            </Link>
          </Button>
          <h1 className="ds-type-global-l ds-type-semibold text-[var(--ds-blueprimary-800)]">Reservar: {typeName || "…"}</h1>
          <p className="mt-[var(--ds-space-05x)] ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
            Elige cómo quieres reservar y filtra por ubicación, día y etiquetas.
          </p>
        </div>
      </div>

      <Card className="rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] bg-[var(--background)] shadow-[var(--ds-shadow-4dp)]">
        <CardHeader className="border-b border-[var(--ds-neutral-200)] px-[var(--ds-space-3x)] pb-[var(--ds-space-2x)] pt-[var(--ds-space-3x)]">
          <CardTitle className="ds-type-global-s ds-type-semibold text-[var(--ds-text-neutral-default)]">Filtros</CardTitle>
          <CardDescription className="ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
            Ubicación → día (se elige el primer día con horarios válidos según la antelación del tipo) → etiqueta
          </CardDescription>
        </CardHeader>
        <CardContent className="flex flex-wrap items-end gap-[var(--ds-space-2x)] px-[var(--ds-space-3x)] py-[var(--ds-space-3x)]">
          {locationLevelOptions.length > 0 && (
            <div className="space-y-[var(--ds-space-05x)]">
              <span className="ds-type-global-xxs text-[var(--ds-text-neutral-lighter)]">Ubicación</span>
              <div className="flex flex-wrap gap-[var(--ds-space-1x)]">
                {locationLevelOptions.map((level, index) => (
                  <Select
                    key={level.depth}
                    value={selectedLocationByDepth[index] ?? "__none__"}
                    onValueChange={(value) => {
                      setSelectedLocationByDepth((prev) => {
                        const next = prev.slice(0, index)
                        if (value !== "__none__") next[index] = value
                        return next
                      })
                    }}
                  >
                    <SelectTrigger className="h-[var(--ds-space-5x)] w-[calc(var(--ds-space-5x)*5)] rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]">
                      <SelectValue placeholder={`Nivel ${index + 1}`} />
                    </SelectTrigger>
                    <SelectContent className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-200)] shadow-[var(--ds-shadow-8dp)]">
                      <SelectItem value="__none__" className="ds-type-global-xs">Sin selección</SelectItem>
                      {level.options.map((location) => (
                        <SelectItem key={location.id} value={location.id} className="ds-type-global-xs">
                          {location.value}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                ))}
              </div>
            </div>
          )}
          <div className="space-y-[var(--ds-space-05x)]">
            <span className="ds-type-global-xxs text-[var(--ds-text-neutral-lighter)]">Día</span>
            <Popover>
              <PopoverTrigger asChild>
                <Button
                  variant="outline"
                  className="h-[var(--ds-space-5x)] w-[calc(var(--ds-space-5x)*5)] justify-start rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] text-left ds-type-global-xs text-[var(--ds-text-neutral-default)]"
                >
                  <CalendarIcon className="mr-[var(--ds-space-1x)] h-[var(--ds-space-2x)] w-[var(--ds-space-2x)]" />
                  {format(selectedDate, "EEE d MMM yyyy", { locale: es })}
                </Button>
              </PopoverTrigger>
              <PopoverContent
                className="w-auto rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] p-0 shadow-[var(--ds-shadow-8dp)]"
                align="start"
              >
                <Calendar
                  mode="single"
                  selected={selectedDate}
                  onSelect={(d) => d && setSelectedDate(d)}
                  disabled={(date) => isBefore(startOfDay(date), startOfDay(new Date()))}
                  locale={es}
                />
              </PopoverContent>
            </Popover>
          </div>
          <div className="space-y-[var(--ds-space-05x)]">
            <span className="ds-type-global-xxs text-[var(--ds-text-neutral-lighter)]">Etiqueta</span>
            <Select value={filterTag} onValueChange={setFilterTag}>
              <SelectTrigger className="h-[var(--ds-space-5x)] w-[calc(var(--ds-space-5x)*5)] rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]">
                <SelectValue placeholder="Todas" />
              </SelectTrigger>
              <SelectContent className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-200)] shadow-[var(--ds-shadow-8dp)]">
                <SelectItem value="all" className="ds-type-global-xs">Todas las etiquetas</SelectItem>
                {tagOptions.map((t) => (
                  <SelectItem key={t} value={t} className="ds-type-global-xs">
                    {t}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </CardContent>
      </Card>

      <div className="space-y-[var(--ds-space-1x)]">
        <span className="ds-type-global-xs ds-type-semibold text-[var(--ds-text-neutral-default)]">Flujo de reserva</span>
        <ToggleGroup
          type="single"
          value={flow}
          onValueChange={(v) => {
            if (v === "resource-first" || v === "time-first") {
              setFlow(v)
              setPickedSlot(null)
              setExpandedResourceId(null)
            }
          }}
          className="justify-start gap-[var(--ds-space-1x)]"
        >
          <ToggleGroupItem
            value="resource-first"
            aria-label="Espacio primero"
            className="h-[var(--ds-space-5x)] gap-[var(--ds-space-1x)] rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] px-[var(--ds-space-2x)] ds-type-global-xs text-[var(--ds-text-neutral-default)] data-[state=on]:border-[var(--ds-brand-400)] data-[state=on]:bg-[var(--ds-blueprimary-100)] data-[state=on]:text-[var(--ds-blueprimary-800)]"
          >
            <ListOrdered className="h-[var(--ds-space-2x)] w-[var(--ds-space-2x)]" />
            Primero el espacio
          </ToggleGroupItem>
          <ToggleGroupItem
            value="time-first"
            aria-label="Horario primero"
            className="h-[var(--ds-space-5x)] gap-[var(--ds-space-1x)] rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] px-[var(--ds-space-2x)] ds-type-global-xs text-[var(--ds-text-neutral-default)] data-[state=on]:border-[var(--ds-brand-400)] data-[state=on]:bg-[var(--ds-blueprimary-100)] data-[state=on]:text-[var(--ds-blueprimary-800)]"
          >
            <CalendarClock className="h-[var(--ds-space-2x)] w-[var(--ds-space-2x)]" />
            Primero día y hora
          </ToggleGroupItem>
        </ToggleGroup>
      </div>

      {loading ? (
        <div className="flex justify-center py-[calc(var(--ds-space-3x)*2)]">
          <div className="h-[var(--ds-space-4x)] w-[var(--ds-space-4x)] animate-spin rounded-full border-[var(--ds-space-05x)] border-[var(--ds-brand-400)] border-t-transparent" />
        </div>
      ) : flow === "resource-first" ? (
        <div className="space-y-[var(--ds-space-2x)]">
          {filteredResources.map((resource) => (
            <Card
              key={resource.id}
              className="rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] bg-[var(--background)] shadow-[var(--ds-shadow-4dp)]"
            >
              <CardHeader className="pb-[var(--ds-space-2x)]">
                <div className="flex flex-wrap items-start justify-between gap-[var(--ds-space-1x)]">
                  <div className="flex items-center gap-[var(--ds-space-2x)]">
                    <div className="flex h-[var(--ds-space-5x)] w-[var(--ds-space-5x)] items-center justify-center rounded-[var(--ds-radius-m)] bg-[var(--ds-blueprimary-100)] text-[var(--ds-brand-400)]">
                      <DynamicIcon
                        name={resource.resource_types?.icon}
                        className="h-[calc(var(--ds-space-2x)+var(--ds-space-05x))] w-[calc(var(--ds-space-2x)+var(--ds-space-05x))]"
                      />
                    </div>
                    <div>
                      <CardTitle className="ds-type-global-s ds-type-semibold text-[var(--ds-text-neutral-default)]">
                        {resource.name}
                      </CardTitle>
                      <CardDescription className="mt-[var(--ds-space-05x)] flex flex-wrap items-center gap-[var(--ds-space-1x)] ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
                        <MapPin className="h-[var(--ds-space-15x)] w-[var(--ds-space-15x)] shrink-0" />
                        {getResourceLocationPathLabel(resource) ?? "Sin ubicación jerárquica"}
                        {resource.floor && <span>• {resource.floor}</span>}
                      </CardDescription>
                    </div>
                  </div>
                  <div className="flex flex-wrap gap-[var(--ds-space-05x)]">
                    {(resource.amenities as string[])?.map((a) => (
                      <Badge
                        key={a}
                        className="rounded-[var(--ds-radius-s)] border-0 bg-[var(--ds-neutral-100)] ds-type-global-xxs text-[var(--ds-text-neutral-default)]"
                      >
                        {a}
                      </Badge>
                    ))}
                  </div>
                </div>
                <Button
                  variant="outline"
                  size="sm"
                  className={cn(
                    "h-[var(--ds-space-5x)] rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] px-[var(--ds-space-2x)] ds-type-global-xs",
                    expandedResourceId === resource.id
                      ? "border-[var(--ds-brand-400)] bg-[var(--ds-blueprimary-100)] text-[var(--ds-blueprimary-800)]"
                      : "text-[var(--ds-text-neutral-default)]"
                  )}
                  onClick={() =>
                    setExpandedResourceId(expandedResourceId === resource.id ? null : resource.id)
                  }
                >
                  <Clock className="mr-[var(--ds-space-1x)] h-[var(--ds-space-2x)] w-[var(--ds-space-2x)]" />
                  {expandedResourceId === resource.id ? "Ocultar horarios" : "Elegir horario"}
                </Button>
              </CardHeader>
              {expandedResourceId === resource.id && (
                <CardContent>
                  <div className="flex flex-wrap gap-[var(--ds-space-05x)]">
                    {slotStarts.map((slot) => {
                      const ok = slotFreeForResource(resource, slot)
                      return (
                        <button
                          key={slot}
                          type="button"
                          disabled={!ok}
                          onClick={() => ok && openBooking(resource, slot)}
                          className={cn(
                            "rounded-[var(--ds-radius-s)] border px-[var(--ds-space-1x)] py-[var(--ds-space-05x)] ds-type-global-xxs transition-colors",
                            ok
                              ? "cursor-pointer border-[var(--ds-brand-400)] bg-[var(--ds-blueprimary-100)] text-[var(--ds-blueprimary-800)] hover:bg-[var(--ds-brand-400)] hover:text-[var(--background)]"
                              : "cursor-not-allowed border-[var(--ds-neutral-200)] bg-[var(--ds-neutral-100)] text-[var(--ds-text-neutral-lighter)]"
                          )}
                        >
                          {slot}
                        </button>
                      )
                    })}
                  </div>
                </CardContent>
              )}
            </Card>
          ))}
          {filteredResources.length === 0 && (
            <Card className="rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] bg-[var(--background)] shadow-[var(--ds-shadow-4dp)]">
              <CardContent className="py-[var(--ds-space-5x)] text-center ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
                No hay recursos con estos filtros.
              </CardContent>
            </Card>
          )}
        </div>
      ) : (
        <div className="space-y-[var(--ds-space-3x)]">
          <Card className="rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] bg-[var(--background)] shadow-[var(--ds-shadow-4dp)]">
            <CardHeader>
              <CardTitle className="ds-type-global-s ds-type-semibold text-[var(--ds-text-neutral-default)]">1. Elige horario</CardTitle>
              <CardDescription className="ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
                Día: {format(selectedDate, "EEEE d MMMM", { locale: es })}
              </CardDescription>
            </CardHeader>
            <CardContent>
              <div className="flex flex-wrap gap-[var(--ds-space-05x)]">
                {slotStarts.map((slot) => {
                  const any = filteredResources.some((r) => slotFreeForResource(r, slot))
                  const selected = pickedSlot === slot
                  return (
                    <button
                      key={slot}
                      type="button"
                      disabled={!any}
                      onClick={() => any && setPickedSlot(slot)}
                      className={cn(
                        "rounded-[var(--ds-radius-s)] border px-[var(--ds-space-1x)] py-[var(--ds-space-05x)] ds-type-global-xxs transition-colors",
                        !any && "opacity-40 cursor-not-allowed",
                        any && !selected && "cursor-pointer border-[var(--ds-brand-400)] bg-[var(--ds-blueprimary-100)] text-[var(--ds-blueprimary-800)] hover:bg-[var(--ds-brand-400)] hover:text-[var(--background)]",
                        selected && "border-[var(--ds-brand-400)] bg-[var(--ds-brand-400)] text-[var(--background)]"
                      )}
                    >
                      {slot}
                    </button>
                  )
                })}
              </div>
            </CardContent>
          </Card>

          {pickedSlot && (
            <Card className="rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] bg-[var(--background)] shadow-[var(--ds-shadow-4dp)]">
              <CardHeader>
                <CardTitle className="ds-type-global-s ds-type-semibold text-[var(--ds-text-neutral-default)]">
                  2. Elige espacio disponible a las {pickedSlot}
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-[var(--ds-space-1x)]">
                {availableResourcesForPickedSlot.length === 0 ? (
                  <p className="ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
                    Ningún espacio libre en ese horario.
                  </p>
                ) : (
                  availableResourcesForPickedSlot.map((resource) => (
                    <button
                      key={resource.id}
                      type="button"
                      onClick={() => openBooking(resource, pickedSlot)}
                      className="flex w-full items-center justify-between rounded-[var(--ds-radius-l)] border border-[var(--ds-neutral-200)] bg-[var(--background)] p-[var(--ds-space-2x)] text-left transition-colors hover:bg-[var(--ds-neutral-100)]"
                    >
                      <div className="flex items-center gap-[var(--ds-space-2x)]">
                        <div className="flex h-[var(--ds-space-4x)] w-[var(--ds-space-4x)] items-center justify-center rounded-[var(--ds-radius-m)] bg-[var(--ds-blueprimary-100)] text-[var(--ds-brand-400)]">
                          <DynamicIcon
                            name={resource.resource_types?.icon}
                            className="h-[var(--ds-space-2x)] w-[var(--ds-space-2x)]"
                          />
                        </div>
                        <div>
                          <p className="ds-type-global-xs ds-type-semibold text-[var(--ds-text-neutral-default)]">{resource.name}</p>
                          <p className="ds-type-global-xxs text-[var(--ds-text-neutral-lighter)]">
                            {getResourceLocationPathLabel(resource) ?? "Sin ubicación jerárquica"}
                            {resource.floor && ` • ${resource.floor}`}
                          </p>
                        </div>
                      </div>
                      <Badge className="rounded-[var(--ds-radius-s)] border-0 bg-[var(--ds-blueprimary-100)] ds-type-global-xxs ds-type-semibold text-[var(--ds-blueprimary-800)]">
                        Reservar
                      </Badge>
                    </button>
                  ))
                )}
              </CardContent>
            </Card>
          )}
        </div>
      )}

      <ReservationDialog
        open={dialogOpen}
        onOpenChange={handleDialogClose}
        resource={selectedResource}
        date={selectedDate}
        initialTimeSlot={selectedTimeSlot}
        bookingFields={typeBookingFields}
      />
    </div>
  )
}
