from functools import wraps

from django.contrib import messages
from django.db.models import QuerySet

from .models import Project, ProjectMembership


def get_allowed_projects(user) -> QuerySet:
    """Return only active companies the user is allowed to access."""
    if not user.is_authenticated:
        return Project.objects.none()
    if user.is_superuser:
        return Project.objects.filter(is_active=True)
    return Project.objects.filter(
        memberships__user=user,
        memberships__is_active=True,
        is_active=True,
    ).distinct()


def get_current_project(request):
    allowed = get_allowed_projects(request.user)
    if not allowed.exists():
        request.session.pop("active_project_id", None)
        return None

    project_id = request.session.get("active_project_id")
    project = None
    if project_id:
        try:
            project = allowed.filter(id=project_id).first()
        except (ValueError, TypeError):
            project = None

    if project is None:
        project = allowed.order_by("created_at").first()
        if project:
            request.session["active_project_id"] = str(project.id)
            request.session.modified = True
    return project


def set_current_project(request, project):
    if not get_allowed_projects(request.user).filter(pk=project.pk).exists():
        return False
    request.session["active_project_id"] = str(project.pk)
    request.session.modified = True
    return True


def get_membership(user, project):
    if not user.is_authenticated or project is None or user.is_superuser:
        return None
    return ProjectMembership.objects.filter(
        user=user, project=project, is_active=True
    ).first()


def require_active_project(view_func):
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        project = get_current_project(request)
        if project is None:
            messages.warning(
                request,
                "No active company is available for this account. "
                "The Application Owner must approve your company first."
            )
            return __import__("django.shortcuts", fromlist=["redirect"]).redirect("dashboard:home")
        return view_func(request, *args, **kwargs)
    return wrapper
