"""Self-contained access gates for the job board.

Formerly the job board leaned on ``apps.rep.courses.mixins.RepManageMixin`` and
``rep_perms`` (LMS permissions). After the REP LMS was retired in favour of
Moodle, careers owns its own gate: secretariat / grants / learning-admin staff
roles, plus holders of the ``rep_career.post_job_listing`` permission. The
permission codename keeps its ``rep_career`` app_label (the app label is
preserved on the move), so existing grants keep working.
"""
from __future__ import annotations

from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied

from apps.core.permissions.pending_review import (
    WRITE_METHODS as _PENDING_WRITE_METHODS,
    _is_pending as _is_pending_review,
    _redirect_with_flash as _pending_redirect,
)
from apps.core.permissions.roles import UserRole

# Roles that may manage the job board / career resources.
CAREER_STAFF_ROLE_VALUES = frozenset(
    {
        UserRole.ADMIN.value,
        UserRole.GRANTS_MANAGER.value,
        UserRole.REP_LEARNING_ADMIN.value,
    }
)

# Explicit Django permission for posting job listings (partners/employers).
POST_JOB_LISTING_PERM = "rep_career.post_job_listing"


class CareerManageMixin(LoginRequiredMixin):
    """Career staff: secretariat, grants managers, learning admins, superusers,
    or holders of the ``rep_career.post_job_listing`` permission.

    Blocks write-method requests for users with ``pending_admin_review=True``.
    """

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return self.handle_no_permission()
        if (
            request.method in _PENDING_WRITE_METHODS
            and _is_pending_review(request.user)
        ):
            return _pending_redirect(request)
        u = request.user
        if u.is_superuser:
            return super().dispatch(request, *args, **kwargs)
        role = getattr(u, "role", "") or ""
        if role in CAREER_STAFF_ROLE_VALUES:
            return super().dispatch(request, *args, **kwargs)
        if u.has_perm(POST_JOB_LISTING_PERM):
            return super().dispatch(request, *args, **kwargs)
        raise PermissionDenied
