import { headers } from "next/headers";
import { NextResponse } from "next/server";

import env from "@/env";
import { db } from "@/server/db";
import {
  account as accountTable,
  session as sessionTable,
  user,
} from "@/server/db/schemas/auth";
import { eq } from "drizzle-orm";

import { auth } from "@/lib/auth/auth";

/**
 * GET /api/users/[id]
 * Obtiene un usuario específico
 */
export async function GET(
  request: Request,
  { params }: { params: Promise<{ id: string }> },
) {
  try {
    const session = await auth.api.getSession({
      headers: await headers(),
    });

    if (!session) {
      return NextResponse.json(
        { success: false, error: "No autorizado" },
        { status: 401 },
      );
    }

    const { id } = await params;
    const userRole = (session.user as { role?: string }).role ?? "user";

    // Solo admin y superAdmin pueden ver detalles de otros usuarios
    if (
      userRole !== "admin" &&
      userRole !== "superAdmin" &&
      session.user.id !== id
    ) {
      return NextResponse.json(
        { success: false, error: "No tienes permisos" },
        { status: 403 },
      );
    }

    const [userData] = await db
      .select({
        id: user.id,
        name: user.name,
        email: user.email,
        role: user.role,
        emailVerified: user.emailVerified,
        image: user.image,
        createdAt: user.createdAt,
        updatedAt: user.updatedAt,
        banned: user.banned,
        banReason: user.banReason,
        banExpires: user.banExpires,
      })
      .from(user)
      .where(eq(user.id, id))
      .limit(1);

    if (!userData) {
      return NextResponse.json(
        { success: false, error: "Usuario no encontrado" },
        { status: 404 },
      );
    }

    return NextResponse.json({
      success: true,
      data: userData,
    });
  } catch (error) {
    console.error("[API /users/[id]] Error:", error);
    return NextResponse.json(
      { success: false, error: "Error al obtener usuario" },
      { status: 500 },
    );
  }
}

/**
 * PUT /api/users/[id]
 * Actualiza un usuario
 */
export async function PUT(
  request: Request,
  { params }: { params: Promise<{ id: string }> },
) {
  try {
    const session = await auth.api.getSession({
      headers: await headers(),
    });

    if (!session) {
      return NextResponse.json(
        { success: false, error: "No autorizado" },
        { status: 401 },
      );
    }

    const { id } = await params;
    const userRole = (session.user as { role?: string }).role ?? "user";

    // Solo admin y superAdmin pueden editar usuarios
    if (userRole !== "admin" && userRole !== "superAdmin") {
      return NextResponse.json(
        { success: false, error: "No tienes permisos para editar usuarios" },
        { status: 403 },
      );
    }

    const body = (await request.json()) as {
      name?: string;
      email?: string;
      role?: string;
      banned?: boolean;
      banReason?: string;
    };
    const { name, email, role: newRole, banned, banReason } = body;

    // Verificar que el usuario existe
    const [existingUser] = await db
      .select()
      .from(user)
      .where(eq(user.id, id))
      .limit(1);

    if (!existingUser) {
      return NextResponse.json(
        { success: false, error: "Usuario no encontrado" },
        { status: 404 },
      );
    }

    // Admin no puede editar roles ni banear
    if (userRole === "admin" && (newRole || banned !== undefined)) {
      return NextResponse.json(
        {
          success: false,
          error: "No tienes permisos para cambiar roles o banear usuarios",
        },
        { status: 403 },
      );
    }

    // Preparar datos de actualización
    const updateData: Record<string, unknown> = {
      updatedAt: new Date(),
    };

    if (name) updateData.name = name;
    if (email) updateData.email = email;
    if (newRole && userRole === "superAdmin") updateData.role = newRole;
    if (banned !== undefined && userRole === "superAdmin")
      updateData.banned = banned;
    if (banReason && userRole === "superAdmin")
      updateData.banReason = banReason;

    // Actualizar usuario
    const [updatedUser] = await db
      .update(user)
      .set(updateData)
      .where(eq(user.id, id))
      .returning();

    return NextResponse.json({
      success: true,
      data: updatedUser,
    });
  } catch (error) {
    console.error("[API /users/[id]] Error:", error);
    return NextResponse.json(
      { success: false, error: "Error al actualizar usuario" },
      { status: 500 },
    );
  }
}

/**
 * DELETE /api/users/[id]
 * Elimina un usuario (solo superAdmin)
 */
export async function DELETE(
  request: Request,
  { params }: { params: Promise<{ id: string }> },
) {
  try {
    const session = await auth.api.getSession({
      headers: await headers(),
    });

    if (!session) {
      return NextResponse.json(
        { success: false, error: "No autorizado" },
        { status: 401 },
      );
    }

    const { id } = await params;
    const userRole = (session.user as { role?: string }).role ?? "user";

    // Solo superAdmin puede eliminar usuarios
    if (userRole !== "superAdmin") {
      return NextResponse.json(
        { success: false, error: "No tienes permisos para eliminar usuarios" },
        { status: 403 },
      );
    }

    // No permitir auto-eliminación
    if (session.user.id === id) {
      return NextResponse.json(
        { success: false, error: "No puedes eliminar tu propio usuario" },
        { status: 400 },
      );
    }

    // Verificar que el usuario existe
    const [existingUser] = await db
      .select()
      .from(user)
      .where(eq(user.id, id))
      .limit(1);

    if (!existingUser) {
      return NextResponse.json(
        { success: false, error: "Usuario no encontrado" },
        { status: 404 },
      );
    }

    // Proteger al usuario administrador principal (por defecto admin@example.com)
    const protectedAdminEmail = env.ADMIN_EMAIL ?? "admin@example.com";
    if (existingUser.email === protectedAdminEmail) {
      return NextResponse.json(
        {
          success: false,
          error: "No se puede eliminar el usuario administrador principal",
        },
        { status: 403 },
      );
    }

    // Eliminar en orden: primero sessions, luego accounts, finalmente user
    // Esto respeta las restricciones de llave foránea

    // 1. Eliminar todas las sesiones del usuario
    await db.delete(sessionTable).where(eq(sessionTable.userId, id));

    // 2. Eliminar todas las cuentas del usuario
    await db.delete(accountTable).where(eq(accountTable.userId, id));

    // 3. Finalmente eliminar el usuario
    await db.delete(user).where(eq(user.id, id));

    return NextResponse.json({
      success: true,
      message: "Usuario eliminado correctamente",
    });
  } catch (error) {
    console.error("[API /users/[id]] Error:", error);
    return NextResponse.json(
      { success: false, error: "Error al eliminar usuario" },
      { status: 500 },
    );
  }
}
