import { NextResponse } from "next/server"
import { createClient } from "@/lib/supabase/server"
import { isAdminUser } from "@/lib/auth/is-admin"
import type { LocationRow } from "@/lib/locations/tree"

type CreateLocationBody = {
  value?: string
  parentId?: string | null
}

function locationsTable(client: Awaited<ReturnType<typeof createClient>>) {
  return client.from("locations" as any) as any
}

export async function GET() {
  const supabase = await createClient()
  const {
    data: { session },
    error: sessionError,
  } = await supabase.auth.getSession()
  const user = session?.user

  if (sessionError || !user) {
    return NextResponse.json({ error: "No autorizado" }, { status: 401 })
  }

  const { data, error } = await locationsTable(supabase)
    .select("id, parent_id, value, depth, path, is_active")
    .eq("is_active", true)
    .order("depth", { ascending: true })
    .order("value", { ascending: true })

  if (error) {
    return NextResponse.json({ error: "No se pudieron consultar las ubicaciones" }, { status: 500 })
  }

  return NextResponse.json({ ok: true, locations: (data ?? []) as LocationRow[] })
}

export async function POST(request: Request) {
  const body = (await request.json().catch(() => ({}))) as CreateLocationBody
  const value = typeof body.value === "string" ? body.value.trim() : ""
  const parentId =
    typeof body.parentId === "string" && body.parentId.trim().length > 0 ? body.parentId.trim() : null

  if (!value) {
    return NextResponse.json({ error: "El valor de la ubicación es obligatorio" }, { status: 400 })
  }

  const supabase = await createClient()
  const {
    data: { session },
    error: sessionError,
  } = await supabase.auth.getSession()
  const user = session?.user

  if (sessionError || !user) {
    return NextResponse.json({ error: "No autorizado" }, { status: 401 })
  }
  if (!isAdminUser(user)) {
    return NextResponse.json({ error: "No tienes permisos para crear ubicaciones" }, { status: 403 })
  }

  let depth = 1
  let path = [value]

  if (parentId) {
    const { data: parent, error: parentError } = await locationsTable(supabase)
      .select("id, depth, path")
      .eq("id", parentId)
      .maybeSingle()

    if (parentError) {
      return NextResponse.json({ error: "No se pudo consultar la ubicación padre" }, { status: 500 })
    }
    if (!parent) {
      return NextResponse.json({ error: "No se encontró la ubicación padre" }, { status: 404 })
    }

    depth = (typeof parent.depth === "number" ? parent.depth : 0) + 1
    path = [...((parent.path ?? []) as string[]), value]
  }

  if (depth > 20) {
    return NextResponse.json({ error: "La profundidad máxima de ubicaciones es de 20 niveles" }, { status: 409 })
  }

  const { data: created, error: insertError } = await locationsTable(supabase)
    .insert({
      value,
      parent_id: parentId,
      depth,
      path,
      is_active: true,
    })
    .select("id, parent_id, value, depth, path, is_active")
    .maybeSingle()

  if (insertError) {
    return NextResponse.json({ error: "No se pudo crear la ubicación" }, { status: 500 })
  }

  return NextResponse.json({ ok: true, location: created as LocationRow })
}
