from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework import permissions, status
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth import authenticate

from .serializers import SignupSerializer, UserSerializer


class IsAdmin(permissions.BasePermission):
    def has_permission(self, request, view):
        print(f"--- IsAdmin Check (users) ---")
        print(f"User: {request.user}")
        print(f"Authenticated: {request.user.is_authenticated}")
        if request.user.is_authenticated:
            print(f"Role: {request.user.role}")
            print(f"Is Superuser: {request.user.is_superuser}")
        else:
            print(f"Auth Header: {request.headers.get('Authorization')}")
        result = request.user.is_authenticated and (request.user.role == "ADMIN" or request.user.is_superuser)
        print(f"Result: {result}")
        print(f"-----------------------------")
        return result

from django.contrib.auth import get_user_model

User = get_user_model()

class AdminUserListCreateView(GenericAPIView):
    # This view handles both creating owners and listing users for Admin
    serializer_class = SignupSerializer
    permission_classes = [permissions.IsAuthenticated, IsAdmin]

    def get(self, request):
        """
        Fetch users. Optionally filter by 'role' query param (e.g. ?role=HOTEL_OWNER).
        """
        role = request.query_params.get('role')
        if role:
            users = User.objects.filter(role=role)
        else:
            users = User.objects.all()
            
        # Use UserSerializer for listing (excludes password)
        return Response(UserSerializer(users, many=True).data)

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        return Response(UserSerializer(user).data, status=status.HTTP_201_CREATED)


# --------------------------------------------------
# Signup
# --------------------------------------------------

class SignupView(GenericAPIView):
    serializer_class = SignupSerializer
    permission_classes = [permissions.AllowAny]

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()

        from .models import create_user_session
        session = create_user_session(user, request)
        refresh = RefreshToken.for_user(user)
        refresh['session_key'] = str(session.session_key)
        refresh.access_token['session_key'] = str(session.session_key)

        return Response({
            "user": UserSerializer(user).data,
            "tokens": {
                "access": str(refresh.access_token),
                "refresh": str(refresh)
            }
        }, status=status.HTTP_201_CREATED)


# --------------------------------------------------
# Login
# --------------------------------------------------

class LoginView(GenericAPIView):
    permission_classes = [permissions.AllowAny]

    def post(self, request):
        username = request.data.get("username")
        password = request.data.get("password")

        user = authenticate(username=username, password=password)
        if not user:
            return Response(
                {"error": "Invalid credentials"},
                status=status.HTTP_400_BAD_REQUEST
            )

        from .models import create_user_session
        session = create_user_session(user, request)
        refresh = RefreshToken.for_user(user)
        refresh['session_key'] = str(session.session_key)
        refresh.access_token['session_key'] = str(session.session_key)

        return Response({
            "user": UserSerializer(user).data,
            "tokens": {
                "access": str(refresh.access_token),
                "refresh": str(refresh)
            }
        })


# --------------------------------------------------
# Profile (Authenticated)
# --------------------------------------------------

class ProfileView(GenericAPIView):
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        return Response(UserSerializer(request.user).data)


# --------------------------------------------------
# Delivery Partner Profile
# --------------------------------------------------

class DeliveryProfileView(GenericAPIView):
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        if request.user.role != "DELIVERY_PARTNER":
            return Response({"error": "Only delivery partners have a delivery profile"}, status=status.HTTP_400_BAD_REQUEST)
        
        from .models import DeliveryPartnerProfile
        from .serializers import DeliveryPartnerProfileSerializer
        profile, created = DeliveryPartnerProfile.objects.get_or_create(user=request.user)
        
        # We also want to return phone from User model
        data = DeliveryPartnerProfileSerializer(profile).data
        data['phone'] = request.user.phone
        return Response(data)

    def put(self, request):
        if request.user.role != "DELIVERY_PARTNER":
            return Response({"error": "Only delivery partners have a delivery profile"}, status=status.HTTP_400_BAD_REQUEST)

        from .models import DeliveryPartnerProfile
        from .serializers import DeliveryPartnerProfileSerializer
        profile, created = DeliveryPartnerProfile.objects.get_or_create(user=request.user)
        
        # Update phone if provided
        phone = request.data.get("phone")
        if phone is not None:
            request.user.phone = phone
            request.user.save()

        serializer = DeliveryPartnerProfileSerializer(profile, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        data = serializer.data
        data['phone'] = request.user.phone
        return Response(data)


# Session Management Views
# --------------------------------------------------

from rest_framework import generics
from .models import UserSession
from .serializers import UserSessionSerializer

class UserSessionListView(generics.ListAPIView):
    serializer_class = UserSessionSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        user = self.request.user
        if user.is_authenticated and (user.role == "ADMIN" or user.is_superuser):
            # Admins see all sessions
            queryset = UserSession.objects.all().order_by('-last_activity')
            # Optional query params to filter by user or active status
            user_id = self.request.query_params.get('user_id')
            if user_id:
                queryset = queryset.filter(user_id=user_id)
            is_active = self.request.query_params.get('is_active')
            if is_active is not None:
                is_active_val = is_active.lower() in ['true', '1']
                queryset = queryset.filter(is_active=is_active_val)
            return queryset
        else:
            # Regular users see only their own sessions
            return UserSession.objects.filter(user=user).order_by('-last_activity')

class UserSessionRevokeView(generics.GenericAPIView):
    permission_classes = [permissions.IsAuthenticated]

    def delete(self, request, session_key):
        try:
            session = UserSession.objects.get(session_key=session_key)
        except (UserSession.DoesNotExist, ValueError):
            return Response({"error": "Session not found"}, status=status.HTTP_404_NOT_FOUND)

        if session.user != request.user and not (request.user.role == "ADMIN" or request.user.is_superuser):
            return Response({"error": "You do not have permission to revoke this session"}, status=status.HTTP_403_FORBIDDEN)

        session.is_active = False
        session.save(update_fields=['is_active'])
        return Response({"message": "Session revoked successfully"}, status=status.HTTP_200_OK)

class UserSessionClearAllView(generics.GenericAPIView):
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        user = request.user
        target_user_id = request.data.get('user_id')
        
        # If admin wants to clear another user's sessions
        if target_user_id and (user.role == "ADMIN" or user.is_superuser):
            try:
                target_user = User.objects.get(id=target_user_id)
            except User.DoesNotExist:
                return Response({"error": "Target user not found"}, status=status.HTTP_404_NOT_FOUND)
            
            UserSession.objects.filter(user=target_user, is_active=True).update(is_active=False)
            return Response({"message": f"All sessions for user {target_user.username} have been revoked."}, status=status.HTTP_200_OK)
        
        # Otherwise, regular user clearing their own sessions (optionally keeping the current one)
        keep_current = request.data.get('keep_current', True)
        
        sessions = UserSession.objects.filter(user=user, is_active=True)
        if keep_current:
            token = request.auth
            current_session_key = token.get("session_key") if token else None
            if current_session_key:
                sessions = sessions.exclude(session_key=current_session_key)
                
        sessions.update(is_active=False)
        return Response({"message": "Sessions revoked successfully"}, status=status.HTTP_200_OK)


class SessionConfigurationView(generics.GenericAPIView):
    permission_classes = [permissions.IsAuthenticated, IsAdmin]

    def get(self, request):
        from .models import SessionConfiguration
        from .serializers import SessionConfigurationSerializer
        config = SessionConfiguration.get_settings()
        return Response(SessionConfigurationSerializer(config).data)

    def post(self, request):
        from .models import SessionConfiguration
        from .serializers import SessionConfigurationSerializer
        config = SessionConfiguration.get_settings()
        serializer = SessionConfigurationSerializer(config, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)
