"use client"

import { useState, useEffect, useMemo } from "react"
import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Textarea } from "@/components/ui/textarea"
import { FieldGroup, Field, FieldLabel } from "@/components/ui/field"
import { Spinner } from "@/components/ui/spinner"
import { Badge } from "@/components/ui/badge"
import { Switch } from "@/components/ui/switch"
import { format, setHours, setMinutes, addMinutes, isValid } from "date-fns"
import { es } from "date-fns/locale"
import { Clock, MapPin, Users, Calendar as CalendarIcon, Check, AlertCircle } from "lucide-react"
import type { Database } from "@/lib/supabase/database.types"
import { getResourceLocationPathLabel } from "@/lib/resources/location"
import {
  bookingFieldsToSlotStarts,
  buildDurationOptionsMinutes,
  getFullDayBookingRange,
  type ResourceTypeBookingFields,
} from "@/lib/booking"

type Resource = Database["public"]["Tables"]["resources"]["Row"] & {
  resource_types: { name: string; slug: string } | null
}

const TIME_HH_MM_REGEX = /^([01]\d|2[0-3]):([0-5]\d)$/

function isValidTimeHHmm(value: string): boolean {
  return TIME_HH_MM_REGEX.test(value)
}

function buildStartDate(date: Date, startTime: string): Date | null {
  if (!isValid(date) || !isValidTimeHHmm(startTime)) return null
  const [hours, minutes] = startTime.split(":").map(Number)
  const startDate = setMinutes(setHours(date, hours), minutes)
  return isValid(startDate) ? startDate : null
}

function formatDurationLabel(minutes: number): string {
  if (minutes >= 60 && minutes % 60 === 0) {
    const h = minutes / 60
    return h === 1 ? "1 hora" : `${h} horas`
  }
  if (minutes >= 60) {
    const h = Math.floor(minutes / 60)
    const m = minutes % 60
    return m === 0 ? (h === 1 ? "1 hora" : `${h} horas`) : `${h} h ${m} min`
  }
  return `${minutes} minutos`
}

interface ReservationDialogProps {
  open: boolean
  onOpenChange: () => void
  resource: Resource | null
  date: Date
  initialTimeSlot: { start: string; end: string } | null
  bookingFields: ResourceTypeBookingFields
}

export function ReservationDialog({
  open,
  onOpenChange,
  resource,
  date,
  initialTimeSlot,
  bookingFields,
}: ReservationDialogProps) {
  const [loading, setLoading] = useState(false)
  const [success, setSuccess] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [startTime, setStartTime] = useState(initialTimeSlot?.start || "09:00")
  const [duration, setDuration] = useState(60)
  const [notes, setNotes] = useState("")
  const [fullDay, setFullDay] = useState(false)

  const slotStarts = useMemo(() => bookingFieldsToSlotStarts(bookingFields), [bookingFields])

  const fullDayRange = useMemo(() => getFullDayBookingRange(date, bookingFields), [date, bookingFields])

  const durationOptions = useMemo(() => {
    if (fullDay) return []
    return buildDurationOptionsMinutes({ startTimeHHmm: startTime, date, fields: bookingFields })
  }, [fullDay, startTime, date, bookingFields])

  useEffect(() => {
    if (!open) return
    setSuccess(false)
    setError(null)
    setNotes("")
    setFullDay(false)
    const fallbackStart = slotStarts[0] ?? "09:00"
    if (initialTimeSlot) {
      setStartTime(isValidTimeHHmm(initialTimeSlot.start) ? initialTimeSlot.start : fallbackStart)
    } else {
      setStartTime(fallbackStart)
    }
  }, [initialTimeSlot, open, slotStarts])

  useEffect(() => {
    if (!open || fullDay) return
    if (durationOptions.length === 0) return
    setDuration((d) => {
      const safeCurrent = Number.isFinite(d) && d > 0 ? d : 0
      return durationOptions.includes(safeCurrent) ? safeCurrent : durationOptions[0]
    })
  }, [open, fullDay, durationOptions])

  const getEndTime = () => {
    if (fullDay) return isValid(fullDayRange.end) ? format(fullDayRange.end, "HH:mm") : "--:--"

    const startDate = buildStartDate(date, startTime)
    if (!startDate) return "--:--"

    const safeDuration = Number.isFinite(duration) && duration > 0 ? duration : (durationOptions[0] ?? 0)
    if (safeDuration <= 0) return "--:--"

    const endDate = addMinutes(startDate, safeDuration)
    if (!isValid(endDate)) return "--:--"
    return format(endDate, "HH:mm")
  }

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    setLoading(true)
    setError(null)
    if (!resource) {
      setError("Recurso inválido")
      setLoading(false)
      return
    }

    let startAt: Date
    let endAt: Date
    if (fullDay) {
      startAt = fullDayRange.start
      endAt = fullDayRange.end
      if (!isValid(startAt) || !isValid(endAt) || endAt.getTime() <= startAt.getTime()) {
        setError("La ventana horaria del recurso es inválida. Revisá la configuración del tipo.")
        setLoading(false)
        return
      }
    } else {
      const parsedStartAt = buildStartDate(date, startTime)
      const safeDuration = Number.isFinite(duration) && duration > 0 ? duration : NaN
      if (!parsedStartAt || !Number.isFinite(safeDuration)) {
        setError("Seleccioná una hora y duración válidas para continuar.")
        setLoading(false)
        return
      }

      startAt = parsedStartAt
      endAt = addMinutes(startAt, safeDuration)
      if (!isValid(endAt) || endAt.getTime() <= startAt.getTime()) {
        setError("No se pudo calcular el horario de fin. Probá con otra combinación.")
        setLoading(false)
        return
      }
    }

    const response = await fetch("/api/reservations", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        resourceId: resource.id,
        startAt: startAt.toISOString(),
        endAt: endAt.toISOString(),
        notes: notes || null,
      }),
    })
    const payload = (await response.json().catch(() => null)) as { error?: string } | null

    if (!response.ok) {
      setError(payload?.error ?? "Error al crear la reserva")
      setLoading(false)
      return
    }

    setSuccess(true)
    setLoading(false)

    setTimeout(() => {
      onOpenChange()
    }, 1500)
  }

  if (!resource) return null

  const summaryStart = fullDay
    ? (isValid(fullDayRange.start) ? format(fullDayRange.start, "HH:mm") : "--:--")
    : (isValidTimeHHmm(startTime) ? startTime : "--:--")
  const summaryEnd = getEndTime()
  const summaryDurationLabel = fullDay
    ? "Día completo (toda la ventana)"
    : (Number.isFinite(duration) && duration > 0 ? formatDurationLabel(duration) : "Duración inválida")
  const canSubmit = fullDay
    ? isValid(fullDayRange.start) &&
      isValid(fullDayRange.end) &&
      fullDayRange.end.getTime() > fullDayRange.start.getTime()
    : durationOptions.length > 0 && isValidTimeHHmm(startTime) && Number.isFinite(duration) && duration > 0

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[425px] rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] bg-white shadow-[var(--ds-shadow-8dp)]">
        {success ? (
          <div className="flex flex-col items-center justify-center py-[var(--ds-space-4x)]">
            <div className="mb-[var(--ds-space-2x)] flex h-16 w-16 items-center justify-center rounded-full bg-[var(--ds-success-100)] text-[var(--ds-success-700)]">
              <Check className="h-8 w-8" />
            </div>
            <h3 className="mb-[var(--ds-space-1x)] ds-type-global-m ds-type-semibold text-[var(--ds-text-neutral-default)]">
              Reserva confirmada
            </h3>
            <p className="text-center ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
              Tu reserva de {resource.name} ha sido creada exitosamente
            </p>
          </div>
        ) : (
          <>
            <DialogHeader>
              <DialogTitle className="ds-type-global-m ds-type-semibold text-[var(--ds-text-neutral-default)]">
                Nueva Reserva
              </DialogTitle>
              <DialogDescription className="ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
                Confirma los detalles de tu reserva
              </DialogDescription>
            </DialogHeader>

            <div className="space-y-[var(--ds-space-1x)] rounded-[var(--ds-radius-m)] border border-[var(--ds-neutral-200)] bg-[var(--ds-blueprimary-100)] p-[var(--ds-space-2x)]">
              <h4 className="ds-type-global-s ds-type-semibold text-[var(--ds-blueprimary-800)]">
                {resource.name}
              </h4>
              <div className="flex flex-wrap gap-[var(--ds-space-2x)] ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
                <span className="flex items-center gap-1">
                  <MapPin className="h-4 w-4" />
                  {getResourceLocationPathLabel(resource) ?? "Sin ubicacion jerarquica"}
                  {resource.floor && ` • ${resource.floor}`}
                </span>
                {resource.capacity && resource.capacity > 1 && (
                  <span className="flex items-center gap-1">
                    <Users className="h-4 w-4" />
                    {resource.capacity} personas
                  </span>
                )}
                <span className="flex items-center gap-1">
                  <CalendarIcon className="h-4 w-4" />
                  <span className="capitalize">
                    {format(date, "EEEE d 'de' MMMM", { locale: es })}
                  </span>
                </span>
              </div>
              {(resource.amenities as string[])?.length > 0 && (
                <div className="flex flex-wrap gap-[var(--ds-space-05x)] pt-[var(--ds-space-05x)]">
                  {(resource.amenities as string[]).map((amenity) => (
                    <Badge
                      key={amenity}
                      className="rounded-[var(--ds-radius-s)] border-0 bg-white ds-type-global-xxs text-[var(--ds-text-neutral-default)] hover:bg-white"
                    >
                      {amenity}
                    </Badge>
                  ))}
                </div>
              )}
            </div>

            <form onSubmit={handleSubmit}>
              <FieldGroup className="gap-[var(--ds-space-2x)] py-[var(--ds-space-3x)]">
                <div className="flex items-center justify-between rounded-[var(--ds-radius-m)] border border-[var(--ds-neutral-200)] px-[var(--ds-space-2x)] py-[var(--ds-space-2x)]">
                  <div>
                    <p className="ds-type-global-xs ds-type-semibold text-[var(--ds-text-neutral-default)]">
                      Día completo
                    </p>
                    <p className="ds-type-global-xxs text-[var(--ds-text-neutral-lighter)]">
                      Bloquea toda la ventana de reserva del día
                    </p>
                  </div>
                  <Switch checked={fullDay} onCheckedChange={setFullDay} />
                </div>

                <div className="grid grid-cols-2 gap-[var(--ds-space-2x)]">
                  <Field>
                    <FieldLabel className="ds-type-global-xs ds-type-semibold text-[var(--ds-text-neutral-default)]">
                      Hora inicio
                    </FieldLabel>
                    <Select value={startTime} onValueChange={setStartTime} disabled={fullDay}>
                      <SelectTrigger className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]">
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        {slotStarts.map((time) => (
                          <SelectItem key={time} value={time}>
                            {time}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </Field>

                  <Field>
                    <FieldLabel className="ds-type-global-xs ds-type-semibold text-[var(--ds-text-neutral-default)]">
                      Duracion
                    </FieldLabel>
                    <Select
                      value={duration.toString()}
                      onValueChange={(v) => {
                        const nextDuration = Number.parseInt(v, 10)
                        if (Number.isFinite(nextDuration) && nextDuration > 0) {
                          setDuration(nextDuration)
                        }
                      }}
                      disabled={fullDay}
                    >
                      <SelectTrigger className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]">
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        {durationOptions.map((d) => (
                          <SelectItem key={d} value={d.toString()}>
                            {formatDurationLabel(d)}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </Field>
                </div>

                <div className="flex items-center gap-[var(--ds-space-2x)] rounded-[var(--ds-radius-m)] border border-[var(--ds-brand-400)] bg-[var(--ds-blueprimary-100)] p-[var(--ds-space-2x)]">
                  <Clock className="h-5 w-5 text-[var(--ds-brand-400)]" />
                  <div>
                    <p className="ds-type-global-xs ds-type-semibold text-[var(--ds-text-neutral-default)]">
                      {summaryStart} - {summaryEnd}
                    </p>
                    <p className="ds-type-global-xxs text-[var(--ds-text-neutral-lighter)]">
                      {summaryDurationLabel}
                    </p>
                  </div>
                </div>

                <Field>
                  <FieldLabel className="ds-type-global-xs ds-type-semibold text-[var(--ds-text-neutral-default)]">
                    Notas (opcional)
                  </FieldLabel>
                  <Textarea
                    value={notes}
                    onChange={(e) => setNotes(e.target.value)}
                    placeholder="Ej: Reunión con cliente, necesito café..."
                    rows={2}
                    className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]"
                  />
                </Field>

                {error && (
                  <div className="flex items-center gap-[var(--ds-space-1x)] ds-type-global-xs text-[var(--ds-error-700)]">
                    <AlertCircle className="h-4 w-4" />
                    {error}
                  </div>
                )}
              </FieldGroup>

              <DialogFooter>
                <Button
                  type="button"
                  variant="outline"
                  onClick={onOpenChange}
                  className="rounded-[var(--ds-radius-m)] border-[var(--ds-neutral-300)] ds-type-global-xs text-[var(--ds-text-neutral-default)]"
                >
                  Cancelar
                </Button>
                <Button
                  type="submit"
                  disabled={loading || !canSubmit}
                  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)]"
                >
                  {loading && <Spinner className="mr-2" />}
                  Confirmar reserva
                </Button>
              </DialogFooter>
            </form>
          </>
        )}
      </DialogContent>
    </Dialog>
  )
}
