from django.contrib import messages
from django.contrib.auth import logout
from django.shortcuts import redirect
from .tenant_context import set_current_db_alias, clear_current_db_alias
from .tenant_utils import register_alias

# Views that must stay reachable even when a company is paused/unprovisioned.
EXEMPT_PATHS = {"/login/", "/logout/", "/register/"}


class TenantMiddleware:
    """
    For every request:
      - If the user is a super admin, no tenant DB is needed.
      - If the user belongs to a company, point all inventory/sales/expenses
        queries at that company's own database for the duration of the request.
      - If the company has been paused or isn't provisioned yet, the user is
        logged out and sent back to the login page with an explanation.
    """

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        clear_current_db_alias()
        try:
            user = getattr(request, "user", None)
            if user is not None and user.is_authenticated and not getattr(user, "is_superadmin", False):
                company = getattr(user, "company", None)
                if company is not None and request.path not in EXEMPT_PATHS:
                    if not company.is_approved:
                        logout(request)
                        messages.error(request, "Your company's registration is still pending approval.")
                        return redirect("login")
                    if not company.is_active:
                        logout(request)
                        messages.error(request, "Your company's access has been paused by the administrator. Please contact support.")
                        return redirect("login")
                    if not company.is_provisioned:
                        logout(request)
                        messages.error(request, "Your company's workspace is still being set up. Please try again shortly.")
                        return redirect("login")
                    register_alias(company.db_alias)
                    set_current_db_alias(company.db_alias)
            response = self.get_response(request)
        finally:
            clear_current_db_alias()
        return response
