import { headers } from "next/headers";
import { NextResponse } from "next/server";

import { db } from "@/server/db";
import { account, user } from "@/server/db/schemas/auth";
import { eq, like, or, sql } from "drizzle-orm";

import { auth } from "@/lib/auth/auth";

import type { UserRole } from "@/types/users";

/**
 * GET /api/users
 * Obtiene lista de usuarios con paginación y filtros
 * Solo accesible para admin y superAdmin
 */
export async function GET(request: Request) {
  try {
    const session = await auth.api.getSession({
      headers: await headers(),
    });

    if (!session) {
      return NextResponse.json(
        { success: false, error: "No autorizado" },
        { status: 401 },
      );
    }

    const userRole = (session.user as { role?: string }).role ?? "user";

    // Solo admin y superAdmin pueden ver usuarios
    if (userRole !== "admin" && userRole !== "superAdmin") {
      return NextResponse.json(
        { success: false, error: "No tienes permisos para ver usuarios" },
        { status: 403 },
      );
    }

    const { searchParams } = new URL(request.url);
    const page = parseInt(searchParams.get("page") ?? "1");
    const limit = parseInt(searchParams.get("limit") ?? "20");
    const offset = (page - 1) * limit;
    const search = searchParams.get("search");
    const role = searchParams.get("role");

    // Construir filtros
    const filters = [];

    // Si es admin (no superAdmin), solo puede ver usuarios normales
    if (userRole === "admin") {
      filters.push(eq(user.role, "user"));
    }

    // Si es superAdmin y hay filtro de rol, aplicarlo
    if (userRole === "superAdmin" && role) {
      filters.push(eq(user.role, role as "user" | "admin" | "superAdmin"));
    }

    if (search) {
      filters.push(
        or(like(user.name, `%${search}%`), like(user.email, `%${search}%`)),
      );
    }

    // Consulta principal
    const usersData = 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(filters.length > 0 ? or(...filters) : undefined)
      .limit(limit)
      .offset(offset);

    // Contar total
    const totalResult = await db
      .select({ count: sql<number>`count(*)::int` })
      .from(user)
      .where(filters.length > 0 ? or(...filters) : undefined);

    const total = totalResult[0]?.count || 0;
    const totalPages = Math.ceil(total / limit);

    return NextResponse.json({
      success: true,
      data: usersData,
      pagination: {
        page,
        limit,
        total,
        totalPages,
      },
    });
  } catch (error) {
    console.error("[API /users] Error:", error);
    return NextResponse.json(
      { success: false, error: "Error al obtener usuarios" },
      { status: 500 },
    );
  }
}

/**
 * POST /api/users
 * Crea un nuevo usuario
 * Solo accesible para admin y superAdmin
 */
export async function POST(request: Request) {
  try {
    const session = await auth.api.getSession({
      headers: await headers(),
    });

    if (!session) {
      return NextResponse.json(
        { success: false, error: "No autorizado" },
        { status: 401 },
      );
    }

    const userRole = (session.user as { role?: string }).role ?? "user";

    // Solo admin y superAdmin pueden crear usuarios
    if (userRole !== "admin" && userRole !== "superAdmin") {
      return NextResponse.json(
        { success: false, error: "No tienes permisos para crear usuarios" },
        { status: 403 },
      );
    }

    const body = (await request.json()) as {
      name?: string;
      email?: string;
      password?: string;
      role?: string;
    };
    const { name, email, password, role: newUserRole } = body;

    // Validaciones
    if (!name || !email || !password) {
      return NextResponse.json(
        { success: false, error: "Faltan campos requeridos" },
        { status: 400 },
      );
    }

    // Admin solo puede crear usuarios normales
    if (userRole === "admin" && newUserRole !== "user") {
      return NextResponse.json(
        {
          success: false,
          error: "Solo puedes crear usuarios con rol 'user'",
        },
        { status: 403 },
      );
    }

    // Verificar si el email ya existe
    const existingUser = await db
      .select()
      .from(user)
      .where(eq(user.email, email))
      .limit(1);

    if (existingUser.length > 0) {
      return NextResponse.json(
        { success: false, error: "El email ya está registrado" },
        { status: 400 },
      );
    }

    // Crear usuario y cuenta manualmente usando Better Auth
    const crypto = await import("crypto");

    // Obtener el contexto de Better Auth para usar su función de hash
    const context = await auth.$context;

    // Generar ID único para el usuario
    const userId = crypto.randomUUID();
    const now = new Date();

    // Hashear la contraseña usando la función de Better Auth
    // Esto garantiza compatibilidad total con el sistema de autenticación
    const hashedPassword = await context.password.hash(password);

    // 1. Crear el usuario
    const [newUser] = await db
      .insert(user)
      .values({
        id: userId,
        name,
        email,
        role: (newUserRole ?? "user") as UserRole,
        emailVerified: true,
        createdAt: now,
        updatedAt: now,
      })
      .returning();

    // 2. Crear la cuenta (credenciales)
    const accountId = crypto.randomUUID();
    await db.insert(account).values({
      id: accountId,
      accountId: email, // Better Auth usa el email como accountId para credentials
      providerId: "credential",
      userId: userId,
      password: hashedPassword,
      createdAt: now,
      updatedAt: now,
    });

    return NextResponse.json({
      success: true,
      data: newUser,
    });
  } catch (error) {
    console.error("[API /users] Error:", error);
    return NextResponse.json(
      { success: false, error: "Error al crear usuario" },
      { status: 500 },
    );
  }
}
