from functools import wraps

from django.contrib.auth.decorators import login_required, user_passes_test
from django.core.exceptions import PermissionDenied


def get_user_profile(user):
    if not user.is_authenticated:
        return None
    from .models import UserProfile

    return UserProfile.objects.filter(user_id=user.pk).first()


def is_financial_admin(user):
    return user.is_active and user.is_superuser


def is_employee_user(user):
    profile = get_user_profile(user)
    return bool(profile and profile.is_employee())


def is_client_user(user):
    profile = get_user_profile(user)
    return bool(profile and profile.is_client())


def has_financial_access(user):
    return is_financial_admin(user) or is_employee_user(user) or is_client_user(user)


def can_write_financials(user):
    return is_financial_admin(user) or is_employee_user(user)


def get_employees():
    from .models import Employee, UserProfile

    return Employee.objects.filter(
        user__profile__user_type=UserProfile.UserType.EMPLOYEE
    )


def get_user_employee(user):
    from .models import Employee

    if not is_employee_user(user):
        return None
    return Employee.objects.filter(user=user).first()


def financial_admin_required(view_func):
    return user_passes_test(is_financial_admin)(view_func)


def financial_access_required(view_func):
    @login_required
    @wraps(view_func)
    def _wrapped(request, *args, **kwargs):
        if has_financial_access(request.user):
            return view_func(request, *args, **kwargs)
        raise PermissionDenied

    return _wrapped


def financial_write_required(view_func):
    @login_required
    @wraps(view_func)
    def _wrapped(request, *args, **kwargs):
        if can_write_financials(request.user):
            return view_func(request, *args, **kwargs)
        raise PermissionDenied

    return _wrapped
