/**
 * API de Avatar
 * POST - Faz upload de uma nova foto de perfil
 * DELETE - Remove a foto de perfil (volta ao padrão)
 */

import { NextResponse } from "next/server"

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

const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB
const ALLOWED_TYPES = ["image/jpeg", "image/png", "image/webp", "image/gif"]

function extractSetCookies(headers: Headers) {
  const headersWithGetSetCookie = headers as Headers & { getSetCookie?: () => string[] | undefined }
  let setCookieHeaders =
    typeof headersWithGetSetCookie.getSetCookie === "function"
      ? headersWithGetSetCookie.getSetCookie() ?? []
      : []

  if (setCookieHeaders.length === 0) {
    const single = headers.get("set-cookie")
    if (single) {
      setCookieHeaders = [single]
    }
  }

  return setCookieHeaders
}

export async function POST(request: Request) {
  try {
    const session = await getServerSession()

    if (!session?.user?.id) {
      return NextResponse.json({ error: "Não autorizado" }, { status: 401 })
    }

    const formData = await request.formData()
    const file = formData.get("file") as File | null

    if (!file) {
      return NextResponse.json({ error: "Nenhum arquivo enviado" }, { status: 400 })
    }

    // Valida tipo
    if (!ALLOWED_TYPES.includes(file.type)) {
      return NextResponse.json(
        { error: "Tipo de arquivo não permitido. Use JPG, PNG, WebP ou GIF." },
        { status: 400 }
      )
    }

    // Valida tamanho
    if (file.size > MAX_FILE_SIZE) {
      return NextResponse.json(
        { error: "Arquivo muito grande. Máximo 5MB." },
        { status: 400 }
      )
    }

    const convex = createConvexClient()

    // Gera URL de upload
    const uploadUrl = await convex.action(api.files.generateUploadUrl, {})

    // Faz upload do arquivo
    const uploadResponse = await fetch(uploadUrl, {
      method: "POST",
      headers: { "Content-Type": file.type },
      body: file,
    })

    if (!uploadResponse.ok) {
      console.error("[profile/avatar] Erro no upload:", await uploadResponse.text())
      return NextResponse.json({ error: "Erro ao fazer upload" }, { status: 500 })
    }

    const { storageId } = (await uploadResponse.json()) as { storageId: Id<"_storage"> }

    // Obtém URL pública do arquivo
    const avatarUrl = await convex.action(api.files.getUrl, { storageId })

    if (!avatarUrl) {
      return NextResponse.json({ error: "Erro ao obter URL do avatar" }, { status: 500 })
    }

    // Atualiza no Better Auth e propaga Set-Cookie para invalidar o cookieCache da sessao (avatarUrl, etc)
    let authSetCookies: string[] = []
    try {
      const updateResponse = await auth.api.updateUser({
        request,
        headers: request.headers,
        body: { avatarUrl },
        asResponse: true,
      })

      if (!updateResponse?.ok) {
        throw new Error(`Falha ao atualizar usuario no Better Auth (${updateResponse?.status ?? "sem status"})`)
      }

      authSetCookies = extractSetCookies(updateResponse.headers)
    } catch (error) {
      console.warn("[profile/avatar] Falha ao atualizar sessao via Better Auth, usando fallback Prisma:", error)
      await prisma.authUser.update({
        where: { id: session.user.id },
        data: { avatarUrl },
      })
    }

    // Sincroniza com o Convex
    try {
      const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID
      await convex.mutation(api.users.updateAvatar, {
        tenantId,
        email: session.user.email,
        avatarUrl,
      })
    } catch (error) {
      console.warn("[profile/avatar] Falha ao sincronizar avatar no Convex:", error)
    }

    const response = NextResponse.json({
      success: true,
      avatarUrl,
    })

    for (const cookie of authSetCookies) {
      response.headers.append("set-cookie", cookie)
    }

    return response
  } catch (error) {
    console.error("[profile/avatar] Erro:", error)
    return NextResponse.json({ error: "Erro interno do servidor" }, { status: 500 })
  }
}

export async function DELETE(request: Request) {
  try {
    const session = await getServerSession()

    if (!session?.user?.id) {
      return NextResponse.json({ error: "Não autorizado" }, { status: 401 })
    }

    // Atualiza no Better Auth e propaga Set-Cookie para invalidar o cookieCache da sessao (avatarUrl, etc)
    let authSetCookies: string[] = []
    try {
      const updateResponse = await auth.api.updateUser({
        request,
        headers: request.headers,
        body: { avatarUrl: null },
        asResponse: true,
      })

      if (!updateResponse?.ok) {
        throw new Error(`Falha ao atualizar usuario no Better Auth (${updateResponse?.status ?? "sem status"})`)
      }

      authSetCookies = extractSetCookies(updateResponse.headers)
    } catch (error) {
      console.warn("[profile/avatar] Falha ao atualizar sessao via Better Auth, usando fallback Prisma:", error)
      await prisma.authUser.update({
        where: { id: session.user.id },
        data: { avatarUrl: null },
      })
    }

    // Sincroniza com o Convex
    try {
      const convex = createConvexClient()
      const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID
      await convex.mutation(api.users.updateAvatar, {
        tenantId,
        email: session.user.email,
        avatarUrl: null,
      })
    } catch (error) {
      console.warn("[profile/avatar] Falha ao sincronizar remoção de avatar no Convex:", error)
    }

    const response = NextResponse.json({
      success: true,
      message: "Foto removida com sucesso",
    })

    for (const cookie of authSetCookies) {
      response.headers.append("set-cookie", cookie)
    }

    return response
  } catch (error) {
    console.error("[profile/avatar] Erro ao remover:", error)
    return NextResponse.json({ error: "Erro interno do servidor" }, { status: 500 })
  }
}

/**
 * PATCH - Força sincronização do avatar atual do Prisma para o Convex
 * Útil quando a sincronização automática falhou
 */
export async function PATCH() {
  try {
    const session = await getServerSession()

    if (!session?.user?.id) {
      return NextResponse.json({ error: "Não autorizado" }, { status: 401 })
    }

    // Busca o avatar atual no Prisma
    const user = await prisma.authUser.findUnique({
      where: { id: session.user.id },
      select: { avatarUrl: true },
    })

    // Sincroniza com o Convex
    const convex = createConvexClient()
    const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID

    const result = await convex.mutation(api.users.updateAvatar, {
      tenantId,
      email: session.user.email,
      avatarUrl: user?.avatarUrl ?? null,
    })

    console.log("[profile/avatar] Sincronização forçada:", result)

    return NextResponse.json({
      success: true,
      message: "Avatar sincronizado com sucesso",
      avatarUrl: user?.avatarUrl ?? null,
      convexResult: result,
    })
  } catch (error) {
    console.error("[profile/avatar] Erro na sincronização:", error)
    return NextResponse.json({ error: "Erro ao sincronizar avatar" }, { status: 500 })
  }
}
