"use client"

import { useCallback, useEffect, useMemo, useState } from "react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { toast } from "sonner"
import { Plus, Pencil, ChevronRight, ChevronDown, MapPin } from "lucide-react"
import { ConfirmDeleteDialog } from "@/components/admin/confirm-delete-dialog"
import type { LocationRow } from "@/lib/locations/tree"
import { buildLocationChildrenMap } from "@/lib/locations/tree"
import { LocationDialog } from "@/components/admin/location-dialog"

/* ------------------------------------------------------------------ */
/*  Tree node component                                                */
/* ------------------------------------------------------------------ */

function LocationTreeNode({
  location,
  level,
  childrenMap,
  expanded,
  onToggle,
  onEdit,
  onDelete,
}: {
  location: LocationRow
  /** Nivel visual en el árbol (1 = raíz). Se calcula desde la jerarquía, no desde location.depth. */
  level: number
  childrenMap: Map<string | null, LocationRow[]>
  expanded: Set<string>
  onToggle: (id: string) => void
  onEdit: (loc: LocationRow) => void
  onDelete: (loc: LocationRow) => void
}) {
  const children = childrenMap.get(location.id) ?? []
  const hasChildren = children.length > 0
  const isExpanded = expanded.has(location.id)

  return (
    <div>
      <div
        className="flex items-center justify-between rounded-[var(--ds-radius-m)] border border-[var(--ds-neutral-200)] bg-white px-3 py-2 transition-colors hover:bg-[var(--ds-neutral-100)]"
        style={{ marginLeft: `${Math.max(0, level - 1) * 24}px` }}
      >
        <div className="flex items-center gap-2">
          {hasChildren ? (
            <button
              type="button"
              onClick={(e) => {
                e.preventDefault()
                e.stopPropagation()
                onToggle(location.id)
              }}
              className="flex h-5 w-5 shrink-0 items-center justify-center rounded-[var(--ds-radius-s)] text-[var(--ds-text-neutral-lighter)] transition-colors hover:bg-[var(--ds-blueprimary-100)] hover:text-[var(--ds-blueprimary-800)]"
              aria-expanded={isExpanded}
              aria-label={isExpanded ? "Colapsar" : "Expandir"}
            >
              {isExpanded ? (
                <ChevronDown className="h-4 w-4" />
              ) : (
                <ChevronRight className="h-4 w-4" />
              )}
            </button>
          ) : (
            <span className="flex h-5 w-5 items-center justify-center text-[var(--ds-neutral-300)]">
              <MapPin className="h-3 w-3" />
            </span>
          )}

          <Badge
            variant="outline"
            className="rounded-[var(--ds-radius-s)] border-[var(--ds-neutral-300)] ds-type-global-xxs text-[var(--ds-text-neutral-lighter)]"
          >
            Nivel {level}
          </Badge>

          <span className="ds-type-global-xs ds-type-semibold text-[var(--ds-text-neutral-default)]">
            {location.value}
          </span>

          {hasChildren && (
            <span className="ds-type-global-xxs text-[var(--ds-text-neutral-lighter)]">
              ({children.length})
            </span>
          )}
        </div>

        <div className="flex items-center gap-1">
          <Button
            variant="ghost"
            size="icon"
            className="h-7 w-7 rounded-[var(--ds-radius-s)] text-[var(--ds-text-neutral-lighter)] hover:bg-[var(--ds-blueprimary-100)] hover:text-[var(--ds-blueprimary-800)]"
            onClick={() => onEdit(location)}
          >
            <Pencil className="h-3.5 w-3.5" />
          </Button>
          <ConfirmDeleteDialog
            title={`¿Eliminar "${location.value}"?`}
            description="Se eliminará la ubicación de forma permanente."
            onConfirm={() => onDelete(location)}
          />
        </div>
      </div>

      {hasChildren && isExpanded && (
        <div className="mt-1 space-y-1">
          {children.map((child) => (
            <LocationTreeNode
              key={child.id}
              location={child}
              level={level + 1}
              childrenMap={childrenMap}
              expanded={expanded}
              onToggle={onToggle}
              onEdit={onEdit}
              onDelete={onDelete}
            />
          ))}
        </div>
      )}
    </div>
  )
}

/* ------------------------------------------------------------------ */
/*  Main page                                                          */
/* ------------------------------------------------------------------ */

export default function LocationsAdminPage() {
  const [locations, setLocations] = useState<LocationRow[]>([])
  const [loading, setLoading] = useState(true)
  const [expanded, setExpanded] = useState<Set<string>>(new Set())
  const [dialogOpen, setDialogOpen] = useState(false)
  const [editingLocation, setEditingLocation] = useState<LocationRow | null>(null)

  const childrenMap = useMemo(() => buildLocationChildrenMap(locations), [locations])
  const rootLocations = useMemo(() => childrenMap.get(null) ?? [], [childrenMap])

  const fetchLocations = async () => {
    setLoading(true)
    const response = await fetch("/api/locations")
    const payload = (await response.json().catch(() => null)) as
      | { locations?: LocationRow[]; error?: string }
      | null

    if (!response.ok) {
      toast.error(payload?.error ?? "No se pudo cargar ubicaciones")
      setLoading(false)
      return
    }

    setLocations(payload?.locations ?? [])
    setLoading(false)
  }

  useEffect(() => {
    void fetchLocations()
  }, [])

  const handleToggle = useCallback((id: string) => {
    setExpanded((prev) => {
      const next = new Set(prev)
      if (next.has(id)) {
        next.delete(id)
      } else {
        next.add(id)
      }
      return next
    })
  }, [])

  const handleExpandAll = useCallback(() => {
    const allIds = new Set(locations.filter((l) => (childrenMap.get(l.id) ?? []).length > 0).map((l) => l.id))
    setExpanded(allIds)
  }, [locations, childrenMap])

  const handleCollapseAll = useCallback(() => {
    setExpanded(new Set())
  }, [])

  const handleOpenCreate = () => {
    setEditingLocation(null)
    setDialogOpen(true)
  }

  const handleOpenEdit = (location: LocationRow) => {
    setEditingLocation(location)
    setDialogOpen(true)
  }

  const handleDelete = async (location: LocationRow) => {
    const response = await fetch(`/api/locations/${location.id}`, {
      method: "DELETE",
    })
    const payload = (await response.json().catch(() => null)) as { error?: string } | null

    if (!response.ok) {
      toast.error(payload?.error ?? "No se pudo eliminar ubicación")
      return
    }

    toast.success("Ubicación eliminada")
    void fetchLocations()
  }

  const handleDialogSaved = () => {
    void fetchLocations()
  }

  return (
    <div className="space-y-[var(--ds-space-4x)]">
      <div className="flex items-center justify-between">
        <h1 className="ds-type-global-l ds-type-semibold text-[var(--ds-text-neutral-default)]">
          Ubicaciones
        </h1>
        <Button
          onClick={handleOpenCreate}
          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)]"
        >
          <Plus className="mr-2 h-4 w-4" />
          Nueva ubicación
        </Button>
      </div>

      <Card className="rounded-[var(--ds-radius-l)] border-[var(--ds-neutral-200)] bg-white shadow-[var(--ds-shadow-4dp)]">
        <CardHeader className="flex flex-row items-start justify-between">
          <div>
            <CardTitle className="ds-type-global-m ds-type-semibold text-[var(--ds-text-neutral-default)]">
              Árbol actual
            </CardTitle>
            <CardDescription className="ds-type-global-xs text-[var(--ds-text-neutral-lighter)]">
              {locations.length} ubicaciones activas
            </CardDescription>
          </div>
          {locations.length > 0 && (
            <div className="flex gap-1">
              <Button
                type="button"
                variant="ghost"
                size="sm"
                onClick={handleExpandAll}
                className="ds-type-global-xxs text-[var(--ds-text-neutral-lighter)] hover:text-[var(--ds-text-neutral-default)]"
              >
                Expandir todo
              </Button>
              <Button
                type="button"
                variant="ghost"
                size="sm"
                onClick={handleCollapseAll}
                className="ds-type-global-xxs text-[var(--ds-text-neutral-lighter)] hover:text-[var(--ds-text-neutral-default)]"
              >
                Colapsar todo
              </Button>
            </div>
          )}
        </CardHeader>
        <CardContent>
          {loading ? (
            <div className="flex items-center justify-center py-8">
              <div className="h-8 w-8 animate-spin rounded-full border-4 border-[var(--ds-brand-400)] border-t-transparent" />
            </div>
          ) : rootLocations.length === 0 ? (
            <div className="py-[var(--ds-space-5x)] text-center text-[var(--ds-text-neutral-lighter)]">
              <MapPin className="mx-auto mb-[var(--ds-space-2x)] h-[var(--ds-space-5x)] w-[var(--ds-space-5x)] opacity-50" />
              <p className="ds-type-global-s">No hay ubicaciones creadas</p>
              <p className="mt-[var(--ds-space-05x)] ds-type-global-xs">
                Crea tu primera ubicación raíz para comenzar
              </p>
            </div>
          ) : (
            <div className="space-y-1">
              {rootLocations.map((root) => (
                <LocationTreeNode
                  key={root.id}
                  location={root}
                  level={1}
                  childrenMap={childrenMap}
                  expanded={expanded}
                  onToggle={handleToggle}
                  onEdit={handleOpenEdit}
                  onDelete={handleDelete}
                />
              ))}
            </div>
          )}
        </CardContent>
      </Card>

      <LocationDialog
        open={dialogOpen}
        onOpenChange={setDialogOpen}
        location={editingLocation}
        allLocations={locations}
        onSaved={handleDialogSaved}
      />
    </div>
  )
}
