from django.shortcuts import redirect , render
from django.urls import reverse, resolve, Resolver404
from django.http import HttpResponseNotFound
from django.core.exceptions import PermissionDenied

from core.views import technicians_list
from .models import AccessLevel
from doctor.models import Technician, Doctor
from patient.models import Patient


# core/middleware.py (یا هر app دیگری)
import hashlib
from datetime import datetime

class NoCacheMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        
        # فقط برای صفحات HTML (نه static files)
        if not request.path.startswith('/static/') and not request.path.startswith('/media/'):
            
            # 🔥 Header های قوی‌تر برای جلوگیری از کش
            response['Cache-Control'] = 'no-store, no-cache, must-revalidate, private, max-age=0'
            response['Pragma'] = 'no-cache'
            response['Expires'] = '0'
            
            # 🔥 ETag یونیک برای هر response
            content = getattr(response, 'content', b'')
            if content:
                etag = hashlib.md5(str(datetime.now().timestamp()).encode()).hexdigest()
                response['ETag'] = f'"{etag}"'
            
            # 🔥 Vary برای force revalidate
            response['Vary'] = 'Cookie, Accept-Encoding'
            
            # 🔥 جلوگیری از Back/Forward cache
            response['X-Accel-Expires'] = '0'
        
        return response
        
        
        
def get_profile_redirect(user):
    try:
        technician = Technician.objects.get(user=user)
        return f"/dashboard/profile/technician/{technician.id}/"
    except Technician.DoesNotExist:
        pass

    try:
        doctor = Doctor.objects.get(user=user)
        return f"/dashboard/profile/doctor/{doctor.id}/"
    except Doctor.DoesNotExist:
        pass

    try:
        patient = Patient.objects.get(user=user)
        return f"/dashboard/profile/patient/{patient.id}/"
    except Patient.DoesNotExist:
        pass

    return "/dashboard/"
# class LoginRequiredMiddleware:
#     print("in login_required middleware")
#     def __init__(self, get_response):
#         print("in init")
#         self.get_response = get_response
#         self.login_required_paths = ['/dashboard/', '/medical/', '/patients/', '/accountant/',
#                                      '/admin/', '/warehouse/', '/reservation/']
#         self.public_paths = ['/static/', '/media/', '/.well-known/']
#         self.login_path = reverse('userauth:login')
#         self.logout_path = reverse('userauth:logout')
#
#     def __call__(self, request):
#         print("in call")
#         path = request.path
#         print("path1=", path)
#
#
#         print(" self.login_path=",  self.login_path)
#
#         try:
#             resolve(path)
#         except Resolver404:
#             return self.handle_404(request)
#
#         print("path2=", path)
#
#         # Allow access to logout
#         if path == self.logout_path:
#             return self.get_response(request)
#
#         # Handle login page
#         if path == self.login_path:
#             if request.user.is_authenticated:
#                 return redirect(get_profile_redirect(request.user))
#             return self.get_response(request)
#
#         # Check protected paths
#         if any(path.startswith(p) for p in self.login_required_paths):
#             if not request.user.is_authenticated:
#                 return redirect(f"{self.login_path}?next={path}")
#
#         return self.get_response(request)
#
#     def handle_404(self, request):
#         return HttpResponseNotFound(render(request, '404.html'))

class LoginRequiredMiddleware:
    print("in login_required middleware")
    def __init__(self, get_response):
        print("in init")
        self.get_response = get_response
        self.login_required_paths = ['/dashboard/', '/medical/', '/patients/',
                                     '/accountant/',
                                     '/admin/', '/warehouse/', '/reservation/']
        self.public_paths = ['/static/', '/media/', '/.well-known/']
        self.login_path = reverse('userauth:login')
        self.logout_path = reverse('userauth:logout')

    def __call__(self, request):
        path = request.path

        try:
            resolve(path)
        except Resolver404:
            return self.handle_404(request)

        # Allow access to logout
        if path == self.logout_path:
            return self.get_response(request)

        # Handle login page
        if path == self.login_path:
            if request.user.is_authenticated:
                return redirect(get_profile_redirect(request.user))
            return self.get_response(request)

        # Check protected paths
        if any(path.startswith(p) for p in self.login_required_paths):
            if not request.user.is_authenticated:
                return redirect(f"{self.login_path}?next={path}")
            elif request.user.access_level not in ["Administrator","Supervisor","Accountant"]:
                if path == '/dashboard/':  # اگر کاربر احراز هویت شده و مسیر /dashboard/ است
                    return redirect(get_profile_redirect(request.user))  # هدایت به پروفایل

        return self.get_response(request)

    def handle_404(self, request):
        return HttpResponseNotFound(render(request, '404.html'))

class AccessControlMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # Define paths accessible by each access level
        self.access_paths = {
            AccessLevel.ADMINISTRATOR: ['/dashboard/', '/accountant/', '/medical/', '/patients/' ,  '/accounts/' , '/admin/' , '/warehouse/' , '/reservation/'],
            AccessLevel.SUPERVISOR: ['/dashboard/', '/patients/' , '/warehouse/' , '/reservation/'],
            # in patients just access to patients/history and for this implement another func in veiw  patients app.
            AccessLevel.ACCOUNTANT: ['/dashboard/', '/accountant/' , '/patients/'],
            AccessLevel.TECHNICIAN: ['/medical/technician/update/','/dashboard/profile/technician/','/dashboard/technician/report/','/dashboard/api/reservations/','/reservation/change-status/'],
            AccessLevel.DOCTOR: ['/medical/doctor/update/','/dashboard/profile/doctor/','/dashboard/doctor/report/','/dashboard/api/reservations/','/reservation/change-status/'],
        }
        self.logout_path = reverse('userauth:logout')

    def __call__(self, request):
        # Skip middleware for login/logout paths
        if request.path in [self.logout_path, reverse('userauth:login')]:
            return self.get_response(request)

        # Skip middleware for public paths
        if any(request.path.startswith(path) for path in ['/static/', '/media/']):
            return self.get_response(request)

        # Only apply restrictions to authenticated users with access levels
        if request.user.is_authenticated and hasattr(request.user, 'access_level'):
            user_level = request.user.access_level
            # Retrieve allowed paths for the user's access level
            allowed_paths = self.access_paths.get(user_level, [])


            # Redirect if the requested path is not in the allowed paths
            # if request.path not in allowed_paths:
            if not any(request.path.startswith(path) for path in allowed_paths):
                # use view in userauth name unauthorized_view and handler403 in base urls
                raise PermissionDenied()

        response = self.get_response(request)
        return response