import { and, eq, isNull } from "drizzle-orm";
import { NextResponse } from "next/server";
import { tokensApi } from "@/db/schema";
import {
	extractBearerToken,
	hashToken,
	refreshAccessToken,
	verifyJwt,
} from "@/lib/auth/api-token";
import { db } from "@/lib/db";

export async function POST(request: Request) {
	try {
		// Extrair refresh token do header
		const authHeader = request.headers.get("Authorization");
		const token = extractBearerToken(authHeader);

		if (!token) {
			return NextResponse.json(
				{ error: "Refresh token não fornecido" },
				{ status: 401 },
			);
		}

		// Validar refresh token
		const payload = verifyJwt(token);

		if (!payload || payload.type !== "api_refresh") {
			return NextResponse.json(
				{ error: "Refresh token inválido ou expirado" },
				{ status: 401 },
			);
		}

		// Verificar se token não foi revogado
		const tokenRecord = await db.query.tokensApi.findFirst({
			where: and(
				eq(tokensApi.id, payload.tokenId),
				eq(tokensApi.userId, payload.sub),
				isNull(tokensApi.revokedAt),
			),
		});

		if (!tokenRecord) {
			return NextResponse.json(
				{ error: "Token revogado ou não encontrado" },
				{ status: 401 },
			);
		}

		// Gerar novo access token
		const result = refreshAccessToken(token);

		if (!result) {
			return NextResponse.json(
				{ error: "Não foi possível renovar o token" },
				{ status: 401 },
			);
		}

		// Atualizar hash do token e último uso
		await db
			.update(tokensApi)
			.set({
				tokenHash: hashToken(result.accessToken),
				lastUsedAt: new Date(),
				lastUsedIp:
					request.headers.get("x-forwarded-for") ||
					request.headers.get("x-real-ip"),
				expiresAt: result.expiresAt,
			})
			.where(eq(tokensApi.id, payload.tokenId));

		return NextResponse.json({
			accessToken: result.accessToken,
			expiresAt: result.expiresAt.toISOString(),
		});
	} catch (error) {
		console.error("[API] Error refreshing device token:", error);
		return NextResponse.json(
			{ error: "Erro ao renovar token" },
			{ status: 500 },
		);
	}
}
