import { NextResponse } from "next/server"
import { z } from "zod"
import { ConvexHttpClient } from "convex/browser"

import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import { prisma } from "@/lib/prisma"

export const runtime = "nodejs"

type AdminSession = {
  user: {
    email: string
    name: string
    role: string
    tenantId: string | null
    avatarUrl: string | null
  }
} | null

type AssertAdminSessionFn = () => Promise<AdminSession>

let testAssertSessionImpl: AssertAdminSessionFn | null = null

const setAssertAdminSessionForTests: (fn: AssertAdminSessionFn | null) => void = (fn) => {
  if (process.env.NODE_ENV !== "test") return
  testAssertSessionImpl = fn
}

// Exportado apenas para testes; tipado como `never` para não conflitar com o contrato de rotas do Next.
export const __setAssertAdminSessionForTests = setAssertAdminSessionForTests as never

async function resolveAssertAuthenticatedSession(): Promise<AssertAdminSessionFn> {
  if (testAssertSessionImpl) return testAssertSessionImpl

  type AuthServerModuleLike = {
    assertAuthenticatedSession?: AssertAdminSessionFn
    default?: {
      assertAuthenticatedSession?: AssertAdminSessionFn
    }
  }

  const mod = (await import("@/lib/auth-server")) as AuthServerModuleLike
  const fn = mod.assertAuthenticatedSession ?? mod.default?.assertAuthenticatedSession
  if (typeof fn !== "function") {
    throw new Error("assertAuthenticatedSession not available")
  }
  return fn
}

const schema = z.object({
  machineId: z.string().min(1),
})

export async function POST(request: Request) {
  const assertAuthenticatedSession = await resolveAssertAuthenticatedSession()
  const session = await assertAuthenticatedSession()
  if (!session) {
    return NextResponse.json({ error: "Não autorizado" }, { status: 401 })
  }

  const convexUrl = process.env.NEXT_PUBLIC_CONVEX_URL
  if (!convexUrl) {
    return NextResponse.json({ error: "Convex não configurado" }, { status: 500 })
  }

  const payload = await request.json().catch(() => null)
  const parsed = schema.safeParse(payload)
  if (!parsed.success) {
    return NextResponse.json({ error: "Payload inválido", details: parsed.error.flatten() }, { status: 400 })
  }

  const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID

  try {
    const convex = new ConvexHttpClient(convexUrl)
    const ensured = await convex.mutation(api.users.ensureUser, {
      tenantId,
      email: session.user.email,
      name: session.user.name ?? session.user.email,
      avatarUrl: session.user.avatarUrl ?? undefined,
      role: session.user.role.toUpperCase(),
    })

    const actorId = ensured?._id as Id<"users"> | undefined
    if (!actorId) {
      return NextResponse.json({ error: "Falha ao identificar o administrador" }, { status: 500 })
    }

    let machineMissing = false
    try {
      await convex.mutation(api.devices.remove, {
        machineId: parsed.data.machineId as Id<"machines">,
        actorId,
      })
    } catch (error) {
      const message = error instanceof Error ? error.message : ""
      if (message.includes("Dispositivo não encontrada")) {
        machineMissing = true
      } else {
        console.error("[machines.delete] Convex failure", error)
        return NextResponse.json({ error: "Falha ao remover dispositivo no Convex" }, { status: 500 })
      }
    }

    const machineEmail = `machine-${parsed.data.machineId}@machines.local`
    await prisma.authUser.deleteMany({ where: { email: machineEmail } })

    return NextResponse.json({ ok: true, machineMissing })
  } catch (error) {
    console.error("[machines.delete] Falha ao excluir", error)
    return NextResponse.json({ error: "Falha ao excluir dispositivo" }, { status: 500 })
  }
}
