import { auth, currentUser } from "@clerk/nextjs/server";
import { prisma } from "@/lib/prisma";
import { canAccess, isAtLeast } from "@/lib/permissions";
import type { Role } from "@/lib/permissions";

/**
 * Get the current Clerk user ID (fast, no API call)
 */
export async function getAuthUserId(): Promise<string | null> {
  const { userId } = await auth();
  return userId;
}

/**
 * Get or create a database user from Clerk's user data.
 * Called when we need the Prisma user record.
 */
export async function getCurrentUser() {
  const clerkUser = await currentUser();
  if (!clerkUser) return null;

  const email = clerkUser.emailAddresses[0]?.emailAddress;
  if (!email) return null;

  // Find or create user in our database
  let user = await prisma.user.findUnique({
    where: { email },
    include: {
      memberships: {
        include: { organization: true },
      },
    },
  });

  if (!user) {
    user = await prisma.user.create({
      data: {
        id: clerkUser.id,
        name: `${clerkUser.firstName || ""} ${clerkUser.lastName || ""}`.trim() || null,
        email,
        image: clerkUser.imageUrl,
      },
      include: {
        memberships: {
          include: { organization: true },
        },
      },
    });
  } else if (user.id.startsWith("pending_")) {
    // Placeholder user created during invite — migrate memberships to real Clerk user
    const pendingId = user.id;
    const name = `${clerkUser.firstName || ""} ${clerkUser.lastName || ""}`.trim() || user.name;
    await prisma.orgMembership.updateMany({ where: { userId: pendingId }, data: { userId: clerkUser.id } });
    await prisma.user.delete({ where: { id: pendingId } });
    user = await prisma.user.create({
      data: { id: clerkUser.id, email, name, image: clerkUser.imageUrl },
      include: { memberships: { include: { organization: true } } },
    });
  }

  return user;
}

// ─── Role-based helpers ──────────────────────────────────────────────────────

/**
 * Get the user's role in a specific org.
 * Returns "viewer" if not found (safe default — least permissions).
 */
export function getUserRole(
  user: { memberships: Array<{ orgId: string; role: string }> },
  orgId: string
): Role {
  const membership = user.memberships.find(m => m.orgId === orgId);
  return (membership?.role as Role) ?? "viewer";
}

/**
 * Get the user's role in their first org.
 * Convenience for single-org users.
 */
export function getUserPrimaryRole(
  user: { memberships: Array<{ orgId: string; role: string }> }
): { role: Role; orgId: string } {
  const m = user.memberships[0];
  return { role: (m?.role as Role) ?? "viewer", orgId: m?.orgId ?? "" };
}

/**
 * API route guard — checks if the current user has permission.
 * Returns null if allowed, or a NextResponse 403 if denied.
 *
 * Usage in an API route:
 *   const denied = await requirePermission("billing");
 *   if (denied) return denied;
 */
export async function requirePermission(permission: string): Promise<Response | null> {
  const user = await getCurrentUser();
  if (!user) {
    return new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401 });
  }

  const { role } = getUserPrimaryRole(user);

  if (!canAccess(role, permission)) {
    return new Response(
      JSON.stringify({
        error: "Forbidden",
        message: `This action requires ${permission} permission. Your role: ${role}`,
      }),
      { status: 403 }
    );
  }

  return null; // Allowed
}

// Re-export for convenience
export { canAccess, isAtLeast };
export type { Role };
