import { NextResponse } from "next/server"

import { prisma } from "@/lib/prisma"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { assertStaffSession } from "@/lib/auth-server"
import { isAdmin } from "@/lib/authz"

export const runtime = "nodejs"

const ALLOWED_ROLES = ["MANAGER", "COLLABORATOR"] as const

type AllowedRole = (typeof ALLOWED_ROLES)[number]

function normalizeRole(role?: string | null): AllowedRole {
  const normalized = (role ?? "COLLABORATOR").toUpperCase()
  return ALLOWED_ROLES.includes(normalized as AllowedRole) ? (normalized as AllowedRole) : "COLLABORATOR"
}

export async function GET() {
  const session = await assertStaffSession()
  if (!session) {
    return NextResponse.json({ error: "Não autorizado" }, { status: 401 })
  }

  const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID

  const users = await prisma.user.findMany({
    where: {
      tenantId,
      role: { in: [...ALLOWED_ROLES] },
    },
    include: {
      company: {
        select: {
          id: true,
          name: true,
        },
      },
    },
    orderBy: { createdAt: "desc" },
  })

  const emails = users.map((user) => user.email)
  const authUsers = await prisma.authUser.findMany({
    where: { email: { in: emails } },
    select: {
      id: true,
      email: true,
      updatedAt: true,
      createdAt: true,
    },
  })

  const sessions = await prisma.authSession.findMany({
    where: { userId: { in: authUsers.map((authUser) => authUser.id) } },
    orderBy: { updatedAt: "desc" },
    select: {
      userId: true,
      updatedAt: true,
    },
  })

  const sessionByUserId = new Map<string, Date>()
  for (const sessionRow of sessions) {
    if (!sessionByUserId.has(sessionRow.userId)) {
      sessionByUserId.set(sessionRow.userId, sessionRow.updatedAt)
    }
  }

  const authByEmail = new Map<string, { id: string; updatedAt: Date; createdAt: Date }>()
  for (const authUser of authUsers) {
    authByEmail.set(authUser.email.toLowerCase(), {
      id: authUser.id,
      updatedAt: authUser.updatedAt,
      createdAt: authUser.createdAt,
    })
  }

  const items = users.map((user) => {
    const auth = authByEmail.get(user.email.toLowerCase())
    const lastSeenAt = auth ? sessionByUserId.get(auth.id) ?? auth.updatedAt : null
    return {
      id: user.id,
      email: user.email,
      name: user.name,
      role: normalizeRole(user.role),
      companyId: user.companyId,
      companyName: user.company?.name ?? null,
      tenantId: user.tenantId,
      createdAt: user.createdAt.toISOString(),
      updatedAt: user.updatedAt.toISOString(),
      authUserId: auth?.id ?? null,
      lastSeenAt: lastSeenAt ? lastSeenAt.toISOString() : null,
    }
  })

  return NextResponse.json({ items })
}

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

  if (!isAdmin(session.user.role)) {
    return NextResponse.json({ error: "Apenas administradores podem excluir clientes." }, { status: 403 })
  }

  const json = await request.json().catch(() => null)
  const ids = Array.isArray(json?.ids) ? (json.ids as string[]) : []
  if (ids.length === 0) {
    return NextResponse.json({ error: "Nenhum cliente selecionado." }, { status: 400 })
  }

  const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID

  const users = await prisma.user.findMany({
    where: {
      id: { in: ids },
      tenantId,
      role: { in: [...ALLOWED_ROLES] },
    },
    select: {
      id: true,
      email: true,
    },
  })

  if (users.length === 0) {
    return NextResponse.json({ deletedIds: [] })
  }

  const emails = users.map((user) => user.email.toLowerCase())
  const authUsers = await prisma.authUser.findMany({
    where: {
      email: { in: emails },
    },
    select: {
      id: true,
    },
  })

  const authUserIds = authUsers.map((authUser) => authUser.id)

  await prisma.$transaction(async (tx) => {
    if (authUserIds.length > 0) {
      await tx.authSession.deleteMany({ where: { userId: { in: authUserIds } } })
      await tx.authAccount.deleteMany({ where: { userId: { in: authUserIds } } })
      await tx.authUser.deleteMany({ where: { id: { in: authUserIds } } })
    }
    await tx.user.deleteMany({ where: { id: { in: users.map((user) => user.id) } } })
  })

  return NextResponse.json({ deletedIds: users.map((user) => user.id) })
}
