"use client"

import { useState, useEffect, useMemo } from "react"
import { createClient } from "@/lib/supabase/client"
import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} 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 { ImageIcon, X } from "lucide-react"
import { NumericInput } from "@/components/ui/numeric-input"
import type { Database } from "@/lib/supabase/database.types"
import type { LocationRow } from "@/lib/locations/tree"
import { buildLocationChildrenMap, getLocationPathIds } from "@/lib/locations/tree"

type Resource = Database["public"]["Tables"]["resources"]["Row"]
type ResourceType = Database["public"]["Tables"]["resource_types"]["Row"]

interface ResourceDialogProps {
  open: boolean
  onOpenChange: () => void
  resource: Resource | null
  resourceTypes: ResourceType[]
}

export function ResourceDialog({ open, onOpenChange, resource, resourceTypes }: ResourceDialogProps) {
  const [loading, setLoading] = useState(false)
  const [formData, setFormData] = useState({
    name: "",
    description: "",
    resource_type_id: "",
    capacity: 1,
    floor: "",
    amenities: [] as string[],
    is_active: true,
    image_url: "",
  })
  const [amenityInput, setAmenityInput] = useState("")
  const [locations, setLocations] = useState<LocationRow[]>([])
  const [selectedLocationByDepth, setSelectedLocationByDepth] = useState<string[]>([])
  const supabase = useMemo(() => createClient(), [])
  const locationsById = useMemo(
    () => new Map(locations.map((location) => [location.id, location])),
    [locations],
  )
  const locationChildrenMap = useMemo(
    () => buildLocationChildrenMap(locations),
    [locations],
  )

  useEffect(() => {
    if (!open) return
    let cancelled = false
    const loadLocations = async () => {
      const locationsResponse = await fetch("/api/locations")
      const payload = (await locationsResponse.json().catch(() => null)) as
        | { locations?: LocationRow[]; error?: string }
        | null
      if (!locationsResponse.ok) {
        if (!cancelled) toast.error(payload?.error ?? "No se pudo cargar ubicaciones")
        return
      }

      if (!cancelled) {
        setLocations(payload?.locations ?? [])
      }
    }
    void loadLocations()
    return () => {
      cancelled = true
    }
  }, [open, supabase])

  useEffect(() => {
    if (resource) {
      const metadata = (resource.metadata ?? {}) as { locationPathIds?: string[]; image_url?: string }
      setFormData({
        name: resource.name,
        description: resource.description || "",
        resource_type_id: resource.resource_type_id,
        capacity: resource.capacity || 1,
        floor: resource.floor || "",
        amenities: (resource.amenities as string[]) || [],
        is_active: resource.is_active ?? true,
        image_url: metadata.image_url || "",
      })
      setSelectedLocationByDepth(
        Array.isArray(metadata.locationPathIds)
          ? metadata.locationPathIds.filter((value) => typeof value === "string")
          : [],
      )
    } else {
      setFormData({
        name: "",
        description: "",
        resource_type_id: resourceTypes[0]?.id || "",
        capacity: 1,
        floor: "",
        amenities: [],
        is_active: true,
        image_url: "",
      })
      setSelectedLocationByDepth([])
    }
  }, [resource, resourceTypes])

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    setLoading(true)

    const locationPathIds = getLocationPathIds({
      selectedByDepth: selectedLocationByDepth,
      childrenMap: locationChildrenMap,
    })
    const selectedLocation =
      locationPathIds.length > 0 ? locationsById.get(locationPathIds[locationPathIds.length - 1]) : null
    const existingMetadata = (resource?.metadata ?? {}) as Record<string, unknown>

    const payload: Record<string, unknown> = {
      name: formData.name,
      description: formData.description || null,
      resource_type_id: formData.resource_type_id,
      capacity: formData.capacity,
      floor: formData.floor || null,
      amenities: formData.amenities,
      is_active: formData.is_active,
      metadata: {
        ...existingMetadata,
        locationPathIds,
        locationPathValues: selectedLocation?.path ?? [],
        image_url: formData.image_url || null,
      },
    }

    if (resource) {
      const { error } = await (supabase.from("resources") as any).update(payload).eq("id", resource.id)
      if (error) {
        toast.error(`Error al actualizar: [${error.code}] ${error.message}${error.details ? ` — ${error.details}` : ""}`)
        setLoading(false)
        return
      }
    } else {
      const { error } = await (supabase.from("resources") as any).insert(payload)
      if (error) {
        toast.error(`Error al crear: [${error.code}] ${error.message}${error.details ? ` — ${error.details}` : ""}`)
        setLoading(false)
        return
      }
    }

    setLoading(false)
    onOpenChange()
  }

  const addAmenity = () => {
    if (amenityInput.trim() && !formData.amenities.includes(amenityInput.trim())) {
      setFormData(prev => ({
        ...prev,
        amenities: [...prev.amenities, amenityInput.trim()]
      }))
      setAmenityInput("")
    }
  }

  const removeAmenity = (amenity: string) => {
    setFormData(prev => ({
      ...prev,
      amenities: prev.amenities.filter(a => a !== amenity)
    }))
  }

  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])

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="flex max-h-[85vh] flex-col sm:max-w-[500px]">
        <DialogHeader className="flex-shrink-0">
          <DialogTitle>{resource ? "Editar Recurso" : "Nuevo Recurso"}</DialogTitle>
          <DialogDescription>
            {resource ? "Modifica los datos del recurso" : "Completa los datos para crear un nuevo recurso"}
          </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={formData.name}
                  onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}
                  placeholder="Ej: Sala Aconcagua"
                  required
                />
              </Field>

              <div className="grid grid-cols-2 gap-4">
                <Field>
                  <FieldLabel>Tipo</FieldLabel>
                  <Select
                    value={formData.resource_type_id}
                    onValueChange={(value) => setFormData(prev => ({ ...prev, resource_type_id: value }))}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="Selecciona tipo" />
                    </SelectTrigger>
                    <SelectContent>
                      {resourceTypes.map((type) => (
                        <SelectItem key={type.id} value={type.id}>
                          {type.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </Field>
                <Field>
                  <FieldLabel>Capacidad</FieldLabel>
                  <NumericInput
                    min={1}
                    value={formData.capacity}
                    onChange={(v) => setFormData(prev => ({ ...prev, capacity: v }))}
                  />
                </Field>
              </div>

              <Field>
                <FieldLabel>Detalle de ubicación (opcional)</FieldLabel>
                <Input
                  value={formData.floor}
                  onChange={(e) => setFormData(prev => ({ ...prev, floor: e.target.value }))}
                  placeholder="Ej: Torre B, Piso 5, Box 12"
                />
              </Field>

              <Field>
                <FieldLabel>Descripción</FieldLabel>
                <Textarea
                  value={formData.description}
                  onChange={(e) => setFormData(prev => ({ ...prev, description: e.target.value }))}
                  placeholder="Descripción opcional del recurso"
                  rows={2}
                />
              </Field>

              <Field>
                <FieldLabel>Amenidades</FieldLabel>
                <div className="flex gap-2">
                  <Input
                    value={amenityInput}
                    onChange={(e) => setAmenityInput(e.target.value)}
                    placeholder="Ej: TV, Pizarra, etc."
                    onKeyDown={(e) => e.key === "Enter" && (e.preventDefault(), addAmenity())}
                  />
                  <Button type="button" variant="secondary" onClick={addAmenity}>
                    Agregar
                  </Button>
                </div>
                {formData.amenities.length > 0 && (
                  <div className="mt-2 flex flex-wrap gap-2">
                    {formData.amenities.map((amenity) => (
                      <span
                        key={amenity}
                        className="inline-flex items-center gap-1 rounded-md bg-secondary px-2 py-1 text-sm text-secondary-foreground"
                      >
                        {amenity}
                        <button
                          type="button"
                          onClick={() => removeAmenity(amenity)}
                          className="hover:text-destructive"
                        >
                          ×
                        </button>
                      </span>
                    ))}
                  </div>
                )}
              </Field>

              <Field>
                <FieldLabel>Imagen del recurso (URL)</FieldLabel>
                <Input
                  value={formData.image_url}
                  onChange={(e) => setFormData(prev => ({ ...prev, image_url: e.target.value }))}
                  placeholder="https://ejemplo.com/imagen.jpg"
                />
                {formData.image_url && (
                  <div className="relative mt-2 inline-block">
                    <img
                      src={formData.image_url}
                      alt="Preview"
                      className="h-20 w-32 rounded-[var(--ds-radius-m)] border border-[var(--ds-neutral-200)] object-cover"
                      onError={(e) => { (e.target as HTMLImageElement).style.display = "none" }}
                    />
                    <button
                      type="button"
                      onClick={() => setFormData(prev => ({ ...prev, image_url: "" }))}
                      className="absolute -right-2 -top-2 flex h-5 w-5 items-center justify-center rounded-full bg-[var(--ds-error-600)] text-white"
                    >
                      <X className="h-3 w-3" />
                    </button>
                  </div>
                )}
                {!formData.image_url && (
                  <div className="mt-2 flex h-20 w-32 items-center justify-center rounded-[var(--ds-radius-m)] border border-dashed border-[var(--ds-neutral-300)] text-[var(--ds-text-neutral-lighter)]">
                    <ImageIcon className="h-6 w-6" />
                  </div>
                )}
              </Field>

              {locationLevelOptions.length > 0 && (
                <Field>
                  <FieldLabel>Ubicación jerárquica</FieldLabel>
                  <div className="space-y-2">
                    {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>
                          <SelectValue placeholder={`Nivel ${index + 1}`} />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="__none__">Sin selección en este nivel</SelectItem>
                          {level.options.map((location) => (
                            <SelectItem key={location.id} value={location.id}>
                              {location.value}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    ))}
                  </div>
                </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)]">Activo</span>
                <Switch
                  checked={formData.is_active}
                  onCheckedChange={(checked) => setFormData(prev => ({ ...prev, is_active: checked }))}
                />
              </div>
            </FieldGroup>
          </div>

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