import json
from django.forms import model_to_dict
from django.http import JsonResponse
import requests
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.http import JsonResponse
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView, TokenVerifyView

from .models import Agent,Message, Invitation, Organization, UserProfile,UserAccount

from .serializers import MessageSerializer, UserAccountSerializer, UserPhoneUpdateSerializer, UserProfilePictureSerializer, UserProfileSerializer, OrganizationSerializer, InvitationSerializer, AgentSerializer
import re

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny, IsAuthenticated

from django.shortcuts import get_object_or_404

from django.core.serializers import serialize

from rest_framework.parsers import MultiPartParser, FormParser

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.response import Response
from rest_framework import status

from .models import Wallet, Subscription, SubscriptionPackage
from .serializers import WalletSerializer, SubscriptionPackageSerializer, SubscriptionSerializer

from django.shortcuts import get_object_or_404

import stripe
from django.conf import settings
from .models import Wallet, WalletTransaction, StripeRecharge
from .serializers import StripeRechargeSerializer

stripe.api_key = settings.STRIPE_SECRET_KEY

import paypalrestsdk
from django.conf import settings
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from django.shortcuts import get_object_or_404

from .models import Wallet, WalletTransaction, PayPalRecharge

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
import paypalrestsdk
from django.conf import settings
from django.utils import timezone
from datetime import timedelta
from decimal import Decimal, ROUND_HALF_UP

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
import paypalrestsdk
from django.conf import settings
from django.utils import timezone
from datetime import timedelta

from .models import UserVerification

from rest_framework.decorators import api_view, permission_classes, parser_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.response import Response
from rest_framework import status
from django.shortcuts import get_object_or_404
from .models import UserVerification, IdentityDocumentType

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from .models import Coupon, CouponUsage, SubscriptionPackage, Subscription
from django.utils import timezone
from decimal import Decimal

from rest_framework.decorators import api_view, permission_classes, parser_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.response import Response
from rest_framework import status
from django.utils import timezone
from .models import (
    UserVerification, IdentityDocumentType, VerificationFee,
    VerificationDiscount, SubscriptionPackage, Subscription
)
from django.conf import settings
from decimal import Decimal
import paypalrestsdk

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from .models import SubscriptionPackage
from .serializers import SubscriptionPackageSerializer

from .serializers import CustomTokenObtainPairSerializer

class JWTCREATE(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer
    def post(self, request, *args, **kwargs):
        # Normalize and lowercase email if present in request data
        if 'email' in request.data:
            request.data['email'] = request.data['email'].lower()
        response = super().post(request, *args, **kwargs)
        if response.status_code == 200:
            if 'access' in response.data:
                response.set_cookie(
                    'access',
                    response.data['access'],
                    max_age=60 * 60 * 24,  # 1 day
                    httponly=True,
                    samesite='Lax',
                    secure=False  # Set to True in production with HTTPS
                )
            if 'refresh' in response.data:
                response.set_cookie(
                    'refresh',
                    response.data['refresh'],
                    max_age=60 * 60 * 24 * 30,  # 30 days
                    httponly=True,
                    samesite='Lax',
                    secure=False  # Set to True in production with HTTPS
                )
        return response

class JWTREFRESH(TokenRefreshView):
    def post(self, request, *args, **kwargs):
        # Try to get refresh token from cookies first
        refresh_token = request.COOKIES.get('refresh')
        
        # If not in cookies, check the request body
        if not refresh_token and 'refresh' in request.data:
            refresh_token = request.data['refresh']
            
        # If refresh token found, use it
        if refresh_token:
            request.data['refresh'] = refresh_token
        
        # Call the parent method to handle token refresh
        response = super().post(request, *args, **kwargs)
        
        # If successful, update cookies with the new tokens
        if response.status_code == 200 and 'access' in response.data:
            # Set cookies for the new tokens (optional, depending on your frontend setup)
            response.set_cookie(
                'access',
                response.data['access'],
                max_age=60 * 60 * 24,  # 1 day
                httponly=True,
                samesite='Lax',
                secure=False  # Set to True in production with HTTPS
            )
            
            # If refresh token was rotated and included in the response
            if 'refresh' in response.data:
                response.set_cookie(
                    'refresh',
                    response.data['refresh'],
                    max_age=60 * 60 * 24 * 30,  # 30 days
                    httponly=True,
                    samesite='Lax',
                    secure=False  # Set to True in production with HTTPS
                )
        
        return response

class JWTVERIFY(TokenVerifyView):
    def post(self, request, *args, **kwargs):
        response = super().post(request, *args, **kwargs)
        return response

class JWTLOGOUT(APIView):
    def post(self, request, *args, **kwargs):
        response = Response(status=status.HTTP_204_NO_CONTENT)
        response.delete_cookie('access')
        response.delete_cookie('refresh')

        return response
    
class ChangePasswordView(APIView):
    def post(self, request):
        old_password = request.data.get('old_password')
        new_password = request.data.get('new_password')
        re_new_password = request.data.get('re_new_password')

        if len(new_password) < 8:
            return Response({'detail': 'New password must be at least 8 characters long.'}, status=status.HTTP_400_BAD_REQUEST)

        if new_password != re_new_password:
            return Response({'detail': 'New password and confirmation do not match.'}, status=status.HTTP_400_BAD_REQUEST)

        if not request.user.check_password(old_password):
            return Response({'detail': 'Incorrect old password.'}, status=status.HTTP_400_BAD_REQUEST)

        request.user.set_password(new_password)
        request.user.save()

        return Response({'detail': 'Password successfully changed.'}, status=status.HTTP_200_OK)

class GetUserFullName(APIView):
    def get(self, request):
        user = request.user
        full_name = user.full_name
        return Response({'full_name': full_name}, status=status.HTTP_200_OK)

class GetUserMe(APIView):
    def get(self, request):
        user = request.user
        
        # Include profile_picture in response if it exists
        response_data = {
            'id': user.id,
            'full_name': user.full_name,
            'email': user.email,
            'role': user.role  # Add role to response
        }
        
        # Add profile picture URL if it exists
        if user.profile_picture:
            # Get the full URL including domain
            request_protocol = 'https' if request.is_secure() else 'http'
            domain = request.get_host()
            profile_picture_url = f"{request_protocol}://{domain}{user.profile_picture.url}"
            response_data['profile_picture'] = profile_picture_url
        
        return Response(response_data, status=status.HTTP_200_OK)

class UpdateFullName(APIView):
    def post(self, request):
        try:
            user = request.user
            new_full_name = request.data.get('new_full_name')

            if new_full_name:
                # Check if the full name contains only letters and spaces
                if re.match("^[a-zA-Z\s]+$", new_full_name):
                    # Remove leading and trailing spaces from the full name
                    new_full_name = new_full_name.strip()
                    
                    user.full_name = new_full_name
                    user.save()
                    return Response({'message': 'Full name updated successfully'}, status=status.HTTP_200_OK)
                else:
                    return Response({'error': 'Full name contains numbers or special characters'}, status=status.HTTP_400_BAD_REQUEST)
            else:
                return Response({'error': 'New full name is required'}, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        


class GetUserFullName(APIView):
    def get(self, request):
        user = request.user
        full_name = user.full_name
        return Response({'full_name': full_name}, status=status.HTTP_200_OK)

class ChangePhoneNumberView(APIView):
    def post(self, request, *args, **kwargs):
        serializer = UserPhoneUpdateSerializer(data=request.data)
        if serializer.is_valid():
            new_phone = serializer.validated_data['phone']

            user = self.request.user

            user.phone = new_phone
            user.save()

            return Response({"message": "Phone number updated successfully"}, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class UserProfileDetailView(APIView):
    def get(self, request):
        user = request.user
        profile, created = UserProfile.objects.get_or_create(user=user)

        # Add profile picture URL if it exists
        profile_picture_url = None
        if user.profile_picture:
            request_protocol = 'https' if request.is_secure() else 'http'
            domain = request.get_host()
            profile_picture_url = f"{request_protocol}://{domain}{user.profile_picture.url}"

        return Response({
            "full_name": user.full_name,
            "phone": user.phone,
            "email": user.email,
            "profile_picture": profile_picture_url,
            "skype_link": profile.skype_link,
            "facebook_link": profile.facebook_link,
            "linkedin_link": profile.linkedin_link,
            "title": profile.title,
            "website": profile.website,
            "twitter": profile.twitter,
            "pinterest": profile.pinterest,
            "description": profile.description,
        },status=status.HTTP_200_OK)
    
class UserProfileCreateUpdateView(APIView):
    def post(self, request):
        data = request.data
        try:
            profile = UserProfile.objects.get(user=request.user)
        except UserProfile.DoesNotExist:
            return Response({"error": "User profile not found."}, status=status.HTTP_404_NOT_FOUND)
        # Validate required fields
        full_name = data.get("full_name", "").strip()
        email = data.get("email", "").strip()
        phone = data.get("phone", "").strip()
        if not full_name or not email or not phone:
            return Response({"error": "Full name, email, and phone cannot be empty."}, status=status.HTTP_400_BAD_REQUEST)
        # Update UserAccount fields
        user = request.user
        user.full_name = full_name
        user.email = email
        user.phone = phone
        user.save()
        # Update UserProfile fields
        profile.skype_link = data.get("skype_link", profile.skype_link)
        profile.facebook_link = data.get("facebook_link", profile.facebook_link)
        profile.linkedin_link = data.get("linkedin_link", profile.linkedin_link)
        profile.title = data.get("title", profile.title)
        profile.website = data.get("website", profile.website)
        profile.twitter = data.get("twitter", profile.twitter)
        profile.pinterest = data.get("pinterest", profile.pinterest)
        profile.description = data.get("description", profile.description)
        profile.save()
        return Response({"message": "User profile created/updated successfully"}, status=status.HTTP_201_CREATED)

@api_view(['GET'])
@permission_classes([AllowAny])
def autocomplete_agent_emails(request):
    if request.GET.get('q'):
        query = request.GET['q'].lower()  # Normalize to lowercase
        agents = Agent.objects.filter(user__email__icontains=query)
        alist = []
        for agent in agents:
            alist.append({
                "name": agent.user.full_name,
                "email": agent.user.email,
            })
        return JsonResponse(alist, safe=False)
    return JsonResponse([], safe=False)

class AddAgentToOrganizationView(APIView):
    def post(self, request):
        email = request.data.get('email', '').lower()  # Normalize to lowercase
        try:
            auser = Agent.objects.get(user__email=email)
            organization = Organization.objects.get(user=request.user)
            
            # Check if there's an existing invitation for the same organization and email
            invitation = Invitation.objects.filter(organization=organization, agent=auser, is_accepted=False, is_rejected=False).first()
            if invitation:
                return Response({'message': f'An invitation to {auser.user.email} already exists'}, status=status.HTTP_400_BAD_REQUEST)
            
            if not auser in organization.agents.all():
                # Create a new invitation
                invitation = Invitation(organization=organization, agent=auser)
                invitation.save()
                return Response({'message': f'Invitation sent to {auser.user.email}'}, status=status.HTTP_201_CREATED)
            else:
                return Response({'message': f'{auser.user.email} is already associated with an organization'}, status=status.HTTP_400_BAD_REQUEST)
        except Agent.DoesNotExist:
            return Response({'message': f'User with email {email} does not exist'}, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def list_invitations(request):
    try:
        that_agent = Agent.objects.get(user=request.user)
        invitations = Invitation.objects.filter(agent=that_agent, is_rejected=False, is_accepted=False)
    except Agent.DoesNotExist:
        return Response({"error": "Agent does not exist"}, status=status.HTTP_404_NOT_FOUND)
    serializer = InvitationSerializer(invitations, many=True, context={'request': request})
    return Response(serializer.data)

class AcceptInvitationView(APIView):
    def post(self, request, invitation_id):
        try:
            agent = Agent.objects.get(user=request.user)
            invitation = Invitation.objects.get(agent=agent,id=invitation_id, is_accepted=False, is_rejected=False)
        except Invitation.DoesNotExist:
            return JsonResponse({"error": "Invitation does not exist or has already been accepted/rejected"}, status=status.HTTP_404_NOT_FOUND)

        # Perform the action to accept the invitation (e.g., set is_accepted to True).
        invitation.is_accepted = True
        invitation.save()

        organization = Organization.objects.get(user=invitation.organization.user)
        organization.agents.add(invitation.agent)

        organization.save()

        return JsonResponse({"message": "Invitation accepted"}, status=status.HTTP_200_OK)

class RejectInvitationView(APIView):
    def post(self, request, invitation_id):
        try:
            invitation = Invitation.objects.get(id=invitation_id, is_accepted=False, is_rejected=False)
        except Invitation.DoesNotExist:
            return JsonResponse({"error": "Invitation does not exist or has already been accepted/rejected"}, status=status.HTTP_404_NOT_FOUND)

        # Perform the action to reject the invitation (e.g., set is_rejected to True).
        invitation.is_rejected = True
        invitation.save()

        try:
            organization = Organization.objects.get(user=invitation.organization.user)
            organization.agents.remove(invitation.agent)
            organization.save()
        except:
            return JsonResponse({"message": "Invitation rejected."}, status=status.HTTP_200_OK)

        return JsonResponse({"message": "Invitation rejected"}, status=status.HTTP_200_OK)
    
@api_view(['GET'])
@permission_classes([AllowAny])
def all_agent_list(request):
    agents = Agent.objects.all()
    agent_list = []
    for agent in agents:
        user = agent.user
        profile = UserProfile.objects.filter(user=user).first()
        agent_list.append({
            "id": agent.id,
            "name": user.full_name if user else "",
            "email": user.email if user else "",
            "phone": user.phone if user else "",
            "image": user.profile_picture.url if user and user.profile_picture else "/agents/1.png",
            "width": 100,
            "height": 100,
        })
    return Response(agent_list)

class RemoveAgentFromOrganization(APIView):
    def post(self, request, id):
        try:
            organization = get_object_or_404(Organization, user__id=request.user.id)
            agent = get_object_or_404(Agent, user__id=id)

            organization.agents.remove(agent)
            organization.save()

            return Response({"data":"Agent removed from the organization."})
        except:
            return Response({"data":"Something went wrong!"})

class MessagesListView(APIView):
    def get(self, request):
        user = UserAccount.objects.get(pk=request.user.pk)  # get your primary key
        messages = Message.get_message_list(user) # get all messages between you and the other user

        other_users = [] # list of other users

        # getting the other person's name fromthe message list and adding them to a list
        for i in range(len(messages)):
            if messages[i].sender != user:
                other_users.append(messages[i].sender)
            else:
                other_users.append(messages[i].recipient)
                
        mserializer = MessageSerializer(messages, many=True)
        userializer = UserAccountSerializer(other_users,many=True)
        context= {}
        context['messages_list'] = mserializer.data
        context['other_users'] = userializer.data
        context['you'] = user.email
        return Response(context)

# class UserListsView(APIView):
#     def get(self, request, *args, **kwargs):
#         user = get_object_or_404(UserAccount, pk=request.user.pk)
#         users = UserAccount.objects.exclude(pk=user.pk)

#         user_data = []  # List to store user data
#         for u in users:
#             user_data.append({
#                 'id': u.id,
#                 'email': u.email,
#                 'full_name':u.full_name
#                 # Add other fields as needed
#             })

#         return Response({'users': user_data}, status=status.HTTP_200_OK)
    
class UserListsView(APIView):
    def get(self, request, *args, **kwargs):
        # Get the currently logged-in user
        current_user = get_object_or_404(UserAccount, pk=request.user.pk)

        # Get a list of users who have exchanged messages with the current user
        users_with_messages = Message.get_users_with_messages(current_user)

        # Prepare the response data
        user_data = []
        for u in users_with_messages:
            # Add profile picture URL if it exists
            profile_picture_url = None
            if u.profile_picture:
                request_protocol = 'https' if request.is_secure() else 'http'
                domain = request.get_host()
                profile_picture_url = f"{request_protocol}://{domain}{u.profile_picture.url}"
            user_data.append({
                'id': u.id,
                'email': u.email,
                'full_name': u.full_name,
                'profile_picture': profile_picture_url,
                # Add other fields as needed
            })

        return Response({'users': user_data}, status=status.HTTP_200_OK)    
    
class InboxView(APIView):
    def get(self, request, id, *args, **kwargs):
        user = get_object_or_404(UserAccount, id=id)
        current_user = get_object_or_404(UserAccount, pk=request.user.pk)
        messages = Message.get_all_messages(current_user, user)

        message_data = []

        for message in messages:
            message_data.append({
                "id":message.id,
                'sender_id': message.sender.id,
                'recipient_id': message.recipient.id,
                'sender': message.sender.full_name,
                'recipient':message.recipient.full_name,
                'message': message.message,
                'timestamp': message.date.strftime('%Y-%m-%d %H:%M:%S'),
                # Add other message-related fields as needed
            })

        return Response({'messages': message_data}, status=status.HTTP_200_OK)

    def post(self, request, id, *args, **kwargs):
        current_user = get_object_or_404(UserAccount, pk=request.user.pk)
        recipient = get_object_or_404(UserAccount, id=id)
        message_text = request.data.get('message')

        if not request.user.is_authenticated:
            return Response({'error': 'User not authenticated'}, status=status.HTTP_401_UNAUTHORIZED)

        if message_text and request.method == 'POST':
            message = Message.objects.create(sender=current_user, recipient=recipient, message=message_text)
            message_data = {
                'sender_id': message.sender.id,
                'recipient_id': message.recipient.id,
                'sender': message.sender.full_name,
                'recipient':message.recipient.full_name,
                'message': message.message,
                'timestamp': message.date.strftime('%Y-%m-%d %H:%M:%S'),
                # 'timestamp': message.timestamp.strftime('%Y-%m-%d %H:%M:%S'),
                # Add other message-related fields as needed
            }
            return Response({'message': message_data}, status=status.HTTP_201_CREATED)
        else:
            return Response({'error': 'Invalid message data'}, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET'])
@permission_classes([AllowAny]) # Any user can view (FOR PUBLIC URLS)
def getAgentProfile(request,id, *args, **kwargs):
    try:
        Agent.objects.get(user__id=id)
        profile = UserProfile.objects.get(user__id=id)
        # Serialize the UserProfile instance to JSON
        serialized_data = serialize('json', [profile, ])

        # Convert serialized data to Python dictionary
        deserialized_data = json.loads(serialized_data)

        # Extract the fields you need or return the entire data
        user_profile_data = deserialized_data[0]['fields']
        user_profile_data['user']=id

        # Return the serialized data in JSON format
        return JsonResponse(user_profile_data)
    except Exception as error:
        return Response({"error":"Invalid ID/Something wrong happend!"})

@api_view(['GET'])
@permission_classes([AllowAny]) # Any user can view (FOR PUBLIC URLS)
def getOrganizationProfile(request,id, *args, **kwargs):
    try:
        Organization.objects.get(user__id=id)
        profile = UserProfile.objects.get(user__id=id)
        # Serialize the UserProfile instance to JSON
        serialized_data = serialize('json', [profile, ])

        # Convert serialized data to Python dictionary
        deserialized_data = json.loads(serialized_data)

        # Extract the fields you need or return the entire data
        user_profile_data = deserialized_data[0]['fields']
        user_profile_data['user']=id

        # Return the serialized data in JSON format
        return JsonResponse(user_profile_data)
    except Exception as error:
        return Response({"error":"Invalid ID/Something wrong happend!"})

class UserProfilePictureUpdateView(APIView):
    parser_classes = (MultiPartParser, FormParser,)

    def post(self, request, *args, **kwargs):
        user = self.request.user  # Assuming you are using token-based authentication
        serializer = UserProfilePictureSerializer(user, data=request.data)

        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET'])
@permission_classes([AllowAny]) # Any user can view (FOR PUBLIC URLS)
def agentDetails(request, id):

    userAc = UserAccount.objects.get(id=id)
    profile = UserProfile.objects.get(user=userAc)

    serializer  = UserProfileSerializer(profile)
    return Response(serializer.data)

def getAgents(request, *args, **kwargs):
    if request.method == 'Get':
        id = request.GET.get('id')
        organization = UserAccount.objects.get(id=id)
        agents = UserAccount.objects.filter(role='2')
        
        names = [agent.full_name for agent in agents]

        data = {
            'titles': names
        }

        return JsonResponse(data)

# ---------------------------
# Wallet Views
# ---------------------------

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_wallet(request):
    wallet, _ = Wallet.objects.get_or_create(user=request.user)
    serializer = WalletSerializer(wallet)
    return Response(serializer.data)


from .models import WalletTransaction
from .serializers import WalletTransactionSerializer

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def add_funds(request):
    amount = request.data.get('amount')

    try:
        amount = float(amount)
        if amount <= 0:
            raise ValueError
    except:
        return Response({'error': 'Invalid amount'}, status=status.HTTP_400_BAD_REQUEST)

    wallet, _ = Wallet.objects.get_or_create(user=request.user)
    wallet.balance += amount
    wallet.save()

    # Log transaction
    WalletTransaction.objects.create(
        user=request.user,
        amount=amount,
        transaction_type='credit',
        purpose='Wallet Recharge'
    )

    return Response({
        'message': 'Funds added successfully',
        'balance': wallet.balance
    }, status=status.HTTP_200_OK)

# ---------------------------
# Subscription Views
# ---------------------------

@api_view(['GET'])
@permission_classes([AllowAny])
def list_subscription_packages(request):
    packages = SubscriptionPackage.objects.all()
    serializer = SubscriptionPackageSerializer(packages, many=True)
    return Response(serializer.data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def subscribe_package(request):
    package_id = request.data.get('package_id')
    duration_days = request.data.get('duration_days', 30)  # Optional override

    if not package_id:
        return Response({'error': 'Package ID is required'}, status=status.HTTP_400_BAD_REQUEST)

    package = get_object_or_404(SubscriptionPackage, id=package_id)
    wallet, _ = Wallet.objects.get_or_create(user=request.user)

    if wallet.balance < package.price:
        return Response({'error': 'Insufficient balance'}, status=status.HTTP_400_BAD_REQUEST)

    wallet.balance -= package.price
    wallet.save()

    subscription = Subscription.objects.create(
        user=request.user,
        package=package,
        duration_days=duration_days
    )

    WalletTransaction.objects.create(
        user=request.user,
        amount=package.price,
        transaction_type='debit',
        purpose=f'Subscription to {package.name}'
    )

    serializer = SubscriptionSerializer(subscription)

    return Response({
        'message': f'Subscribed to {package.name}',
        'subscription': serializer.data,
        'remaining_balance': wallet.balance
    }, status=status.HTTP_201_CREATED)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def my_subscriptions(request):
    subscriptions = Subscription.objects.filter(user=request.user).order_by('-subscription_date')
    serializer = SubscriptionSerializer(subscriptions, many=True)
    return Response(serializer.data)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def wallet_transaction_history(request):
    transactions = WalletTransaction.objects.filter(user=request.user).order_by('-timestamp')
    serializer = WalletTransactionSerializer(transactions, many=True)
    return Response(serializer.data)

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def check_active_subscription(request):
    active_subs = Subscription.objects.filter(user=request.user, expiry_date__gt=timezone.now()).order_by('-expiry_date')

    if active_subs.exists():
        return Response({
            'is_active': True,
            'active_subscription': SubscriptionSerializer(active_subs.first()).data
        })

    return Response({'is_active': False})


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_stripe_session(request):
    try:
        amount = float(request.data.get('amount'))
        if amount <= 0:
            raise ValueError
    except:
        return Response({'error': 'Invalid amount'}, status=status.HTTP_400_BAD_REQUEST)

    # Stripe expects amount in cents
    stripe_session = stripe.checkout.Session.create(
        payment_method_types=['card'],
        line_items=[{
            'price_data': {
                'currency': 'usd',
                'product_data': {
                    'name': 'Wallet Recharge',
                },
                'unit_amount': int(amount * 100),
            },
            'quantity': 1,
        }],
        mode='payment',
        success_url=settings.STRIPE_SUCCESS_URL + '?session_id={CHECKOUT_SESSION_ID}',
        cancel_url=settings.STRIPE_CANCEL_URL,
    )

    # Log recharge intent
    StripeRecharge.objects.create(
        user=request.user,
        session_id=stripe_session['id'],
        amount=amount
    )

    return Response({'sessionId': stripe_session['id'], 'publicKey': settings.STRIPE_PUBLIC_KEY})


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def stripe_payment_success(request):
    session_id = request.query_params.get('session_id')
    if not session_id:
        return Response({'error': 'Session ID is required'}, status=status.HTTP_400_BAD_REQUEST)

    recharge = get_object_or_404(StripeRecharge, session_id=session_id, user=request.user)

    if recharge.success:
        return Response({'message': 'Already processed'})

    session = stripe.checkout.Session.retrieve(session_id)
    if session.payment_status != 'paid':
        return Response({'error': 'Payment not completed'}, status=status.HTTP_400_BAD_REQUEST)

    # Mark as success
    recharge.success = True
    recharge.save()

    # Add funds
    wallet, _ = Wallet.objects.get_or_create(user=request.user)
    wallet.balance += recharge.amount
    wallet.save()

    # Log transaction
    WalletTransaction.objects.create(
        user=request.user,
        amount=recharge.amount,
        transaction_type='credit',
        purpose='Stripe Recharge'
    )

    return Response({'message': 'Wallet recharged successfully'})

# # Configure PayPal SDK
# paypalrestsdk.configure({
#     "mode": settings.PAYPAL_MODE,
#     "client_id": settings.PAYPAL_CLIENT_ID,
#     "client_secret": settings.PAYPAL_CLIENT_SECRET
# })

# @api_view(['POST'])
# @permission_classes([IsAuthenticated])
# def create_paypal_payment(request):
#     try:
#         amount = float(request.data.get('amount'))
#         if amount <= 0:
#             raise ValueError
#     except:
#         return Response({'error': 'Invalid amount'}, status=status.HTTP_400_BAD_REQUEST)

#     payment = paypalrestsdk.Payment({
#         "intent": "sale",
#         "payer": {
#             "payment_method": "paypal"
#         },
#         "redirect_urls": {
#             "return_url": settings.PAYPAL_SUCCESS_URL,
#             "cancel_url": settings.PAYPAL_CANCEL_URL,
#         },
#         "transactions": [{
#             "amount": {
#                 "total": f"{amount:.2f}",
#                 "currency": "USD"
#             },
#             "description": "Wallet Recharge"
#         }]
#     })

#     if payment.create():
#         PayPalRecharge.objects.create(
#             user=request.user,
#             payment_id=payment.id,
#             amount=amount
#         )

#         # Find approval URL
#         for link in payment.links:
#             if link.rel == "approval_url":
#                 return Response({"payment_url": link.href})
#         return Response({"error": "Approval URL not found"}, status=status.HTTP_400_BAD_REQUEST)
#     else:
#         return Response({"error": payment.error}, status=status.HTTP_400_BAD_REQUEST)


# @api_view(['GET'])
# @permission_classes([IsAuthenticated])
# def paypal_payment_success(request):
#     payment_id = request.query_params.get('paymentId')
#     payer_id = request.query_params.get('PayerID')

#     if not payment_id or not payer_id:
#         return Response({'error': 'Missing parameters'}, status=status.HTTP_400_BAD_REQUEST)

#     recharge = get_object_or_404(PayPalRecharge, payment_id=payment_id, user=request.user)

#     if recharge.success:
#         return Response({'message': 'Payment already processed'})

#     payment = paypalrestsdk.Payment.find(payment_id)
#     if payment.execute({"payer_id": payer_id}):
#         recharge.success = True
#         recharge.payer_id = payer_id
#         recharge.save()

#         # Add to wallet
#         wallet, _ = Wallet.objects.get_or_create(user=request.user)
#         wallet.balance += recharge.amount
#         wallet.save()

#         WalletTransaction.objects.create(
#             user=request.user,
#             amount=recharge.amount,
#             transaction_type='credit',
#             purpose='PayPal Recharge'
#         )

#         return Response({'message': 'Wallet recharged successfully'})
#     else:
#         return Response({'error': 'Payment execution failed'}, status=status.HTTP_400_BAD_REQUEST)

class ConnectedOrganizationsView(APIView):
    permission_classes = [IsAuthenticated]
    def get(self, request):
        try:
            agent = Agent.objects.get(user=request.user)
            organizations = agent.organizations_associated.filter(
                invitation__is_accepted=True
            ).distinct()
            serializer = OrganizationSerializer(organizations, many=True, context={'request': request})
            return Response(serializer.data)
        except Agent.DoesNotExist:
            return Response({'error': 'Agent does not exist'}, status=status.HTTP_404_NOT_FOUND)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_paypal_payment(request):
    user = request.user
    package_id = request.data.get('package_id')
    coupon_code = (request.data.get('coupon') or '').strip()  # <--- new

    

    # Validate package
    try:
        package = SubscriptionPackage.objects.get(id=package_id)
    except SubscriptionPackage.DoesNotExist:
        return Response({"error": "Package not found"}, status=status.HTTP_404_NOT_FOUND)

    price = package.price
    applied_coupon = None
    final_price = price

    

    # --- Coupon Validation/Calculation ---
    if coupon_code:
        try:
            coupon = Coupon.objects.get(code__iexact=coupon_code)
            if not coupon.is_valid():
                return Response({'error': 'Coupon expired or inactive.'}, status=status.HTTP_400_BAD_REQUEST)
            usage_count = CouponUsage.objects.filter(coupon=coupon, user=user).count()
            if usage_count >= coupon.max_uses:
                return Response({'error': 'You already used this coupon.'}, status=status.HTTP_400_BAD_REQUEST)
            # Calculate discount
            if coupon.discount_type == 'flat':
                final_price = max(Decimal('0.00'), price - coupon.discount_value)
            else:
                final_price = max(Decimal('0.00'), price * (Decimal('1.00') - coupon.discount_value / Decimal('100.00')))
            applied_coupon = coupon
        except Coupon.DoesNotExist:
            return Response({'error': 'Invalid coupon.'}, status=status.HTTP_400_BAD_REQUEST)

    # Zero-price shortcut (should use free subscribe endpoint, but for safety)
    if final_price == 0:
        return Response({'error': 'Coupon makes price zero; please use free subscribe endpoint.'}, status=400)
    
    final_price = str(final_price.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))

    paypalrestsdk.configure({
        "mode": settings.PAYPAL_MODE,
        "client_id": settings.PAYPAL_CLIENT_ID,
        "client_secret": settings.PAYPAL_CLIENT_SECRET,
    })

    # --- Main PayPal Payment Logic ---
    payment = paypalrestsdk.Payment({
        "intent": "sale",
        "payer": {"payment_method": "paypal"},
        "redirect_urls": {
            "return_url": settings.PAYPAL_SUCCESS_URL + f"?package_id={package.id}" + (f"&coupon={coupon_code}" if coupon_code else ""),
            "cancel_url": settings.PAYPAL_CANCEL_URL,
        },
        "transactions": [{
            "amount": {
                "total": str(final_price),
                "currency": "EUR",
            },
            "description": f"Subscribe to {package.name}" + (f" (Coupon: {coupon_code})" if coupon_code else ""),
        }]
    })

    if payment.create():
        PayPalRecharge.objects.create(
            user=user,
            payment_id=payment.id,
            amount=final_price,
            success=False,
            # Optionally log coupon_code here if you want to track
        )
        approval_url = next(
            (link.href for link in payment.links if link.rel == "approval_url"),
            None
        )
        return Response({"approval_url": approval_url})
    else:
        return Response({'error': 'Payment creation failed', 'details': payment.error}, status=status.HTTP_400_BAD_REQUEST)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def paypal_payment_success(request):
    payment_id = request.data.get('paymentId')
    payer_id = request.data.get('payerId')
    package_id = request.data.get('package_id')
    coupon_code = (request.data.get('coupon') or '').strip()  # <--- new

    if not all([payment_id, payer_id, package_id]):
        return Response({'error': 'Missing required fields.'}, status=status.HTTP_400_BAD_REQUEST)

    paypalrestsdk.configure({
        "mode": settings.PAYPAL_MODE,
        "client_id": settings.PAYPAL_CLIENT_ID,
        "client_secret": settings.PAYPAL_CLIENT_SECRET,
    })

    try:
        payment = paypalrestsdk.Payment.find(payment_id)
        if payment.execute({"payer_id": payer_id}):
            recharge = PayPalRecharge.objects.get(payment_id=payment_id)
            if not recharge.success:
                recharge.success = True
                recharge.payer_id = payer_id
                recharge.save()
                user = recharge.user
                package = SubscriptionPackage.objects.get(id=package_id)

                # --- Coupon re-validate and mark usage ---
                applied_coupon = None
                if coupon_code:
                    try:
                        coupon = Coupon.objects.get(code__iexact=coupon_code)
                        if not coupon.is_valid():
                            return Response({'error': 'Coupon expired or inactive.'}, status=status.HTTP_400_BAD_REQUEST)
                        usage_count = CouponUsage.objects.filter(coupon=coupon, user=user).count()
                        if usage_count >= coupon.max_uses:
                            return Response({'error': 'You already used this coupon.'}, status=status.HTTP_400_BAD_REQUEST)
                        # Calculate and verify price again!
                        if coupon.discount_type == 'flat':
                            final_price = max(Decimal('0.00'), package.price - coupon.discount_value)
                            final_price = final_price.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
                        else:
                            final_price = max(Decimal('0.00'), package.price * (Decimal('1.00') - coupon.discount_value / Decimal('100.00')))
                            final_price = final_price.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
                        # Check actual payment amount against computed price
                        if Decimal(payment.transactions[0].amount.total) != final_price:
                            return Response({'error': 'Payment amount mismatch. Coupon abuse detected.'}, status=status.HTTP_400_BAD_REQUEST)
                        applied_coupon = coupon
                    except Coupon.DoesNotExist:
                        return Response({'error': 'Invalid coupon.'}, status=status.HTTP_400_BAD_REQUEST)

                # --- Subscription Logic (unchanged) ---
                existing_subscription = Subscription.objects.filter(
                    user=user,
                    expiry_date__gt=timezone.now()
                ).order_by('-expiry_date').first()

                new_start = timezone.now()
                new_expiry = new_start + timedelta(days=30)  # Or package.duration_days if you want dynamic

                if existing_subscription:
                    # Update the existing subscription
                    existing_subscription.package = package
                    existing_subscription.subscription_date = new_start
                    existing_subscription.duration_days = 30
                    existing_subscription.expiry_date = new_expiry
                    existing_subscription.save()
                else:
                    # Create new subscription
                    Subscription.objects.create(
                        user=user,
                        package=package,
                        subscription_date=new_start,
                        duration_days=30,
                        expiry_date=new_expiry,
                    )

                # Mark coupon as used after success
                if applied_coupon:
                    CouponUsage.objects.create(coupon=applied_coupon, user=user)

            return Response({'success': True})
        else:
            return Response({'error': 'Payment execution failed.'}, status=status.HTTP_400_BAD_REQUEST)
    except Exception as e:
        return Response({'error': f'Error: {str(e)}'}, status=status.HTTP_400_BAD_REQUEST)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def verification_paypal_success(request):
    """
    Handles PayPal success callback for verification payment.
    For renewals: instantly approves and extends expiry.
    For new/pending verifications: keeps pending for admin review.
    """
    payment_id = request.data.get('paymentId')
    payer_id = request.data.get('payerId')
    verification_id = request.data.get('verification_id')

    if not all([payment_id, payer_id, verification_id]):
        return Response({'success': False, 'error': "Missing data"}, status=400)

    # Configure PayPal
    paypalrestsdk.configure({
        "mode": settings.PAYPAL_MODE,
        "client_id": settings.PAYPAL_CLIENT_ID,
        "client_secret": settings.PAYPAL_CLIENT_SECRET,
    })

    # Find PayPal payment and execute
    try:
        payment = paypalrestsdk.Payment.find(payment_id)
        if not payment.execute({"payer_id": payer_id}):
            return Response({'success': False, 'error': "PayPal payment execution failed."}, status=400)
    except Exception as e:
        return Response({'success': False, 'error': f"PayPal error: {str(e)}"}, status=400)

    # Find verification record
    try:
        verif = UserVerification.objects.get(pk=verification_id, user=request.user)
    except UserVerification.DoesNotExist:
        return Response({'success': False, 'error': "Verification not found."}, status=404)

    now = timezone.now()

    # Determine if this is a renewal (already approved and expired)
    is_renew = (
        verif.status == "approved" and verif.expiry_date and verif.expiry_date < now
    ) or (
        verif.status == "approved" and not verif.expiry_date  # If expiry wasn't set, treat as approved/active
    )

    if is_renew:
        # Extend expiry by 30 days (or use your own logic)
        verif.expiry_date = now + timedelta(days=30)
        verif.paid = True
        verif.status = "approved"
        verif.save()
        return Response({'success': True, 'message': "Verification renewed!"})

    # Otherwise, if this is a new/pending verification
    if verif.status in ["pending"]:
        verif.paid = True
        verif.save()
        return Response({'success': True, 'message': "Verification pending approval."})

    # If the status is rejected, user should resubmit docs instead of paying again
    if verif.status == "rejected":
        return Response({'success': False, 'error': "This verification was rejected. Please re-upload documents and do not pay again."}, status=400)

    # For already approved and active verifications (no renewal needed)
    if verif.status == "approved" and verif.expiry_date and verif.expiry_date > now:
        return Response({'success': True, 'message': "Verification is already active."})

    # Any other state (should not happen)
    return Response({'success': False, 'error': "Invalid verification status."}, status=400)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
@parser_classes([MultiPartParser, FormParser])
def resubmit_rejected_verification(request, verification_id):
    """
    Allow users to update document fields for a rejected verification.
    Sets status back to 'pending', clears rejected_reason, does NOT ask for payment.
    """
    user = request.user
    verif = get_object_or_404(UserVerification, id=verification_id, user=user)

    if verif.status != 'rejected':
        return Response({'success': False, 'message': "Only rejected verifications can be resubmitted."}, status=400)

    document_type_id = request.data.get("document_type")
    document_image = request.FILES.get("document_image")
    selfie_image = request.FILES.get("selfie_image")

    # Validate document type
    if not document_type_id or not document_image:
        return Response({'success': False, 'message': "Document type and document image are required."}, status=400)
    try:
        doc_type = IdentityDocumentType.objects.get(pk=document_type_id)
    except IdentityDocumentType.DoesNotExist:
        return Response({'success': False, 'message': "Invalid document type."}, status=400)

    # Update fields
    verif.document_type = doc_type
    verif.document_image = document_image
    if selfie_image:
        verif.selfie_image = selfie_image
    verif.status = 'pending'
    verif.rejected_reason = ""
    verif.applied_at = timezone.now()
    verif.verified_at = None
    verif.save()

    return Response({'success': True, 'message': "Documents updated and sent for review."})

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def validate_coupon(request):
    code = request.data.get('code', '').strip()
    plan_id = request.data.get('plan_id')
    user = request.user

    if not code or not plan_id:
        return Response({'valid': False, 'message': 'Coupon code and plan required.'}, status=400)
    try:
        coupon = Coupon.objects.get(code__iexact=code)
    except Coupon.DoesNotExist:
        return Response({'valid': False, 'message': 'Invalid coupon code.'})
    if not coupon.is_valid():
        return Response({'valid': False, 'message': 'Coupon expired or inactive.'})
    # Per-user usage
    usage_count = CouponUsage.objects.filter(coupon=coupon, user=user).count()
    if usage_count >= coupon.max_uses:
        return Response({'valid': False, 'message': 'You have already used this coupon the maximum number of times.'})
    # (Add global usage check if needed)

    try:
        plan = SubscriptionPackage.objects.get(id=plan_id)
    except SubscriptionPackage.DoesNotExist:
        return Response({'valid': False, 'message': 'Invalid subscription package.'})

    original_price = plan.price
    if coupon.discount_type == 'flat':
        discount = coupon.discount_value
        final_price = max(Decimal('0.00'), original_price - discount)
    else:
        percent = coupon.discount_value
        final_price = max(Decimal('0.00'), original_price * (Decimal('1.00') - percent / Decimal('100.00')))

    return Response({
        'valid': True,
        'discount_type': coupon.discount_type,
        'discount_value': str(coupon.discount_value),
        'final_price': float(final_price),
        'original_price': float(original_price),
        'message': 'Coupon applied successfully.'
    })


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def subscribe_with_coupon(request):
    plan_id = request.data.get('plan_id')
    code = request.data.get('coupon', '').strip()
    user = request.user

    # Validate plan
    try:
        plan = SubscriptionPackage.objects.get(id=plan_id)
    except SubscriptionPackage.DoesNotExist:
        return Response({'success': False, 'message': 'Invalid plan.'}, status=400)

    # Validate coupon
    try:
        coupon = Coupon.objects.get(code__iexact=code)
    except Coupon.DoesNotExist:
        return Response({'success': False, 'message': 'Invalid coupon.'}, status=400)
    if not coupon.is_valid():
        return Response({'success': False, 'message': 'Coupon expired or inactive.'}, status=400)
    usage_count = CouponUsage.objects.filter(coupon=coupon, user=user).count()
    if usage_count >= coupon.max_uses:
        return Response({'success': False, 'message': 'You already used this coupon.'}, status=400)
    # (Add global usage check if needed)

    original_price = plan.price
    if coupon.discount_type == 'flat':
        discount = coupon.discount_value
        final_price = max(Decimal('0.00'), original_price - discount)
    else:
        percent = coupon.discount_value
        final_price = max(Decimal('0.00'), original_price * (Decimal('1.00') - percent / Decimal('100.00')))

    if final_price > 0:
        return Response({'success': False, 'message': 'Coupon does not make plan free.'}, status=400)

    # Create subscription and mark coupon usage
    Subscription.objects.create(
        user=user,
        package=plan,
        subscription_date=timezone.now(),
        duration_days=30,  # Or use plan field if you want custom durations
    )
    CouponUsage.objects.create(coupon=coupon, user=user)

    return Response({'success': True, 'message': 'Subscribed successfully.'})

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def my_connected_agents(request):
    """
    Returns agents connected to the current user:
    - If user is an organization, returns all agents in their organization.
    - If user is an agent, returns only themselves.
    - Otherwise, returns empty list.
    """
    user = request.user
    agents = []
    if Organization.objects.filter(user=user).exists():
        org = Organization.objects.get(user=user)
        agents = org.agents.all()
    elif Agent.objects.filter(user=user).exists():
        agent = Agent.objects.get(user=user)
        agents = [agent]
    # Build custom response with id, name, email, phone
    agent_data = []
    for agent in agents:
        agent_user = agent.user
        profile_picture = None
        if agent_user and agent_user.profile_picture:
            if hasattr(request, 'build_absolute_uri'):
                profile_picture = request.build_absolute_uri(agent_user.profile_picture.url)
            else:
                profile_picture = agent_user.profile_picture.url
        agent_data.append({
            'id': agent.id,
            'user_id':agent.user.id,
            'name': getattr(agent_user, 'full_name', '') or getattr(agent_user, 'email', f'Agent {agent.id}'),
            'email': getattr(agent_user, 'email', ''),
            'phone': getattr(agent_user, 'phone', ''),
            'image': profile_picture,
        })
    return Response(agent_data)

# 1. Get current user verification status
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def verification_status(request):
    user = request.user
    verif = UserVerification.objects.filter(user=user).order_by('-applied_at').first()
    if not verif:
        return Response({'status': 'not_submitted'})
    return Response({
        'id': verif.id,
        'status': verif.status,
        'expiry_date': verif.expiry_date,
        'verified_at': verif.verified_at,
        'document_type': verif.document_type.name,
        'applied_at': verif.applied_at,
    })

# 2. Get verification fee and allowed doc types
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def verification_fee(request):
    fee_obj = VerificationFee.objects.order_by('-created_at').first()
    doc_types = IdentityDocumentType.objects.filter(requires_photo=True)
    return Response({
        'fee': float(fee_obj.price) if fee_obj else None,
        'doc_types': [{'id': t.id, 'name': t.name} for t in doc_types]
    })

# 3. Get discount and subscription info
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def verification_discount(request):
    user = request.user
    discount = None
    subscription = Subscription.objects.filter(user=user, expiry_date__gt=timezone.now()).order_by('-expiry_date').first()
    if subscription:
        try:
            vdiscount = VerificationDiscount.objects.get(package=subscription.package)
            discount = {
                'discount_type': vdiscount.discount_type,
                'discount_value': str(vdiscount.discount_value),
            }
            sub_info = {
                'package_name': subscription.package.name
            }
        except VerificationDiscount.DoesNotExist:
            sub_info = {
                'package_name': subscription.package.name
            }
    else:
        sub_info = None
    return Response({
        'discount': discount,
        'subscription': sub_info
    })

# 4. Submit verification documents (new)
@api_view(['POST'])
@permission_classes([IsAuthenticated])
@parser_classes([MultiPartParser, FormParser])
def submit_verification(request):
    user = request.user
    document_type_id = request.data.get('document_type')
    document_image = request.data.get('document_image')
    selfie_image = request.data.get('selfie_image')

    # Get fee
    fee_obj = VerificationFee.objects.order_by('-created_at').first()
    if not fee_obj:
        return Response({'success': False, 'message': "Verification fee not set."}, status=400)
    base_fee = Decimal(fee_obj.price)

    # Discount if subscribed
    subscription = Subscription.objects.filter(user=user, expiry_date__gt=timezone.now()).order_by('-expiry_date').first()
    final_fee = base_fee
    if subscription:
        try:
            vdiscount = VerificationDiscount.objects.get(package=subscription.package)
            if vdiscount.discount_type == "flat":
                final_fee = max(Decimal('0.00'), base_fee - vdiscount.discount_value)
            else:
                final_fee = max(Decimal('0.00'), base_fee * (Decimal('1.00') - vdiscount.discount_value / Decimal('100.00')))
        except VerificationDiscount.DoesNotExist:
            pass

    # Validate doc type
    try:
        doc_type = IdentityDocumentType.objects.get(id=document_type_id, requires_photo=True)
    except IdentityDocumentType.DoesNotExist:
        return Response({'success': False, 'message': "Invalid document type."}, status=400)
    if not document_image:
        return Response({'success': False, 'message': "Document image required."}, status=400)

    # Create verification entry
    verif = UserVerification.objects.create(
        user=user,
        document_type=doc_type,
        document_image=document_image,
        selfie_image=selfie_image,
        verification_fee=final_fee,
        status='pending',
        applied_at=timezone.now(),
    )
    return Response({'success': True, 'verification_id': verif.id})

# 5. Create PayPal payment for new verification
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def verification_paypal_create(request):
    user = request.user
    verification_id = request.data.get('verification_id')
    try:
        verif = UserVerification.objects.get(id=verification_id, user=user)
    except UserVerification.DoesNotExist:
        return Response({'success': False, 'message': "Verification request not found."}, status=404)

    if verif.paid:
        return Response({'success': False, 'message': "Verification already paid."}, status=400)
    # Setup PayPal payment
    paypalrestsdk.configure({
        "mode": settings.PAYPAL_MODE,
        "client_id": settings.PAYPAL_CLIENT_ID,
        "client_secret": settings.PAYPAL_CLIENT_SECRET,
    })
    amount_str = str(verif.verification_fee.quantize(Decimal('0.01')))
    payment = paypalrestsdk.Payment({
        "intent": "sale",
        "payer": {"payment_method": "paypal"},
        "redirect_urls": {
            "return_url": settings.VERIF_PAYPAL_SUCCESS_URL + f"?verification_id={verif.id}",
            "cancel_url": settings.VERIF_PAYPAL_CANCEL_URL,
        },
        "transactions": [{
            "amount": {
                "total": amount_str,
                "currency": "EUR",
            },
            "description": f"User verification fee for {user.email}",
        }]
    })

    if payment.create():
        # Save PayPal payment info if you have a model for it, else just return approval_url
        approval_url = next((link.href for link in payment.links if link.rel == "approval_url"), None)
        return Response({"success": True, "approval_url": approval_url})
    else:
        return Response({'success': False, 'message': "Payment creation failed.", 'details': payment.error}, status=400)

# 6. Create PayPal payment for verification renewal
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def verification_paypal_renew(request):
    user = request.user
    verification_id = request.data.get('verification_id')
    try:
        verif = UserVerification.objects.get(id=verification_id, user=user)
    except UserVerification.DoesNotExist:
        return Response({'success': False, 'message': "Verification request not found."}, status=404)
    # Get fee (again, apply discount if needed)
    fee_obj = VerificationFee.objects.order_by('-created_at').first()
    base_fee = Decimal(fee_obj.price)
    subscription = Subscription.objects.filter(user=user, expiry_date__gt=timezone.now()).order_by('-expiry_date').first()
    final_fee = base_fee
    if subscription:
        try:
            vdiscount = VerificationDiscount.objects.get(package=subscription.package)
            if vdiscount.discount_type == "flat":
                final_fee = max(Decimal('0.00'), base_fee - vdiscount.discount_value)
            else:
                final_fee = max(Decimal('0.00'), base_fee * (Decimal('1.00') - vdiscount.discount_value / Decimal('100.00')))
        except VerificationDiscount.DoesNotExist:
            pass
    # Setup PayPal payment
    paypalrestsdk.configure({
        "mode": settings.PAYPAL_MODE,
        "client_id": settings.PAYPAL_CLIENT_ID,
        "client_secret": settings.PAYPAL_CLIENT_SECRET,
    })
    amount_str = str(final_fee.quantize(Decimal('0.01')))
    payment = paypalrestsdk.Payment({
        "intent": "sale",
        "payer": {"payment_method": "paypal"},
        "redirect_urls": {
            "return_url": settings.VERIF_PAYPAL_SUCCESS_URL + f"?verification_id={verif.id}&renew=1",
            "cancel_url": settings.VERIF_PAYPAL_CANCEL_URL,
        },
        "transactions": [{
            "amount": {
                "total": amount_str,
                "currency": "EUR",
            },
            "description": f"User verification renewal for {user.email}",
        }]
    })

    if payment.create():
        approval_url = next((link.href for link in payment.links if link.rel == "approval_url"), None)
        return Response({"success": True, "approval_url": approval_url})
    else:
        return Response({'success': False, 'message': "Payment creation failed.", 'details': payment.error}, status=400)

@api_view(['GET'])
@permission_classes([AllowAny])  # Or IsAuthenticated if you want to restrict
def subscription_package_list(request):
    packages = SubscriptionPackage.objects.all()
    serializer = SubscriptionPackageSerializer(packages, many=True)
    return Response(serializer.data)

@api_view(['GET'])
@permission_classes([AllowAny])
def profile_information_view(request, user_id):
    from .models import UserAccount, UserProfile
    from django.shortcuts import get_object_or_404
    user = get_object_or_404(UserAccount, id=user_id)
    try:
        profile = UserProfile.objects.get(user=user)
    except UserProfile.DoesNotExist:
        profile = None

    # Build absolute URL for profile_picture if it exists
    if user.profile_picture:
        request_protocol = 'https' if request.is_secure() else 'http'
        domain = request.get_host()
        profile_picture_url = f"{request_protocol}://{domain}{user.profile_picture.url}"
    else:
        profile_picture_url = None

    user_data = {
        "id": user.id,
        "full_name": user.full_name,
        "email": user.email,
        "phone": user.phone,
        "role": user.role,
        "profile_picture": profile_picture_url,
        # Add is_verified field
        "is_verified": False,
    }
    # Check verification status
    from users.models import UserVerification
    latest_verification = (
        UserVerification.objects
        .filter(user=user, status='approved')
        .order_by('-verified_at')
        .first()
    )
    if latest_verification and latest_verification.is_active():
        user_data["is_verified"] = True

    profile_data = {
        "skype_link": profile.skype_link if profile else "",
        "facebook_link": profile.facebook_link if profile else "",
        "linkedin_link": profile.linkedin_link if profile else "",
        "title": profile.title if profile else "",
        "website": profile.website if profile else "",
        "twitter": profile.twitter if profile else "",
        "pinterest": profile.pinterest if profile else "",
        "description": profile.description if profile else "",
    }

    return Response({
        "user": user_data,
        "profile": profile_data,
    }, status=status.HTTP_200_OK)

# --- Property Addon PayPal Payment Endpoints ---
from decimal import Decimal
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
import paypalrestsdk
from django.conf import settings

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def property_paypal_create_addon_payment(request):
    """
    Creates a PayPal payment for property addon fees (hide address/contact).
    Expects POST with hide_address, hide_contact (bools).
    Returns approval_url for PayPal payment.
    """
    hide_address = request.data.get('hide_address', False)
    hide_contact = request.data.get('hide_contact', False)

    from property.models import PropertyAddonsFee
    from users.models import Subscription
    from django.utils import timezone
    
    fee_obj = PropertyAddonsFee.objects.order_by('-id').first()
    if not fee_obj:
        return Response({'error': 'Addon fee configuration not found.'}, status=500)

    # Check for active subscription and available credits
    active_subscription = Subscription.objects.filter(
        user=request.user,
        expiry_date__gt=timezone.now()
    ).order_by('-subscription_date').first()
    
    # Calculate what user needs to pay for (after using available credits)
    if active_subscription:
        can_use_hide_address = active_subscription.hide_address_count > 0 and hide_address
        can_use_hide_contact = active_subscription.hide_contact_count > 0 and hide_contact
        
        if hide_address and hide_contact:
            # Both selected - check if we can use combined fee or need to calculate individually
            if can_use_hide_address and can_use_hide_contact:
                # Both can be covered by credits
                base_fee = Decimal('0.00')
            elif can_use_hide_address:
                # Only hide address can be covered by credits, pay for hide contact
                base_fee = fee_obj.hide_contact_fee
            elif can_use_hide_contact:
                # Only hide contact can be covered by credits, pay for hide address
                base_fee = fee_obj.hide_address_fee
            else:
                # Neither can be covered by credits, use combined fee
                base_fee = fee_obj.hide_address_and_contact_combined_fee
        elif hide_address:
            base_fee = Decimal('0.00') if can_use_hide_address else fee_obj.hide_address_fee
        elif hide_contact:
            base_fee = Decimal('0.00') if can_use_hide_contact else fee_obj.hide_contact_fee
        else:
            base_fee = Decimal('0.00')
    else:
        # No subscription - use regular pricing
        if hide_address and hide_contact:
            base_fee = fee_obj.hide_address_and_contact_combined_fee
        elif hide_address:
            base_fee = fee_obj.hide_address_fee
        elif hide_contact:
            base_fee = fee_obj.hide_contact_fee
        else:
            base_fee = Decimal('0.00')

    if base_fee == 0:
        return Response({'error': 'No addon fee required.'}, status=400)

    paypalrestsdk.configure({
        "mode": settings.PAYPAL_MODE,
        "client_id": settings.PAYPAL_CLIENT_ID,
        "client_secret": settings.PAYPAL_CLIENT_SECRET,
    })
    amount_str = str(base_fee.quantize(Decimal('0.01')))
    payment = paypalrestsdk.Payment({
        "intent": "sale",
        "payer": {"payment_method": "paypal"},
        "redirect_urls": {
            "return_url": settings.PAYPAL_SUCCESS_URL + "?addon=1",
            "cancel_url": settings.PAYPAL_CANCEL_URL,
        },
        "transactions": [{
            "amount": {
                "total": amount_str,
                "currency": "EUR",
            },
            "description": f"Property addon fee (hide address/contact)",
        }]
    })
    if payment.create():
        approval_url = next((link.href for link in payment.links if link.rel == "approval_url"), None)
        return Response({"approval_url": approval_url, "fee": float(base_fee)})
    else:
        return Response({'error': 'Payment creation failed.', 'details': payment.error}, status=400)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def property_paypal_confirm_addon_payment(request):
    """
    Confirms PayPal payment for property addon fee. Expects POST with paymentId, payerId, hide_address, hide_contact, and property data (TBD).
    Verifies payment, then allows property creation (for now, just returns success if payment is valid).
    """
    payment_id = request.data.get('paymentId')
    payer_id = request.data.get('payerId')
    hide_address = request.data.get('hide_address', False)
    hide_contact = request.data.get('hide_contact', False)
    # property_data = request.data.get('property_data')  # To be used in next step

    if not all([payment_id, payer_id]):
        return Response({'error': 'Missing paymentId or payerId.'}, status=400)

    paypalrestsdk.configure({
        "mode": settings.PAYPAL_MODE,
        "client_id": settings.PAYPAL_CLIENT_ID,
        "client_secret": settings.PAYPAL_CLIENT_SECRET,
    })
    try:
        payment = paypalrestsdk.Payment.find(payment_id)
        if payment.execute({"payer_id": payer_id}):
            # Optionally, check amount matches expected fee
            # Next step: create property here if property_data is provided
            return Response({'success': True, 'message': 'Payment confirmed. You can now create the property.'})
        else:
            return Response({'error': 'Payment execution failed.'}, status=400)
    except Exception as e:
        return Response({'error': f'PayPal error: {str(e)}'}, status=400)

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def my_subscription(request):
    try:
        # Only one active subscription (non-expired)
        sub = (
            Subscription.objects
            .filter(user=request.user, expiry_date__gt=timezone.now())
            .order_by('-expiry_date')
            .first()
        )

        if not sub:
            return JsonResponse({"boost_count": 0, "message": "No active subscription."})
        return JsonResponse({
            "id": sub.id,
            "package": sub.package.name,
            "boost_count": sub.boost_count,
            "expiry_date": sub.expiry_date,
        })
    except Exception as e:
        return JsonResponse({"error": str(e)}, status=500)