import { NextResponse } from "next/server"
import { randomBytes } from "crypto"

import { prisma } from "@/lib/prisma"
import { assertStaffSession } from "@/lib/auth-server"
import { isAdmin } from "@/lib/authz"
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"
import { syncConvexCompany } from "@/server/companies-sync"

export const runtime = "nodejs"

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

  const companies = await prisma.company.findMany({
    orderBy: { name: "asc" },
  })
  return NextResponse.json({ companies })
}

export async function POST(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 criar empresas" }, { status: 403 })
  }

  const body = (await request.json()) as Partial<{
    name: string
    slug: string
    isAvulso: boolean
    contractedHoursPerMonth: number | string | null
    cnpj: string | null
    domain: string | null
    phone: string | null
    description: string | null
    address: string | null
  }>
  const { name, slug, isAvulso, contractedHoursPerMonth, cnpj, domain, phone, description, address } = body ?? {}
  if (!name || !slug) {
    return NextResponse.json({ error: "Nome e slug são obrigatórios" }, { status: 400 })
  }

  try {
    const provisioningCode = randomBytes(32).toString("hex")
    const company = await prisma.company.create({
      data: {
        tenantId: session.user.tenantId ?? "tenant-atlas",
        name: String(name),
        slug: String(slug),
        provisioningCode,
        // Campos opcionais
        isAvulso: Boolean(isAvulso ?? false),
        contractedHoursPerMonth:
          typeof contractedHoursPerMonth === "number"
            ? contractedHoursPerMonth
            : contractedHoursPerMonth
            ? Number(contractedHoursPerMonth)
            : null,
        cnpj: cnpj ? String(cnpj) : null,
        domain: domain ? String(domain) : null,
        phone: phone ? String(phone) : null,
        description: description ? String(description) : null,
        address: address ? String(address) : null,
      },
    })

    if (company.provisioningCode) {
      const synced = await syncConvexCompany({
        tenantId: company.tenantId,
        slug: company.slug,
        name: company.name,
        provisioningCode: company.provisioningCode,
      })
      if (!synced) {
        console.warn("[admin.companies] Convex não configurado; empresa criada apenas no Prisma.")
      }
    }

    return NextResponse.json({ company })
  } catch (error) {
    console.error("Failed to create company", error)
    if (error instanceof PrismaClientKnownRequestError && error.code === "P2002") {
      // Duplicidade de slug por tenant ou provisioningCode único
      return NextResponse.json(
        { error: "Já existe uma empresa com este slug ou código de provisionamento." },
        { status: 409 }
      )
    }
    return NextResponse.json({ error: "Falha ao criar empresa" }, { status: 500 })
  }
}
