import { Request, Response, NextFunction } from 'express'
import { UserRole, ROLE_PERMISSIONS } from '@skillmate/shared'

export interface AuthRequest extends Request {
  user?: {
    id: string
    username: string
    email: string
    role: UserRole
    employeeId?: string
  }
}

export function hasPermission(userRole: UserRole, permission: string): boolean {
  const rolePermissions = ROLE_PERMISSIONS[userRole] || []
  return rolePermissions.includes(permission)
}

export function requirePermission(permission: string) {
  return (req: AuthRequest, res: Response, next: NextFunction) => {
    if (!req.user) {
      return res.status(401).json({ error: 'Unauthorized' })
    }

    if (!hasPermission(req.user.role, permission)) {
      return res.status(403).json({ 
        error: 'Forbidden', 
        message: `Insufficient permissions. Required: ${permission}` 
      })
    }

    next()
  }
}

export function requireRole(roles: UserRole | UserRole[]) {
  const allowedRoles = Array.isArray(roles) ? roles : [roles]
  
  return (req: AuthRequest, res: Response, next: NextFunction) => {
    if (!req.user) {
      return res.status(401).json({ error: 'Unauthorized' })
    }

    if (!allowedRoles.includes(req.user.role)) {
      return res.status(403).json({ 
        error: 'Forbidden', 
        message: `Access denied. Required role: ${allowedRoles.join(' or ')}` 
      })
    }

    next()
  }
}

export function requireAdminPanel() {
  return requirePermission('admin:panel:access')
}

export function canEditEmployee(req: AuthRequest, targetEmployeeId: string): boolean {
  if (!req.user) return false
  
  // Admins can edit anyone
  if (req.user.role === 'admin') return true
  
  // Superusers can edit any employee
  if (req.user.role === 'superuser') return true
  
  // Users can only edit their own profile (if linked to employee)
  if (req.user.role === 'user' && req.user.employeeId === targetEmployeeId) {
    return true
  }
  
  return false
}

export function requireEditPermission(getTargetId: (req: AuthRequest) => string) {
  return (req: AuthRequest, res: Response, next: NextFunction) => {
    if (!req.user) {
      return res.status(401).json({ error: 'Unauthorized' })
    }

    const targetId = getTargetId(req)
    
    if (!canEditEmployee(req, targetId)) {
      return res.status(403).json({ 
        error: 'Forbidden', 
        message: 'You can only edit your own profile' 
      })
    }

    next()
  }
}