"""
PREPOC ERP - Attribute-Based Access Control (ABAC) Policy Engine
Evaluates contextual access (ownership, management hierarchy, branch) beyond simple RBAC.
"""

def _get_owner_user(record):
    """Helper to extract the owner User from a record."""
    user_field = getattr(record, "user", None) or getattr(record, "employee", None)
    if user_field is None:
        return None
    return getattr(user_field, "user", user_field)


def can_access_record(user, record) -> bool:
    """
    Returns True if the user has contextual rights to view this record.
    Admins can view anything. Employees can view their own records.
    Managers can view records of their reports.
    """
    if user.role in ("SUPER_ADMIN", "HR_MANAGER", "ACCOUNTANT"):
        return True
    
    # Ownership
    owner_user = _get_owner_user(record)
    if owner_user == user:
        return True
        
    # Manager hierarchy (e.g., Team Manager viewing a direct report's profile)
    if hasattr(record, "reporting_manager"):
        manager = getattr(record, "reporting_manager")
        if manager and getattr(manager, "user", None) == user:
            return True
            
    # For records tied to an employee (like Leave, Attendance)
    if hasattr(record, "employee") and hasattr(record.employee, "reporting_manager"):
        manager = record.employee.reporting_manager
        if manager and getattr(manager, "user", None) == user:
            return True

    return False


def can_edit_record(user, record) -> bool:
    """
    Returns True if the user can modify this record.
    Generally, employees can edit their own profiles/requests, admins can edit anything.
    """
    if user.role in ("SUPER_ADMIN", "HR_MANAGER"):
        return True
    
    owner_user = _get_owner_user(record)
    if owner_user == user:
        return True
        
    return False


def can_approve_record(user, record) -> bool:
    """
    Returns True if the user can approve this record (e.g., Leave, Expense).
    """
    if user.role in ("SUPER_ADMIN", "HR_MANAGER", "ACCOUNTANT"):
        return True
        
    if hasattr(record, "approver") and getattr(record, "approver", None) == user:
        return True
        
    # Implicit approval rights if user is the reporting manager of the record's owner
    if hasattr(record, "employee") and hasattr(record.employee, "reporting_manager"):
        manager = record.employee.reporting_manager
        if manager and getattr(manager, "user", None) == user:
            return True
            
    return False


def can_delete_record(user, record) -> bool:
    """
    Returns True if the user can delete this record.
    Only Admins or HR Managers typically hard-delete records.
    """
    return user.role in ("SUPER_ADMIN", "HR_MANAGER")


def can_view_sensitive_fields(user, record) -> bool:
    """
    Determines if sensitive fields (Salary, PAN, Aadhaar) are visible.
    Visible only to the employee themselves, or HR/Accountants.
    """
    if user.role in ("SUPER_ADMIN", "HR_MANAGER", "ACCOUNTANT"):
        return True
        
    owner_user = _get_owner_user(record)
    return owner_user == user
