from django.core.exceptions import ObjectDoesNotExist


def _staff_profile(user):
    try:
        return user.staff_profile
    except ObjectDoesNotExist:
        return None


ROLE_CLIENT = 'client'
ROLE_EMPLOYEE = 'employee'
ROLE_MANAGER = 'manager'
ROLE_CEO = 'ceo'

MODULE_CLIENT_PORTAL = 'client_portal'
MODULE_TASK = 'task_management'

ACTION_VIEW = 'view'
ACTION_CREATE = 'create'
ACTION_EDIT = 'edit'
ACTION_APPROVE = 'approve'
ACTION_ADMIN = 'admin'

MODULE_ACCESS = {
    ROLE_CLIENT: {MODULE_CLIENT_PORTAL},
    ROLE_EMPLOYEE: {MODULE_TASK},
    ROLE_MANAGER: {MODULE_TASK},
    ROLE_CEO: {MODULE_CLIENT_PORTAL, MODULE_TASK},
}

ACTION_ACCESS = {
    ROLE_CLIENT: {
        MODULE_CLIENT_PORTAL: {ACTION_VIEW, ACTION_EDIT},
    },
    ROLE_EMPLOYEE: {
        MODULE_TASK: {ACTION_VIEW, ACTION_EDIT},
    },
    ROLE_MANAGER: {
        MODULE_TASK: {ACTION_VIEW, ACTION_APPROVE, ACTION_ADMIN},
    },
    ROLE_CEO: {
        MODULE_CLIENT_PORTAL: {ACTION_VIEW, ACTION_CREATE, ACTION_EDIT, ACTION_APPROVE, ACTION_ADMIN},
        MODULE_TASK: {ACTION_VIEW, ACTION_CREATE, ACTION_EDIT, ACTION_APPROVE, ACTION_ADMIN},
    },
}


def _legacy_role_from_name(user):
    profile = _staff_profile(user)
    role_name = (getattr(getattr(profile, 'role', None), 'name', '') or '').strip().lower()
    if 'ceo' in role_name or 'coo' in role_name:
        return ROLE_CEO
    if 'manager' in role_name:
        return ROLE_MANAGER
    if profile:
        return ROLE_EMPLOYEE
    return None


def get_user_role(user):
    if not getattr(user, 'is_authenticated', False):
        return None

    if getattr(user, 'is_superuser', False):
        return ROLE_CEO

    if hasattr(user, 'client_profile'):
        return ROLE_CLIENT

    profile = _staff_profile(user)
    if profile and getattr(profile, 'is_active', False):
        return _legacy_role_from_name(user)
    return None


def can_access_module(user, module_name):
    if getattr(user, 'is_superuser', False):
        return True

    if module_name == MODULE_CLIENT_PORTAL and hasattr(user, 'client_profile'):
        return True

    if module_name == MODULE_TASK:
        profile = _staff_profile(user)
        return bool(profile and getattr(profile, 'is_active', False))

    return False


def can_do_action(user, module_name, action):
    role = get_user_role(user)
    if not role:
        return False
    if not can_access_module(user, module_name):
        return False
    return action in ACTION_ACCESS.get(role, {}).get(module_name, set())


def is_executive(user):
    return get_user_role(user) == ROLE_CEO


def is_manager(user):
    return get_user_role(user) == ROLE_MANAGER


def is_employee(user):
    return get_user_role(user) == ROLE_EMPLOYEE


def get_default_dashboard_url(user):
    role = get_user_role(user)
    if role == ROLE_CLIENT:
        return 'client_portal:dashboard'
    if role in {ROLE_EMPLOYEE, ROLE_MANAGER, ROLE_CEO}:
        return 'task_management:my_profile'
    return 'client_portal:login'


def get_role_profile_url(user):
    role = get_user_role(user)
    if role in {ROLE_EMPLOYEE, ROLE_MANAGER, ROLE_CEO}:
        return 'task_management:my_profile'
    if role == ROLE_CLIENT:
        return 'client_portal:dashboard'
    return get_default_dashboard_url(user)
