import { NextRequest, NextResponse } from "next/server"
import * as XLSX from "xlsx"
import { createClient } from "@supabase/supabase-js"
import { getSupabaseAdminEnv } from "@/lib/supabase/env.server"

interface RowError {
  row: number
  message: string
}

function parseActive(value: unknown): boolean {
  if (value === undefined || value === null || value === "") return true
  const str = String(value).trim().toLowerCase()
  return ["sí", "si", "yes", "1", "true"].includes(str)
}

function parseAmenities(value: unknown): string[] {
  if (!value) return []
  return String(value)
    .split(",")
    .map((s) => s.trim())
    .filter(Boolean)
}

export async function POST(request: NextRequest) {
  try {
    const formData = await request.formData()
    const file = formData.get("file")

    if (!file || !(file instanceof Blob)) {
      return NextResponse.json(
        { total: 0, success: 0, failed: 0, errors: [{ row: 0, message: "No se proporcionó un archivo" }] },
        { status: 400 },
      )
    }

    const arrayBuffer = await file.arrayBuffer()
    const wb = XLSX.read(arrayBuffer, { type: "array" })
    const ws = wb.Sheets[wb.SheetNames[0]]
    if (!ws) {
      return NextResponse.json(
        { total: 0, success: 0, failed: 0, errors: [{ row: 0, message: "El archivo no contiene hojas" }] },
        { status: 400 },
      )
    }

    const rows = XLSX.utils.sheet_to_json<Record<string, unknown>>(ws)

    if (rows.length === 0) {
      return NextResponse.json(
        { total: 0, success: 0, failed: 0, errors: [{ row: 0, message: "El archivo no contiene filas de datos" }] },
        { status: 400 },
      )
    }

    // Build supabase admin client using the service role key
    const { url, serviceRoleKey } = getSupabaseAdminEnv()
    const supabase = createClient(url as string, serviceRoleKey, {
      auth: { autoRefreshToken: false, persistSession: false },
    })

    // Fetch all resource types to map names to IDs
    const { data: resourceTypes, error: rtError } = await supabase
      .from("resource_types")
      .select("id, name")

    if (rtError || !resourceTypes) {
      return NextResponse.json(
        { total: rows.length, success: 0, failed: rows.length, errors: [{ row: 0, message: "No se pudieron cargar los tipos de recurso" }] },
        { status: 500 },
      )
    }

    // Case-insensitive name -> id map
    const typeMap = new Map<string, string>()
    for (const rt of resourceTypes) {
      typeMap.set(rt.name.toLowerCase(), rt.id)
    }

    // Fetch locations to map "path > string" to location data
    const { data: allLocations } = await supabase
      .from("locations")
      .select("id, parent_id, value, path")
      .eq("is_active", true)

    const locationsList = (allLocations ?? []) as Array<{
      id: string
      parent_id: string | null
      value: string
      path: string[]
    }>

    // Build a map of id -> location for ancestor lookups
    const locationsById = new Map(locationsList.map((l) => [l.id, l]))

    // Find leaf locations and build a map: "full > path" -> location
    const parentIds = new Set(
      locationsList.filter((l) => l.parent_id).map((l) => l.parent_id!),
    )
    const locationByPath = new Map<string, typeof locationsList[0]>()
    for (const loc of locationsList) {
      if (!parentIds.has(loc.id)) {
        const pathKey = (loc.path ?? []).join(" > ").toLowerCase()
        locationByPath.set(pathKey, loc)
      }
    }

    // Walk up the parent chain to build the full path of IDs (root → leaf)
    function getFullPathIds(leafId: string): string[] {
      const ids: string[] = []
      let current: typeof locationsList[0] | undefined = locationsById.get(leafId)
      while (current) {
        ids.unshift(current.id)
        current = current.parent_id ? locationsById.get(current.parent_id) : undefined
      }
      return ids
    }

    let success = 0
    let failed = 0
    const errors: RowError[] = []

    for (let i = 0; i < rows.length; i++) {
      const row = rows[i]
      const rowNum = i + 2 // 1-indexed + header row

      const name = row["Nombre"] != null ? String(row["Nombre"]).trim() : ""
      const typeName = row["Tipo de recurso"] != null ? String(row["Tipo de recurso"]).trim() : ""
      const ubicacion = row["Ubicación"] != null ? String(row["Ubicación"]).trim() : ""
      const capacityRaw = row["Capacidad"]
      const floor = row["Detalle ubicación"] != null ? String(row["Detalle ubicación"]).trim() : ""
      const description = row["Descripción"] != null ? String(row["Descripción"]).trim() : ""
      const amenities = parseAmenities(row["Amenidades"])
      const imageUrl = row["Imagen URL"] != null ? String(row["Imagen URL"]).trim() : ""
      const isActive = parseActive(row["Activo"])

      // Validate required fields
      if (!name) {
        errors.push({ row: rowNum, message: `Fila ${rowNum}: "Nombre" es requerido` })
        failed++
        continue
      }

      if (!typeName) {
        errors.push({ row: rowNum, message: `Fila ${rowNum}: "Tipo de recurso" es requerido` })
        failed++
        continue
      }

      const resourceTypeId = typeMap.get(typeName.toLowerCase())
      if (!resourceTypeId) {
        errors.push({ row: rowNum, message: `Fila ${rowNum}: Tipo de recurso "${typeName}" no encontrado` })
        failed++
        continue
      }

      const capacity = capacityRaw != null && capacityRaw !== "" ? Number(capacityRaw) : null

      const metadata: Record<string, unknown> = {}
      if (imageUrl) {
        metadata.image_url = imageUrl
      }

      // Resolve location
      if (ubicacion) {
        const matchedLocation = locationByPath.get(ubicacion.toLowerCase())
        if (matchedLocation) {
          metadata.locationPathIds = getFullPathIds(matchedLocation.id)
          metadata.locationPathValues = matchedLocation.path
        }
      }

      const payload = {
        name,
        resource_type_id: resourceTypeId,
        capacity,
        floor: floor || null,
        description: description || null,
        amenities,
        is_active: isActive,
        metadata: Object.keys(metadata).length > 0 ? metadata : null,
      }

      const { error: insertError } = await supabase.from("resources").insert(payload)

      if (insertError) {
        errors.push({ row: rowNum, message: `Fila ${rowNum}: No se pudo crear el recurso` })
        failed++
      } else {
        success++
      }
    }

    return NextResponse.json({
      total: rows.length,
      success,
      failed,
      errors,
    })
  } catch (err) {
    const message = err instanceof Error ? "No se pudo procesar el archivo" : "Error inesperado"
    return NextResponse.json(
      { total: 0, success: 0, failed: 0, errors: [{ row: 0, message }] },
      { status: 500 },
    )
  }
}
