import { NextRequest, NextResponse } from "next/server";
import { requireAuth, requireMainAdmin, getClientMetadata } from "@/lib/admin/auth";
import { db, CustomRole } from "@/lib/admin/db";
import { SUB_ADMIN_ROLES, ROLE_PERMISSIONS, AdminPermission } from "@/lib/admin/permissions";

export const dynamic = "force-dynamic";

/**
 * GET /api/admin/roles
 * Lists all system roles and custom roles with assigned administrator counts.
 */
export async function GET(req: NextRequest) {
  try {
    const auth = await requireAuth(req);
    // Only Main Admin or users with roles.manage can view roles
    if (auth.user.level !== "MAIN_ADMIN" && auth.user.role !== "MAIN_ADMIN") {
      return NextResponse.json({ error: "Forbidden: Access requires Main Admin privileges." }, { status: 403 });
    }

    const customRoles = await db.getRoles();
    const allUsers = await db.getUsers();

    // Built-in system roles
    const systemRoles: (CustomRole & { assignedCount: number })[] = [
      {
        id: "MAIN_ADMIN",
        name: "Main Administrator",
        description: "Full, unrestricted system access and configuration control.",
        permissions: [...ROLE_PERMISSIONS.MAIN_ADMIN],
        isSystem: true,
        createdAt: new Date(0).toISOString(),
        updatedAt: new Date(0).toISOString(),
        createdBy: "SYSTEM",
        assignedCount: allUsers.filter((u) => u.level === "MAIN_ADMIN" || u.role === "MAIN_ADMIN").length,
      },
      ...SUB_ADMIN_ROLES.map((r) => ({
        id: r.id,
        name: r.label,
        description: r.description,
        permissions: [...(ROLE_PERMISSIONS[r.id] || [])],
        isSystem: true,
        createdAt: new Date(0).toISOString(),
        updatedAt: new Date(0).toISOString(),
        createdBy: "SYSTEM",
        assignedCount: allUsers.filter((u) => u.role === r.id).length,
      })),
    ];

    const mappedCustomRoles = customRoles.map((r) => ({
      ...r,
      assignedCount: allUsers.filter((u) => u.role === r.id).length,
    }));

    return NextResponse.json({
      roles: [...systemRoles, ...mappedCustomRoles],
    });
  } catch (err: any) {
    console.error("[GET /api/admin/roles] Error:", err);
    return NextResponse.json(
      { error: err.message || "Failed to fetch roles." },
      { status: err.status || 500 }
    );
  }
}

/**
 * POST /api/admin/roles
 * Creates a new custom sub-admin role.
 */
export async function POST(req: NextRequest) {
  try {
    const auth = await requireMainAdmin(req);
    const body = await req.json().catch(() => ({}));

    const name = typeof body.name === "string" ? body.name.trim() : "";
    const description = typeof body.description === "string" ? body.description.trim() : "";
    const permissions: string[] = Array.isArray(body.permissions) ? body.permissions : [];

    if (!name) {
      return NextResponse.json({ error: "Role name is required." }, { status: 400 });
    }

    // Role name cannot be equivalent to MAIN_ADMIN
    if (/main.*admin/i.test(name) || /super.*admin/i.test(name)) {
      return NextResponse.json(
        { error: "Custom role names cannot be equivalent to or mimic Main Admin." },
        { status: 400 }
      );
    }

    const slugId = `role_${name.toLowerCase().replace(/[^a-z0-9]+/g, "_").slice(0, 30)}_${Date.now().toString(36)}`;

    const newRole: CustomRole = {
      id: slugId,
      name,
      description,
      permissions: permissions.filter((p) => typeof p === "string"),
      isSystem: false,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
      createdBy: auth.user.email,
    };

    const created = await db.createRole(newRole);

    const { ip } = getClientMetadata(req);
    await db.logSecurityEvent({
      actorId: auth.user.id,
      actorName: auth.user.name,
      actorEmail: auth.user.email,
      actorLevel: auth.user.level,
      targetUserId: null,
      targetUserEmail: null,
      targetUserName: null,
      action: "ROLE_CHANGED",
      details: { roleName: name, roleId: slugId, permissionsCount: permissions.length },
      ipAddress: ip,
    });

    return NextResponse.json({ role: created }, { status: 201 });
  } catch (err: any) {
    console.error("[POST /api/admin/roles] Error:", err);
    return NextResponse.json(
      { error: err.message || "Failed to create custom role." },
      { status: err.status || 500 }
    );
  }
}
