import { StaffRole } from '@prisma/client'

/**
 * Permission definitions for the Hub
 */
export type Permission =
  // Dashboard
  | 'dashboard:view'
  // Orders
  | 'orders:view'
  | 'orders:create'
  | 'orders:edit'
  | 'orders:provision'
  | 'orders:delete'
  // Customers
  | 'customers:view'
  | 'customers:create'
  | 'customers:edit'
  | 'customers:delete'
  // Servers
  | 'servers:view'
  | 'servers:power'
  | 'servers:snapshots'
  | 'servers:rescue'
  // Staff Management
  | 'staff:view'
  | 'staff:invite'
  | 'staff:manage'
  | 'staff:delete'
  // System Settings
  | 'settings:view'
  | 'settings:edit'
  // Enterprise Clients
  | 'enterprise:view'
  | 'enterprise:manage'

/**
 * Permission matrix for each role
 * OWNER: Full access, cannot be deleted
 * ADMIN: Full access, can manage staff (but not delete)
 * MANAGER: Orders + servers, no staff/settings
 * SUPPORT: View only + limited actions
 */
const ROLE_PERMISSIONS: Record<StaffRole, Permission[]> = {
  OWNER: [
    // Dashboard
    'dashboard:view',
    // Orders - full access
    'orders:view',
    'orders:create',
    'orders:edit',
    'orders:provision',
    'orders:delete',
    // Customers - full access
    'customers:view',
    'customers:create',
    'customers:edit',
    'customers:delete',
    // Servers - full access
    'servers:view',
    'servers:power',
    'servers:snapshots',
    'servers:rescue',
    // Staff - full access including delete
    'staff:view',
    'staff:invite',
    'staff:manage',
    'staff:delete',
    // Settings - full access
    'settings:view',
    'settings:edit',
    // Enterprise - full access
    'enterprise:view',
    'enterprise:manage',
  ],

  ADMIN: [
    // Dashboard
    'dashboard:view',
    // Orders - full access
    'orders:view',
    'orders:create',
    'orders:edit',
    'orders:provision',
    'orders:delete',
    // Customers - full access
    'customers:view',
    'customers:create',
    'customers:edit',
    'customers:delete',
    // Servers - full access
    'servers:view',
    'servers:power',
    'servers:snapshots',
    'servers:rescue',
    // Staff - can invite and manage but NOT delete
    'staff:view',
    'staff:invite',
    'staff:manage',
    // Settings - full access
    'settings:view',
    'settings:edit',
    // Enterprise - full access
    'enterprise:view',
    'enterprise:manage',
  ],

  MANAGER: [
    // Dashboard
    'dashboard:view',
    // Orders - full operational access
    'orders:view',
    'orders:create',
    'orders:edit',
    'orders:provision',
    // Customers - full access
    'customers:view',
    'customers:create',
    'customers:edit',
    // Servers - full operational access
    'servers:view',
    'servers:power',
    'servers:snapshots',
    'servers:rescue',
    // Enterprise - view and manage
    'enterprise:view',
    'enterprise:manage',
    // No staff or settings access
  ],

  SUPPORT: [
    // Dashboard
    'dashboard:view',
    // Orders - view only
    'orders:view',
    // Customers - view only
    'customers:view',
    // Servers - view only
    'servers:view',
    // Enterprise - view only
    'enterprise:view',
    // No staff, settings, or action permissions
  ],
}

/**
 * Check if a role has a specific permission
 */
export function hasPermission(role: StaffRole, permission: Permission): boolean {
  const permissions = ROLE_PERMISSIONS[role]
  return permissions?.includes(permission) ?? false
}

/**
 * Check if a role has all of the specified permissions
 */
export function hasAllPermissions(role: StaffRole, permissions: Permission[]): boolean {
  return permissions.every(permission => hasPermission(role, permission))
}

/**
 * Check if a role has any of the specified permissions
 */
export function hasAnyPermission(role: StaffRole, permissions: Permission[]): boolean {
  return permissions.some(permission => hasPermission(role, permission))
}

/**
 * Get all permissions for a role
 */
export function getPermissions(role: StaffRole): Permission[] {
  return ROLE_PERMISSIONS[role] ?? []
}

/**
 * Get human-readable role display name
 */
export function getRoleDisplayName(role: StaffRole): string {
  switch (role) {
    case 'OWNER':
      return 'Owner'
    case 'ADMIN':
      return 'Administrator'
    case 'MANAGER':
      return 'Manager'
    case 'SUPPORT':
      return 'Support'
    default:
      return role
  }
}

/**
 * Get role description
 */
export function getRoleDescription(role: StaffRole): string {
  switch (role) {
    case 'OWNER':
      return 'Full access to all features. Cannot be deleted.'
    case 'ADMIN':
      return 'Full access to all features. Can manage staff but not delete them.'
    case 'MANAGER':
      return 'Can manage orders, customers, and servers. No access to staff or settings.'
    case 'SUPPORT':
      return 'View-only access to orders, customers, and servers.'
    default:
      return ''
  }
}

/**
 * Check if a role can manage another role
 * OWNER can manage anyone
 * ADMIN can manage MANAGER and SUPPORT
 * Others cannot manage anyone
 */
export function canManageRole(managerRole: StaffRole, targetRole: StaffRole): boolean {
  if (managerRole === 'OWNER') {
    return true
  }
  if (managerRole === 'ADMIN') {
    return targetRole === 'MANAGER' || targetRole === 'SUPPORT'
  }
  return false
}

/**
 * Check if a role can delete another role
 * Only OWNER can delete staff
 */
export function canDeleteRole(managerRole: StaffRole, targetRole: StaffRole): boolean {
  // Only OWNER can delete
  if (managerRole !== 'OWNER') {
    return false
  }
  // Cannot delete other OWNER accounts
  if (targetRole === 'OWNER') {
    return false
  }
  return true
}

/**
 * Get available roles that a staff member can assign when inviting
 * OWNER can invite any role (except OWNER)
 * ADMIN can invite ADMIN, MANAGER, SUPPORT (but not OWNER)
 */
export function getAssignableRoles(currentRole: StaffRole): StaffRole[] {
  if (currentRole === 'OWNER') {
    return ['ADMIN', 'MANAGER', 'SUPPORT']
  }
  if (currentRole === 'ADMIN') {
    return ['ADMIN', 'MANAGER', 'SUPPORT']
  }
  return []
}

/**
 * Permission service singleton for convenience
 */
export const permissionService = {
  hasPermission,
  hasAllPermissions,
  hasAnyPermission,
  getPermissions,
  getRoleDisplayName,
  getRoleDescription,
  canManageRole,
  canDeleteRole,
  getAssignableRoles,
}
