from rest_framework import viewsets, permissions, status, generics
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.parsers import MultiPartParser, FormParser

from .models import User, Partner, PartnerAdmin
from .serializers import UserSerializer, PartnerSerializer, PartnerAdminSerializer
from .permissions import IsSuperUser, IsDeltaAdmin, IsPartnerAdmin
from rest_framework.permissions import AllowAny

from django.views.decorators.csrf import ensure_csrf_cookie
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.conf import settings

# Make sure these imports are present at the top of your file
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
from allauth.socialaccount.providers.oauth2.client import OAuth2Client
from dj_rest_auth.registration.views import SocialLoginView
from rest_framework.views import APIView
from allauth.account.models import EmailConfirmation, EmailConfirmationHMAC
from allauth.account.utils import send_email_confirmation
from django.contrib.auth import get_user_model
from rest_framework_simplejwt.tokens import RefreshToken
# Add these imports for Google token verification
from google.oauth2 import id_token
from google.auth.transport import requests

User = get_user_model()

class VerifyEmailView(APIView):
    permission_classes = [AllowAny]
    
    def post(self, request):
        print("VERIFICATIONNNNNNNNNNNNNNN")
        key = request.data.get('key')
        print("VERIFICATIONNNNNNNNNNNNNNN", key)
        if not key:
            return Response({'detail': 'Verification key is required.'}, status=status.HTTP_400_BAD_REQUEST)
        
        # Try to verify using HMAC
        confirmation = EmailConfirmationHMAC.from_key(key)
        if not confirmation:
            # Try to get the confirmation from the database
            try:
                confirmation = EmailConfirmation.objects.get(key=key)
            except EmailConfirmation.DoesNotExist:
                return Response({'detail': 'Invalid verification key or key has expired.'}, 
                               status=status.HTTP_400_BAD_REQUEST)
        
        # Confirm the email
        confirmation.confirm(request)
        print("CONFIIIIIIIIIIIIIIIIIRM")
        email_address = confirmation.email_address
        if email_address:
            email_address.verified = True
            email_address.save()

            user = email_address.user
            user.is_active = True
            user.save()
        
        return Response({'detail': 'Email successfully verified.'}, status=status.HTTP_200_OK)


class ResendVerificationEmailView(APIView):
    permission_classes = [AllowAny]
    
    def post(self, request):
        print("ResendVerificationEmailView called")  # Add this debug line
        print(f"Request data: {request.data}")  # Add this to see what data is being received
        
        email = request.data.get('email')
        if not email:
            print("Email is missing in request data")  # Debug missing email
            return Response({'detail': 'Email is required.'}, status=status.HTTP_400_BAD_REQUEST)
        
        User = get_user_model()
        try:
            user = User.objects.get(email=email)
            print(f"User found: {user.username}")  # Debug user found
            
            # Check if email is already verified
            from allauth.account.models import EmailAddress
            email_address = EmailAddress.objects.filter(user=user, email=email).first()
            
            if email_address and email_address.verified:
                print("Email is already verified")  # Debug already verified
                print(user)
                if user.is_active == False:
                    user.is_active =True
                    user.save()
                return Response({'detail': 'Email is already verified.'}, status=status.HTTP_400_BAD_REQUEST)
                
            # Send verification email
            print("Sending verification email")  # Debug before sending
            send_email_confirmation(request, user, signup=False)
            print("Verification email sent")  # Debug after sending
            return Response({'detail': 'Verification email has been sent.'}, status=status.HTTP_200_OK)
            
        except User.DoesNotExist:
            print(f"User with email {email} not found")  # Debug user not found
            # For security reasons, don't reveal that the user doesn't exist
            return Response({'detail': 'Verification email has been sent if the email exists in our system.'}, 
                           status=status.HTTP_200_OK)

# Update the UserRegistrationView to properly handle the response
class UserRegistrationView(generics.CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [permissions.AllowAny]
    
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = self.perform_create(serializer)
        
        return Response({
            "detail": "Verification email has been sent to your email address. Please check your inbox."
        }, status=status.HTTP_201_CREATED)
    
    def perform_create(self, serializer):
        user = serializer.save()
        # By default, new users are visitors
        user.role = User.VISITOR
        user.is_active = False  # User is inactive until email is verified
        user.save()
        
        # Send verification email
        from allauth.account.models import EmailAddress
        from allauth.account.utils import send_email_confirmation
        
        # Create EmailAddress record
        email_address, created = EmailAddress.objects.get_or_create(
            user=user,
            email=user.email,
            defaults={'verified': False, 'primary': True}
        )
        
        # Send confirmation email
        send_email_confirmation(self.request, user, signup=True)
        
        return user

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    
    def get_permissions(self):
        if self.action == 'create':
            return [permissions.AllowAny()]
        elif self.action in ['update', 'partial_update', 'destroy', 'me', 'profile', 'update_profile']:
            return [permissions.IsAuthenticated()]
        else:
            print("action else")
            return [IsSuperUser()]
    
    @action(detail=False, methods=['get'])
    def me(self, request):
        """
        Returns the current authenticated user
        """
        serializer = self.get_serializer(request.user)
        return Response(serializer.data)
    
    @action(detail=False, methods=['get'])
    def profile(self, request):
        """
        Get the profile of the currently authenticated user
        """
        user = request.user
        serializer = self.get_serializer(user)
        return Response(serializer.data)
    
    @action(detail=False, methods=['patch'], parser_classes=[MultiPartParser, FormParser])
    def update_profile(self, request):
        """
        Update the profile of the currently authenticated user
        """
        user = request.user
        serializer = self.get_serializer(user, data=request.data, partial=True)
        
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def get_queryset(self):
        user = self.request.user
        if user.is_superuser:
            return User.objects.all()
        elif user.is_delta_admin():
            # Delta admins can see partner admins they manage
            partner_ids = user.managed_partners.values_list('id', flat=True)
            partner_admin_user_ids = PartnerAdmin.objects.filter(
                partner_id__in=partner_ids
            ).values_list('user_id', flat=True)
            return User.objects.filter(id__in=partner_admin_user_ids)
        return User.objects.filter(id=user.id)  # Users can only see themselves

class PartnerViewSet(viewsets.ModelViewSet):
    queryset = Partner.objects.all()
    serializer_class = PartnerSerializer
    
    def get_permissions(self):
        print("partner permission")
        if self.action in ['list']:
            return [AllowAny()]  # Return an instance of AllowAny, not the class itself
        if self.action in ['retrieve']:
            return [permissions.IsAuthenticated()]
        else:
            return [IsSuperUser() | IsDeltaAdmin()]
    
    def get_queryset(self):
        user = self.request.user
        
        # For anonymous users or list action, return all partners
        if self.action == 'list' and not user.is_authenticated:
            return Partner.objects.all()
            
        # For authenticated users
        if user.is_superuser:
            return Partner.objects.all()
        elif hasattr(user, 'is_delta_admin') and user.is_delta_admin():
            return user.managed_partners.all()
        elif hasattr(user, 'is_partner_admin') and user.is_partner_admin():
            return Partner.objects.filter(id=user.partner_profile.partner_id)
        
        # Default case for authenticated users without special permissions
        return Partner.objects.all()
        return Partner.objects.none()

class PartnerAdminViewSet(viewsets.ModelViewSet):
    queryset = PartnerAdmin.objects.all()
    serializer_class = PartnerAdminSerializer
    
    def get_permissions(self):
        return [IsSuperUser() | IsDeltaAdmin()]
    
    def get_queryset(self):
        user = self.request.user
        if user.is_superuser:
            return PartnerAdmin.objects.all()
        elif user.is_delta_admin():
            partner_ids = user.managed_partners.values_list('id', flat=True)
            return PartnerAdmin.objects.filter(partner_id__in=partner_ids)
        return PartnerAdmin.objects.none()




@ensure_csrf_cookie
def csrf_token_view(request):
    return JsonResponse({"csrfToken": request.META.get("CSRF_COOKIE", "")})


from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

# Add this decorator to your Google auth view class
# Keep only this GoogleLoginView and remove the first one
@method_decorator(csrf_exempt, name='dispatch')
class GoogleLoginView(SocialLoginView):
    adapter_class = GoogleOAuth2Adapter  # Uncomment this line
    callback_url = "http://localhost:3000"
    client_class = OAuth2Client
    
    def post(self, request, *args, **kwargs):
        try:
            # Log the request for debugging
            print("Google login request received")
            print(f"Request data: {request.data}")
            
            # Check if credential is in the request data (from Google Sign-In button)
            if 'credential' in request.data and 'access_token' not in request.data:
                # Create a new dictionary with both credential as access_token
                modified_data = dict(request.data)
                modified_data['access_token'] = request.data['credential']
                
                # Create a new request with the modified data
                request._full_data = modified_data
                print("access token: ", modified_data)
            # Check if id_token is in the request data (from older implementation)
            elif 'id_token' in request.data and 'access_token' not in request.data:
                # Create a new dictionary with both id_token and access_token
                modified_data = dict(request.data)
                modified_data['access_token'] = request.data['id_token']
                
                # Create a new request with the modified data
                request._full_data = modified_data
                print("access token: ", modified_data)
                
            return super().post(request, *args, **kwargs)
        except Exception as e:
            print(f"Google login error: {str(e)}")
            return Response(
                {"detail": f"Authentication failed: {str(e)}"},
                status=status.HTTP_400_BAD_REQUEST
            )
