import { NextResponse } from "next/server"
import { randomBytes } from "crypto"
import { ConvexHttpClient } from "convex/browser"

import { assertAdminSession } from "@/lib/auth-server"
import { prisma } from "@/lib/prisma"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import type { Id } from "@/convex/_generated/dataModel"
import { api } from "@/convex/_generated/api"
import { requireConvexUrl } from "@/server/convex-client"

export const runtime = "nodejs"

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

  const body = (await request.json().catch(() => null)) as { email?: string; companyId?: string }
  const email = body?.email?.trim().toLowerCase()
  const companyId = body?.companyId
  if (!email || !companyId) {
    return NextResponse.json({ error: "Informe e-mail e empresa" }, { status: 400 })
  }

  let client: ConvexHttpClient
  try {
    client = new ConvexHttpClient(requireConvexUrl())
  } catch {
    return NextResponse.json({ error: "Convex não configurado" }, { status: 500 })
  }

  try {
    const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID

    const company = await prisma.company.findUnique({
      where: { id: companyId },
      select: { id: true, tenantId: true, slug: true, name: true, provisioningCode: true },
    })

    if (!company || company.tenantId !== tenantId) {
      return NextResponse.json({ error: "Empresa não encontrada" }, { status: 404 })
    }

    let provisioningCode = company.provisioningCode
    if (!provisioningCode) {
      provisioningCode = randomBytes(16).toString("hex")
      await prisma.company.update({ where: { id: company.id }, data: { provisioningCode } })
    }

    const ensured = await client.mutation(api.users.ensureUser, {
      tenantId,
      email: session.user.email ?? "admin@sistema.dev",
      name: session.user.name ?? session.user.email ?? "Administrador",
      avatarUrl: session.user.avatarUrl ?? undefined,
      role: session.user.role?.toUpperCase?.(),
    })

    if (!ensured?._id) {
      throw new Error("Não foi possível identificar o ator no Convex")
    }

    const ensuredCompany = await client.mutation(api.companies.ensureProvisioned, {
      tenantId,
      slug: company.slug ?? `company-${company.id}`,
      name: company.name,
      provisioningCode,
    })

    if (!ensuredCompany?.id) {
      throw new Error("Falha ao sincronizar empresa no Convex")
    }

    await client.mutation(api.users.assignCompany, {
      tenantId,
      email,
      companyId: ensuredCompany.id as Id<"companies">,
      actorId: ensured._id,
    })
    return NextResponse.json({ ok: true })
  } catch (error) {
    console.error("Failed to assign company", error)
    return NextResponse.json({ error: "Falha ao vincular usuário" }, { status: 500 })
  }
}
