import { NextRequest, NextResponse } from "next/server";
import { db, isDatabaseAvailable } from "@/lib/db";
import { ensureDatabaseInitialized } from "@/lib/db/init";
import { getAdminUser } from "@/lib/auth/admin";
import { clientIp } from "@/lib/auth/rateLimit";
import {
  logSecurityEventAsync,
  SecurityEventType,
} from "@/lib/auth/securityEvents";
import { users } from "@/lib/schema/db";
import { eq, desc, asc, sql, count, like, or, and, ilike } from "drizzle-orm";

export const runtime = "nodejs";

export async function GET(req: NextRequest) {
  const admin = await getAdminUser();
  if (!admin) return NextResponse.json({ error: 'Forbidden' }, { status: 403 });

  logSecurityEventAsync({
    type: SecurityEventType.ADMIN_ACTION,
    userId: admin.id,
    email: admin.email,
    ip: clientIp(req),
    userAgent: req.headers.get("user-agent"),
    metadata: { route: "/api/admin/users", method: "GET" },
  });

  if (!(await isDatabaseAvailable())) {
    return NextResponse.json({ error: 'Database unavailable' }, { status: 503 });
  }
  await ensureDatabaseInitialized();

  const searchParams = req.nextUrl.searchParams;
  const search = searchParams.get("search")?.trim() || "";
  const plan = searchParams.get("plan") || "";
  const useCaseFilter = searchParams.get("useCase") || "";
  const sort = searchParams.get("sort") || "createdAt";
  const order = searchParams.get("order") || "desc";
  const page = parseInt(searchParams.get("page") || "1", 10);
  const limit = parseInt(searchParams.get("limit") || "50", 10);
  const offset = (page - 1) * limit;

  try {
    let conditions = [eq(users.isGuest, false)];

    if (search) {
      conditions.push(or(
        ilike(users.email, `%${search}%`),
        ilike(users.name, `%${search}%`)
      )!);
    }
    
    if (plan && plan !== "all") {
      conditions.push(eq(users.plan, plan as any));
    }

    if (useCaseFilter && useCaseFilter !== "all") {
      conditions.push(eq(users.useCase, useCaseFilter));
    }

    const whereClause = and(...conditions);

    let orderByField;
    switch (sort) {
      case "email": orderByField = users.email; break;
      case "name": orderByField = users.name; break;
      case "plan": orderByField = users.plan; break;
      case "scanCount": orderByField = users.scanCount; break;
      default: orderByField = users.createdAt; break;
    }

    const orderBy = order === "asc" ? asc(orderByField) : desc(orderByField);

    const [totalResult, usersList] = await Promise.all([
      db.select({ count: count() }).from(users).where(whereClause),
      db.select({
        id: users.id,
        email: users.email,
        name: users.name,
        plan: users.plan,
        scanCount: users.scanCount,
        company: users.company,
        useCase: users.useCase,
        monthlyVolume: users.monthlyVolume,
        exportFormat: users.exportFormat,
        mainPainPoint: users.mainPainPoint,
        referralSource: users.referralSource,
        onboardingCompletedAt: users.onboardingCompletedAt,
        emailVerifiedAt: users.emailVerifiedAt,
        createdAt: users.createdAt,
        updatedAt: users.updatedAt
      })
      .from(users)
      .where(whereClause)
      .orderBy(orderBy)
      .limit(limit)
      .offset(offset)
    ]);

    return NextResponse.json({
      users: usersList,
      total: Number(totalResult[0]?.count ?? 0),
      page,
      limit
    });
  } catch (error) {
    console.error("Admin users error:", error);
    return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
  }
}
