import jwt from "jsonwebtoken";
import type { H3Event } from "h3";
import { User } from "../models/User";

export interface AuthUser {
  userId: string;
  username: string;
  roles: string[];
  permissions: {
    canEdit: boolean;
    canModerate: boolean;
    canAdmin: boolean;
  };
}

export async function verifyAuth(event: H3Event): Promise<AuthUser | null> {
  const config = useRuntimeConfig();
  const token = getCookie(event, "auth-token");

  if (!token) {
    return null;
  }

  try {
    const decoded = jwt.verify(token, config.jwtSecret as string) as AuthUser;
    return decoded;
  } catch (error) {
    return null;
  }
}

export async function requireAuth(event: H3Event): Promise<AuthUser> {
  const user = await verifyAuth(event);

  if (!user) {
    throw createError({
      statusCode: 401,
      statusMessage: "Authentication required",
    });
  }

  return user;
}

export async function requireRole(
  event: H3Event,
  requiredRoles: string[],
): Promise<AuthUser> {
  const user = await requireAuth(event);

  const hasRole = requiredRoles.some((role) => user.roles.includes(role));

  if (!hasRole) {
    throw createError({
      statusCode: 403,
      statusMessage: "Insufficient permissions",
    });
  }

  return user;
}

export async function checkAccessLevel(
  event: H3Event,
  accessLevel: "public" | "member" | "cohort" | "admin",
  cohorts?: string[],
): Promise<boolean> {
  // Public content is always accessible
  if (accessLevel === "public") {
    return true;
  }

  const user = await verifyAuth(event);

  // No user = no access to protected content
  if (!user) {
    return false;
  }

  // Check access levels
  switch (accessLevel) {
    case "member":
      // Any authenticated user has member access
      return true;

    case "cohort":
      // Check if user belongs to required cohorts
      if (!cohorts || cohorts.length === 0) {
        return true; // No specific cohort required
      }
      return cohorts.some((cohort) => user.roles.includes(`cohort-${cohort}`));

    case "admin":
      // Only admins have admin access
      return user.permissions.canAdmin || user.roles.includes("admin");

    default:
      return false;
  }
}
