import { getServerSession } from 'next-auth';
import { authOptions } from './auth-options';
import { PermissionCheck, AuthenticatedUser } from './types';

/**
 * Check if user has a specific permission
 * Permission format: resource:action:scope
 * Examples: finance:read:all, hr:write:department, inventory:delete:own
 */
export function hasPermission(
  userPermissions: string[],
  check: PermissionCheck
): boolean {
  const { resource, action, scope = 'all' } = check;

  // Check for exact match
  if (userPermissions.includes(`${resource}:${action}:${scope}`)) {
    return true;
  }

  // Check for broader scope permissions
  // 'all' scope includes 'department', 'team', 'own'
  if (scope !== 'all' && userPermissions.includes(`${resource}:${action}:all`)) {
    return true;
  }

  // Check for admin permission (grants all actions)
  if (action !== 'admin' && userPermissions.includes(`${resource}:admin:all`)) {
    return true;
  }

  // Check for super admin (system:admin:all grants everything)
  if (userPermissions.includes('system:admin:all')) {
    return true;
  }

  return false;
}

/**
 * Check if user has any of the specified permissions
 */
export function hasAnyPermission(
  userPermissions: string[],
  checks: PermissionCheck[]
): boolean {
  return checks.some((check) => hasPermission(userPermissions, check));
}

/**
 * Check if user has all of the specified permissions
 */
export function hasAllPermissions(
  userPermissions: string[],
  checks: PermissionCheck[]
): boolean {
  return checks.every((check) => hasPermission(userPermissions, check));
}

/**
 * Check if user has a specific role
 */
export function hasRole(userRoles: string[], role: string): boolean {
  return userRoles.includes(role);
}

/**
 * Check if user has any of the specified roles
 */
export function hasAnyRole(userRoles: string[], roles: string[]): boolean {
  return roles.some((role) => userRoles.includes(role));
}

/**
 * Server-side: Get current session and check permission
 * Returns the user if authorized, null otherwise
 */
export async function requirePermission(
  check: PermissionCheck
): Promise<AuthenticatedUser | null> {
  const session = await getServerSession(authOptions);

  if (!session?.user) {
    return null;
  }

  if (!hasPermission(session.user.permissions, check)) {
    return null;
  }

  return {
    id: session.user.id,
    email: session.user.email!,
    name: session.user.name || undefined,
    roles: session.user.roles,
    permissions: session.user.permissions,
    department: session.user.department,
  };
}

/**
 * Server-side: Get current session and check role
 * Returns the user if authorized, null otherwise
 */
export async function requireRole(
  role: string | string[]
): Promise<AuthenticatedUser | null> {
  const session = await getServerSession(authOptions);

  if (!session?.user) {
    return null;
  }

  const roles = Array.isArray(role) ? role : [role];
  if (!hasAnyRole(session.user.roles, roles)) {
    return null;
  }

  return {
    id: session.user.id,
    email: session.user.email!,
    name: session.user.name || undefined,
    roles: session.user.roles,
    permissions: session.user.permissions,
    department: session.user.department,
  };
}

/**
 * Server-side: Get current authenticated user
 * Returns null if not authenticated
 */
export async function getCurrentUser(): Promise<AuthenticatedUser | null> {
  const session = await getServerSession(authOptions);

  if (!session?.user) {
    return null;
  }

  return {
    id: session.user.id,
    email: session.user.email!,
    name: session.user.name || undefined,
    roles: session.user.roles,
    permissions: session.user.permissions,
    department: session.user.department,
  };
}

// Resource constants for type safety
export const RESOURCES = {
  SYSTEM: 'system',
  FINANCE: 'finance',
  HR: 'hr',
  INVENTORY: 'inventory',
  CRM: 'crm',
  DOCUMENTS: 'documents',
  CONTRACTS: 'contracts',
  WORKFLOWS: 'workflows',
  AGENTS: 'agents',
  REPORTS: 'reports',
  SETTINGS: 'settings',
} as const;

export const ACTIONS = {
  READ: 'read',
  WRITE: 'write',
  DELETE: 'delete',
  APPROVE: 'approve',
  ADMIN: 'admin',
} as const;

export const SCOPES = {
  ALL: 'all',
  DEPARTMENT: 'department',
  TEAM: 'team',
  OWN: 'own',
} as const;
