"use client"

import { useEffect, useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import { createClient } from "@/lib/supabase/client"
import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Switch } from "@/components/ui/switch"
import { FieldGroup, Field, FieldLabel } from "@/components/ui/field"
import { Spinner } from "@/components/ui/spinner"
import { toast } from "sonner"
import type { Database } from "@/lib/supabase/database.types"
import { LucideIconSelect } from "@/components/ui/lucide-icon-select"
import {
  minutesFromValueUnit,
  type RuleUnit,
  valueUnitFromMinutes,
} from "@/lib/reservations/rules"
import { parseTimeToMinutesSinceMidnight } from "@/lib/booking"

type ResourceType = Database["public"]["Tables"]["resource_types"]["Row"]
type ResourceTypeWithConfig = ResourceType & {
  reminders_enabled?: boolean | null
}

type SlotSize = "15min" | "30min" | "1h"
type TimeGranularity = "5min" | "10min" | "15min" | "30min" | "60min"

const SLOT_SIZE_OPTIONS: { value: SlotSize; label: string }[] = [
  { value: "15min", label: "15 minutos" },
  { value: "30min", label: "30 minutos" },
  { value: "1h", label: "1 hora" },
]

function timeInputValueFromDb(t: string | null | undefined): string {
  if (!t) return "08:00"
  return t.length >= 5 ? t.slice(0, 5) : t
}

function timeForDbFromInput(v: string): string {
  if (!v) return "08:00:00"
  return v.length === 5 ? `${v}:00` : v
}

const GRANULARITY_OPTIONS: { value: TimeGranularity; label: string }[] = [
  { value: "5min", label: "5 minutos" },
  { value: "10min", label: "10 minutos" },
  { value: "15min", label: "15 minutos" },
  { value: "30min", label: "30 minutos" },
  { value: "60min", label: "1 hora" },
]

function slugify(s: string) {
  return s
    .toLowerCase()
    .trim()
    .replace(/\s+/g, "-")
    .replace(/[^a-z0-9-]/g, "")
}

export function ResourceTypeDialog({
  children,
  resourceType,
  onSaved,
}: {
  children: React.ReactNode
  resourceType?: ResourceType | null
  onSaved?: () => void
}) {
  const router = useRouter()
  const supabase = useMemo(() => createClient(), [])

  const [open, setOpen] = useState(false)
  const [loading, setLoading] = useState(false)
  const [slug, setSlug] = useState("")
  const [name, setName] = useState("")
  const [icon, setIcon] = useState("")
  const [description, setDescription] = useState("")
  const [isActive, setIsActive] = useState(true)
  const [slugTouched, setSlugTouched] = useState(false)

  const [bookingWindowStart, setBookingWindowStart] = useState("08:00")
  const [bookingWindowEnd, setBookingWindowEnd] = useState("20:00")
  const [slotSize, setSlotSize] = useState<SlotSize>("30min")
  const [timeGranularity, setTimeGranularity] = useState<TimeGranularity>("15min")

  const [remindersEnabled, setRemindersEnabled] = useState(false)
  const [bookingAdvanceValue, setBookingAdvanceValue] = useState(10)
  const [bookingAdvanceUnit, setBookingAdvanceUnit] = useState<RuleUnit>("days")
  const [cancellationValue, setCancellationValue] = useState(5)
  const [cancellationUnit, setCancellationUnit] = useState<RuleUnit>("hours")
  const [editingValue, setEditingValue] = useState(5)
  const [editingUnit, setEditingUnit] = useState<RuleUnit>("hours")

  useEffect(() => {
    if (!open) return

    let cancelled = false

    const load = async () => {
      if (resourceType) {
        const typedType = resourceType as ResourceTypeWithConfig
        setSlug(resourceType.slug)
        setName(resourceType.name)
        setIcon(resourceType.icon || "")
        setDescription(resourceType.description || "")
        setIsActive(resourceType.is_active ?? true)
        setSlugTouched(true)
        setBookingWindowStart(timeInputValueFromDb(resourceType.booking_window_start))
        setBookingWindowEnd(timeInputValueFromDb(resourceType.booking_window_end))
        const rawSlot = resourceType.slot_size ?? "30min"
        setSlotSize(rawSlot === "15min" || rawSlot === "30min" || rawSlot === "1h" ? rawSlot : "30min")
        setTimeGranularity((resourceType.time_granularity as TimeGranularity) ?? "15min")
        setRemindersEnabled(typedType.reminders_enabled ?? false)

        const { data: policy } = await supabase
          .from("resource_policies")
          .select("*")
          .eq("resource_type_id", resourceType.id)
          .limit(1)
          .maybeSingle()

        if (cancelled) return

        const policyRow = (policy ?? {}) as {
          booking_advance_minutes?: number | null
          cancellation_deadline_minutes?: number | null
          editing_deadline_minutes?: number | null
        }

        const booking = valueUnitFromMinutes(policyRow.booking_advance_minutes, {
          value: 10,
          unit: "days",
        })
        setBookingAdvanceValue(booking.value)
        setBookingAdvanceUnit(booking.unit)

        const cancellation = valueUnitFromMinutes(policyRow.cancellation_deadline_minutes, {
          value: 5,
          unit: "hours",
        })
        setCancellationValue(cancellation.value)
        setCancellationUnit(cancellation.unit)

        const editing = valueUnitFromMinutes(policyRow.editing_deadline_minutes, {
          value: cancellation.value,
          unit: cancellation.unit,
        })
        setEditingValue(editing.value)
        setEditingUnit(editing.unit)
        return
      }

      setSlug("")
      setName("")
      setIcon("")
      setDescription("")
      setIsActive(true)
      setSlugTouched(false)
      setBookingWindowStart("08:00")
      setBookingWindowEnd("20:00")
      setSlotSize("30min")
      setTimeGranularity("15min")
      setRemindersEnabled(false)
      setBookingAdvanceValue(10)
      setBookingAdvanceUnit("days")
      setCancellationValue(5)
      setCancellationUnit("hours")
      setEditingValue(5)
      setEditingUnit("hours")
    }

    void load()

    return () => {
      cancelled = true
    }
  }, [open, resourceType, supabase])

  useEffect(() => {
    if (resourceType || slugTouched) return
    if (name) setSlug(slugify(name))
  }, [name, resourceType, slugTouched])

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    const finalSlug = slugify(slug) || slugify(name)
    if (!finalSlug || !name.trim()) return

    const ws = timeForDbFromInput(bookingWindowStart)
    const we = timeForDbFromInput(bookingWindowEnd)
    if (parseTimeToMinutesSinceMidnight(we) <= parseTimeToMinutesSinceMidnight(ws)) {
      toast.error("El horario de fin debe ser mayor al de inicio")
      return
    }

    setLoading(true)

    const row = {
      slug: finalSlug,
      name: name.trim(),
      icon: icon.trim() || null,
      description: description.trim() || null,
      is_active: isActive,
      booking_unit: "hour" as const,
      booking_window_start: ws,
      booking_window_end: we,
      slot_size: slotSize,
      time_granularity: timeGranularity,
      reminders_enabled: remindersEnabled,
    }

    const bookingAdvanceMinutes = minutesFromValueUnit(bookingAdvanceValue, bookingAdvanceUnit)
    const cancellationDeadlineMinutes = minutesFromValueUnit(cancellationValue, cancellationUnit)
    const editingDeadlineMinutes = minutesFromValueUnit(editingValue, editingUnit)

    let targetTypeId = resourceType?.id ?? null

    if (resourceType) {
      const { error } = await (supabase.from("resource_types") as any).update(row).eq("id", resourceType.id)
      if (error) {
        toast.error(error.message)
        setLoading(false)
        return
      }
      targetTypeId = resourceType.id
    } else {
      const { data: createdType, error } = await (supabase.from("resource_types") as any)
        .insert(row)
        .select("id")
        .maybeSingle()
      if (error) {
        if (error.code === "42501") {
          toast.error("Sin permiso. Ejecuta scripts/003_rls_resources_write_authenticated.sql en Supabase.")
        } else {
          toast.error(error.message)
        }
        setLoading(false)
        return
      }
      targetTypeId = createdType?.id ?? null
    }

    if (!targetTypeId) {
      toast.error("No se pudo resolver el tipo de recurso")
      setLoading(false)
      return
    }

    const policyPayload = {
      resource_type_id: targetTypeId,
      booking_advance_minutes: bookingAdvanceMinutes,
      cancellation_deadline_minutes: cancellationDeadlineMinutes,
      editing_deadline_minutes: editingDeadlineMinutes,
      max_advance_days: Math.max(1, Math.ceil(bookingAdvanceMinutes / (24 * 60))),
    }

    const { data: existingPolicy } = await supabase
      .from("resource_policies")
      .select("id")
      .eq("resource_type_id", targetTypeId)
      .limit(1)
      .maybeSingle()

    if (existingPolicy?.id) {
      const { error: policyError } = await (supabase.from("resource_policies") as any)
        .update(policyPayload)
        .eq("id", existingPolicy.id)
      if (policyError) {
        toast.error(policyError.message)
        setLoading(false)
        return
      }
    } else {
      const { error: policyError } = await (supabase.from("resource_policies") as any).insert(policyPayload)
      if (policyError) {
        toast.error(policyError.message)
        setLoading(false)
        return
      }
    }

    setLoading(false)
    setOpen(false)
    onSaved?.()
    router.refresh()
  }

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>{children}</DialogTrigger>
      <DialogContent className="flex max-h-[85vh] flex-col sm:max-w-[480px]">
        <DialogHeader className="flex-shrink-0">
          <DialogTitle>{resourceType ? "Editar tipo de recurso" : "Nuevo tipo de recurso"}</DialogTitle>
          <DialogDescription>
            Define categorías reservables (salas, estacionamiento, phone booth, etc.)
          </DialogDescription>
        </DialogHeader>
        <form onSubmit={handleSubmit} className="flex min-h-0 flex-1 flex-col">
          <div className="flex-1 overflow-y-auto pr-1">
          <FieldGroup className="gap-4 py-4">
            <Field>
              <FieldLabel>Nombre</FieldLabel>
              <Input
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder="Ej: Phone booth"
                required
              />
            </Field>
            <Field>
              <FieldLabel>Slug (URL)</FieldLabel>
              <Input
                value={slug}
                onChange={(e) => {
                  setSlugTouched(true)
                  setSlug(e.target.value)
                }}
                placeholder="phone-booth"
                required
              />
            </Field>

            <div className="grid grid-cols-2 gap-4">
              <Field>
                <FieldLabel>Inicio ventana</FieldLabel>
                <Input
                  type="time"
                  value={bookingWindowStart}
                  onChange={(e) => setBookingWindowStart(e.target.value)}
                />
              </Field>
              <Field>
                <FieldLabel>Fin ventana</FieldLabel>
                <Input
                  type="time"
                  value={bookingWindowEnd}
                  onChange={(e) => setBookingWindowEnd(e.target.value)}
                />
              </Field>
            </div>

            <div className="grid grid-cols-2 gap-4">
              <Field>
                <FieldLabel>Duración mínima</FieldLabel>
                <Select value={slotSize} onValueChange={(value) => setSlotSize(value as SlotSize)}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {SLOT_SIZE_OPTIONS.map((opt) => (
                      <SelectItem key={opt.value} value={opt.value}>
                        {opt.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </Field>

              <Field>
                <FieldLabel>Granularidad</FieldLabel>
                <Select
                  value={timeGranularity}
                  onValueChange={(value) => setTimeGranularity(value as TimeGranularity)}
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {GRANULARITY_OPTIONS.map((opt) => (
                      <SelectItem key={opt.value} value={opt.value}>
                        {opt.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </Field>
            </div>

            <Field>
              <FieldLabel>Icono (opcional)</FieldLabel>
              <LucideIconSelect
                value={icon}
                onValueChange={setIcon}
                placeholder="Ej: phone-booth"
              />
            </Field>
            <Field>
              <FieldLabel>Descripción</FieldLabel>
              <Textarea
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                rows={2}
              />
            </Field>

            <div className="flex items-center justify-between rounded-[var(--ds-radius-m)] border border-[var(--ds-neutral-200)] px-3 py-2">
              <span className="ds-type-global-xs ds-type-semibold text-[var(--ds-text-neutral-default)]">Enviar recordatorio por email</span>
              <Switch checked={remindersEnabled} onCheckedChange={setRemindersEnabled} />
            </div>

            <div className="grid grid-cols-2 gap-3">
              <Field>
                <FieldLabel>Antelación máxima para reservar</FieldLabel>
                <Input
                  type="number"
                  min={1}
                  value={bookingAdvanceValue}
                  onChange={(e) => setBookingAdvanceValue(Math.max(1, parseInt(e.target.value || "1", 10)))}
                />
              </Field>
              <Field>
                <FieldLabel>Unidad</FieldLabel>
                <Select value={bookingAdvanceUnit} onValueChange={(value) => setBookingAdvanceUnit(value as RuleUnit)}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="hours">Horas</SelectItem>
                    <SelectItem value="days">Días</SelectItem>
                  </SelectContent>
                </Select>
              </Field>
            </div>

            <div className="grid grid-cols-2 gap-3">
              <Field>
                <FieldLabel>Límite para cancelar</FieldLabel>
                <Input
                  type="number"
                  min={1}
                  value={cancellationValue}
                  onChange={(e) => setCancellationValue(Math.max(1, parseInt(e.target.value || "1", 10)))}
                />
              </Field>
              <Field>
                <FieldLabel>Unidad</FieldLabel>
                <Select value={cancellationUnit} onValueChange={(value) => setCancellationUnit(value as RuleUnit)}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="hours">Horas</SelectItem>
                    <SelectItem value="days">Días</SelectItem>
                  </SelectContent>
                </Select>
              </Field>
            </div>

            <div className="grid grid-cols-2 gap-3">
              <Field>
                <FieldLabel>Límite para editar</FieldLabel>
                <Input
                  type="number"
                  min={1}
                  value={editingValue}
                  onChange={(e) => setEditingValue(Math.max(1, parseInt(e.target.value || "1", 10)))}
                />
              </Field>
              <Field>
                <FieldLabel>Unidad</FieldLabel>
                <Select value={editingUnit} onValueChange={(value) => setEditingUnit(value as RuleUnit)}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="hours">Horas</SelectItem>
                    <SelectItem value="days">Días</SelectItem>
                  </SelectContent>
                </Select>
              </Field>
            </div>

            <div className="flex items-center justify-between rounded-[var(--ds-radius-m)] border border-[var(--ds-neutral-200)] px-3 py-2">
              <span className="ds-type-global-xs ds-type-semibold text-[var(--ds-text-neutral-default)]">Activo</span>
              <Switch checked={isActive} onCheckedChange={setIsActive} />
            </div>
          </FieldGroup>
          </div>

          <DialogFooter className="flex-shrink-0 pt-4">
            <Button type="button" variant="outline" onClick={() => setOpen(false)}>
              Cancelar
            </Button>
            <Button type="submit" disabled={loading}>
              {loading && <Spinner className="mr-2" />}
              {resourceType ? "Guardar" : "Crear"}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  )
}
