from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
from rest_framework import status
from rest_framework.exceptions import MethodNotAllowed
from rest_framework.permissions import IsAuthenticated
from .authentication import HasAPIKey

from django.conf import settings
from django.http import Http404, HttpResponse, JsonResponse
from django.db.models import Q
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from django.shortcuts import get_object_or_404

from .serializers import ClubSerializer, CourtSerializer, DateIntervalSerializer, DrawLogSerializer, TournamentSerializer, UserSerializer, EventSerializer, RoundSerializer, GroupStageSerializer, MatchSerializer, TeamScoreSerializer, TeamRegistrationSerializer, PlayerRegistrationSerializer, PurchaseSerializer, ShortUserSerializer, FailedApiCallSerializer, LogSerializer, DeviceTokenSerializer, CustomUserSerializer, UnregisteredTeamSerializer, UnregisteredPlayerSerializer, ImageSerializer, ActivitySerializer, ProspectSerializer, EntitySerializer, TournamentSummarySerializer
from tournaments.models import Club, Tournament, CustomUser, Event, Round, GroupStage, Match, TeamScore, TeamRegistration, PlayerRegistration, Court, DateInterval, Purchase, FailedApiCall, Log, DeviceToken, DrawLog, UnregisteredTeam, UnregisteredPlayer, Image

from biz.models import Activity, Prospect, Entity

from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework import status
from rest_framework.exceptions import MethodNotAllowed

from django.http import Http404
from django.db.models import Q

from .permissions import IsClubOwner
from .utils import check_version_smaller_than_1_1_12, scrape_fft_club_tournaments, scrape_fft_club_tournaments_all_pages, get_umpire_data, scrape_fft_all_tournaments, scrape_fft_all_tournaments_concurrent, scrape_federal_clubs
from shared.discord import send_discord_log_message

from tournaments.services.payment_service import PaymentService
from tournaments.utils.extensions import create_random_filename

import stripe
import json
import pandas as pd

import os
import logging
from datetime import datetime

logger = logging.getLogger(__name__)

@api_view(['GET'])
def user_by_token(request):
    serializer = UserSerializer(request.user)
    return Response(serializer.data, status=status.HTTP_200_OK)

class SoftDeleteViewSet(viewsets.ModelViewSet):
    def destroy(self, request, *args, **kwargs):
        try:
            return super().destroy(request, *args, **kwargs)
        except Http404:
            return Response(status=status.HTTP_204_NO_CONTENT)

class UserViewSet(SoftDeleteViewSet):
    queryset = CustomUser.objects.all()
    serializer_class = CustomUserSerializer
    permission_classes = [] # Users are public whereas the other requests are only for logged users

    def get_serializer_class(self):
        # Use UserSerializer for other actions (e.g., create, retrieve)
        if self.action in ['create', 'retrieve']:
            return UserSerializer
        return self.serializer_class

class ClubViewSet(SoftDeleteViewSet):
    queryset = Club.objects.all()
    serializer_class = ClubSerializer
    permission_classes = [IsClubOwner] # Clubs are public whereas the other requests are only for logged users

    def perform_create(self, serializer):
        serializer.save(creator=self.request.user)

class TournamentSummaryViewSet(SoftDeleteViewSet):
    queryset = Tournament.objects.all()
    serializer_class = TournamentSummarySerializer
    permission_classes = [HasAPIKey]

    def get_queryset(self):
        if self.request.user.is_anonymous:
            return Tournament.objects.none()

        queryset = self.queryset.filter(
            Q(event__creator=self.request.user) | Q(related_user=self.request.user)
        ).distinct()

        # Add min_start_date filtering
        min_start_date = self.request.query_params.get('min_start_date')
        if min_start_date:
            try:
                # Parse the date string (assumes ISO format: YYYY-MM-DD)
                min_date = datetime.fromisoformat(min_start_date).date()
                print(min_date)
                queryset = queryset.filter(start_date__gte=min_date)
            except (ValueError, TypeError):
                # If date parsing fails, ignore the filter
                pass

        return queryset

class TournamentViewSet(SoftDeleteViewSet):
    queryset = Tournament.objects.all()
    serializer_class = TournamentSerializer

    def get_queryset(self):
        if self.request.user.is_anonymous:
            return []
            return self.queryset.filter(
                Q(event__creator=self.request.user))

        return self.queryset.filter(
            Q(event__creator=self.request.user) | Q(related_user=self.request.user)
        ).distinct()


    def perform_create(self, serializer):
        serializer.save()
        # version check
        app_version = self.request.headers.get('App-Version')
        self.warn_if_version_is_too_small(app_version)

    def warn_if_version_is_too_small(self, version):
        if check_version_smaller_than_1_1_12(version):
            message = f'{self.request.user.username} app version is {version}'
            send_discord_log_message(message)

class PurchaseViewSet(SoftDeleteViewSet):
    queryset = Purchase.objects.all()
    serializer_class = PurchaseSerializer

    def get_queryset(self):
        if self.request.user:
            return self.queryset.filter(user=self.request.user)
        return []

    def create(self, request, *args, **kwargs):
        id = request.data.get('id')
        if Purchase.objects.filter(id=id).exists():
            return Response({"detail": "This transaction id is already registered."}, status=status.HTTP_208_ALREADY_REPORTED)

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def patch(self, request, pk):
        raise MethodNotAllowed('PATCH')

    def delete(self, request, pk):
        raise MethodNotAllowed('DELETE')

class EventViewSet(SoftDeleteViewSet):
    queryset = Event.objects.all()
    serializer_class = EventSerializer

    def get_queryset(self):
        if self.request.user.is_anonymous:
            return []
        # return self.queryset.filter(creator=self.request.user)
        return self.queryset.filter(
                Q(creator=self.request.user)
            )

class RoundViewSet(SoftDeleteViewSet):
    queryset = Round.objects.all()
    serializer_class = RoundSerializer

    def get_queryset(self):
        tournament_id = self.request.query_params.get('store_id') or self.request.query_params.get('tournament')
        if tournament_id:
            return self.queryset.filter(tournament=tournament_id)
        if self.request.user:
            return self.queryset.filter(tournament__event__creator=self.request.user)
        return []

class GroupStageViewSet(SoftDeleteViewSet):
    queryset = GroupStage.objects.all()
    serializer_class = GroupStageSerializer

    def get_queryset(self):
        tournament_id = self.request.query_params.get('store_id') or self.request.query_params.get('tournament')
        if tournament_id:
            return self.queryset.filter(tournament=tournament_id)
        if self.request.user:
            return self.queryset.filter(tournament__event__creator=self.request.user)
        return []

class MatchViewSet(SoftDeleteViewSet):
    queryset = Match.objects.all()
    serializer_class = MatchSerializer

    def get_queryset(self):
        tournament_id = self.request.query_params.get('store_id') or self.request.query_params.get('tournament')
        if tournament_id:
            return self.queryset.filter(Q(group_stage__tournament=tournament_id) | Q(round__tournament=tournament_id))
        if self.request.user:
            return self.queryset.filter(Q(group_stage__tournament__event__creator=self.request.user) | Q(round__tournament__event__creator=self.request.user))
        return []

class TeamScoreViewSet(SoftDeleteViewSet):
    queryset = TeamScore.objects.all()
    serializer_class = TeamScoreSerializer

    def get_queryset(self):
        tournament_id = self.request.query_params.get('store_id') or self.request.query_params.get('tournament')
        if tournament_id:
            q = Q(team_registration__tournament=tournament_id) | Q(match__group_stage__tournament=tournament_id) | Q(match__round__tournament=tournament_id)
            return self.queryset.filter(q)
        if self.request.user:
            return self.queryset.filter(team_registration__tournament__event__creator=self.request.user)
        return []

class TeamRegistrationViewSet(SoftDeleteViewSet):
    queryset = TeamRegistration.objects.all()
    serializer_class = TeamRegistrationSerializer

    def get_queryset(self):
        tournament_id = self.request.query_params.get('store_id') or self.request.query_params.get('tournament')
        if tournament_id:
            return self.queryset.filter(tournament=tournament_id)
        if self.request.user:
            return self.queryset.filter(tournament__event__creator=self.request.user)
        return []

class PlayerRegistrationViewSet(SoftDeleteViewSet):
    queryset = PlayerRegistration.objects.all()
    serializer_class = PlayerRegistrationSerializer

    def get_queryset(self):
        tournament_id = self.request.query_params.get('store_id') or self.request.query_params.get('tournament')
        if tournament_id:
            return self.queryset.filter(team_registration__tournament=tournament_id)
        if self.request.user:
            return self.queryset.filter(team_registration__tournament__event__creator=self.request.user)
        return []

class CourtViewSet(SoftDeleteViewSet):
    queryset = Court.objects.all()
    serializer_class = CourtSerializer

class DateIntervalViewSet(SoftDeleteViewSet):
    queryset = DateInterval.objects.all()
    serializer_class = DateIntervalSerializer

    def get_queryset(self):
        if self.request.user.is_anonymous:
            return []

        return self.queryset.filter(
                Q(event__creator=self.request.user)
            )

class FailedApiCallViewSet(viewsets.ModelViewSet):
    queryset = FailedApiCall.objects.all()
    serializer_class = FailedApiCallSerializer
    permission_classes = [] # FailedApiCall are public whereas the other requests are only for logged users

    def get_queryset(self):
        return []

    def perform_create(self, serializer):
        if self.request.user.is_anonymous == False:
            serializer.save(user=self.request.user)
        else:
            serializer.save()

class LogViewSet(viewsets.ModelViewSet):
    queryset = Log.objects.all()
    serializer_class = LogSerializer
    permission_classes = [] # Log are public whereas the other requests are only for logged users

    def get_queryset(self):
        return []

    def perform_create(self, serializer):
        if self.request.user.is_anonymous == False:
            serializer.save(user=self.request.user)
        else:
            serializer.save()

class DeviceTokenViewSet(viewsets.ModelViewSet):
    queryset = DeviceToken.objects.all()
    serializer_class = DeviceTokenSerializer

    def get_queryset(self):
        if self.request.user:
            return self.queryset.filter(user=self.request.user)
        return []

    def create(self, request, *args, **kwargs):
        value = request.data.get('value')
        if DeviceToken.objects.filter(value=value).exists():
            return Response({"detail": "This device token is already registered."}, status=208)

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

class DrawLogViewSet(SoftDeleteViewSet):
    queryset = DrawLog.objects.all()
    serializer_class = DrawLogSerializer

    def get_queryset(self):
        tournament_id = self.request.query_params.get('tournament') or self.request.query_params.get('tournament')
        if tournament_id:
            return self.queryset.filter(tournament=tournament_id)
        if self.request.user:
            return self.queryset.filter(tournament__event__creator=self.request.user)
        return []

class UnregisteredTeamViewSet(SoftDeleteViewSet):
    queryset = UnregisteredTeam.objects.all()
    serializer_class = UnregisteredTeamSerializer

    def get_queryset(self):
        tournament_id = self.request.query_params.get('tournament')
        if tournament_id:
            return self.queryset.filter(tournament=tournament_id)
        if self.request.user:
            return self.queryset.filter(tournament__event__creator=self.request.user)
        return []

class UnregisteredPlayerViewSet(SoftDeleteViewSet):
    queryset = UnregisteredPlayer.objects.all()
    serializer_class = UnregisteredPlayerSerializer

    def get_queryset(self):
        tournament_id = self.request.query_params.get('tournament')
        if tournament_id:
            return self.queryset.filter(unregistered_team__tournament=tournament_id)
        if self.request.user:
            return self.queryset.filter(unregistered_team__tournament__event__creator=self.request.user)
        return []

class ShortUserViewSet(viewsets.ModelViewSet):
    queryset = CustomUser.objects.all()
    serializer_class = ShortUserSerializer
    permission_classes = [] # Users are public whereas the other requests are only for logged users

    def get_queryset(self):
        return self.request.user.agents

class ImageViewSet(viewsets.ModelViewSet):
    """
    Viewset for handling event image uploads and retrieval.

    This allows umpires/organizers to upload images for events from the iOS app,
    which can then be displayed on the event pages.
    """
    serializer_class = ImageSerializer
    queryset = Image.objects.all()

    def get_queryset(self):
        queryset = Image.objects.all()

        # Filter by event
        event_id = self.request.query_params.get('event_id')
        image_type = self.request.query_params.get('image_type')

        if event_id:
            queryset = queryset.filter(event_id=event_id)
        if image_type:
            queryset = queryset.filter(image_type=image_type)

        return queryset

    def perform_create(self, serializer):
        serializer.save()


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def process_refund(request, team_registration_id):
    try:
        # Verify the user is the tournament umpire
        team_registration = get_object_or_404(TeamRegistration, id=team_registration_id)
        if request.user != team_registration.tournament.event.creator:
            return Response({
                'success': False,
                'message': "Vous n'êtes pas autorisé à effectuer ce remboursement"
            }, status=403)

        payment_service = PaymentService(request)
        players_serializer = PlayerRegistrationSerializer(team_registration.players_sorted_by_rank, many=True)
        success, message, refund = payment_service.process_refund(team_registration_id, force_refund=True)
        return Response({
            'success': success,
            'message': message,
            'players': players_serializer.data
        })
    except Exception as e:
            return Response({
                'success': False,
                'message': str(e)
            }, status=400)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def xls_to_csv(request):
    # Check if the request has a file
    if 'file' in request.FILES:
        uploaded_file = request.FILES['file']

        # Save the uploaded file
        directory = 'tmp/csv/'
        file_path = os.path.join(directory, uploaded_file.name)
        file_name = default_storage.save(file_path, ContentFile(uploaded_file.read()))

        logger.info(f'file saved at {file_name}')
        full_path = default_storage.path(file_name)
        logger.info(f'full_path = {full_path}')

        # Check available sheets and look for 'inscriptions'
        xls = pd.ExcelFile(full_path)
        sheet_names = xls.sheet_names

        # Determine which sheet to use
        target_sheet = 0  # Default to first sheet
        if 'inscriptions' in [name.lower() for name in sheet_names]:
            for i, name in enumerate(sheet_names):
                if name.lower() == 'inscriptions':
                    target_sheet = i  # or use the name directly: target_sheet = name
                    break

        # Convert to csv and save
        data_xls = pd.read_excel(full_path, sheet_name=target_sheet, index_col=None)
        csv_file_name = create_random_filename('players', 'csv')
        output_path = os.path.join(directory, csv_file_name)
        full_output_path = default_storage.path(output_path)
        data_xls.to_csv(full_output_path, sep=';', index=False, encoding='utf-8')

        # Send the processed file back
        with default_storage.open(full_output_path, 'rb') as file:
            response = HttpResponse(file.read(), content_type='application/octet-stream')
            response['Content-Disposition'] = f'attachment; filename="players.csv"'

        # Clean up: delete both files
        default_storage.delete(file_path)
        default_storage.delete(output_path)

        return response
    else:
        return HttpResponse("No file was uploaded", status=400)

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_tournament_config(request):
    """Return tournament-related configuration settings"""
    config = settings.TOURNAMENT_SETTINGS
    return Response({
        'time_proximity_rules': config['TIME_PROXIMITY_RULES'],
        'waiting_list_rules': config['WAITING_LIST_RULES'],
        'business_rules': config['BUSINESS_RULES'],
        'minimum_response_time': config['MINIMUM_RESPONSE_TIME']
    })

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_payment_config(request):
    """Return payment-related configuration settings"""
    return Response({
        'stripe_fee': getattr(settings, 'STRIPE_FEE', 0)
    })

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_stripe_connect_account(request):
    stripe.api_key = settings.STRIPE_SECRET_KEY
    user = request.user

    try:
        # Create a new Standard account
        account = stripe.Account.create(
            type='standard',
            metadata={
                'padelclub_email': user.email,
                'platform': 'padelclub'
            }
        )

        return Response({
            'success': True,
            'account_id': account.id,
        })

    except Exception as e:
        return Response({
            'success': False,
            'error': str(e)
        }, status=400)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_stripe_account_link(request):
    """
    Create an account link for a Stripe account.
    Uses HTTPS URLs only - no custom URL schemes.
    """
    stripe.api_key = settings.STRIPE_SECRET_KEY

    # Parse request data
    data = json.loads(request.body)
    account_id = data.get('account_id')

    if not account_id:
        return Response({
            'success': False,
            'error': 'No Stripe account ID found'
        }, status=400)

    try:
        base_path = f"{request.scheme}://{request.get_host()}"

        refresh_url = f"{base_path}/stripe-refresh-account-link/"
        return_url = f"{base_path}/stripe-onboarding-complete/"

        # Generate the account link URL
        account_link = stripe.AccountLink.create(
            account=account_id,
            refresh_url=refresh_url,
            return_url=return_url,
            type='account_onboarding',
        )

        return Response({
            'success': True,
            'url': account_link.url,
            'account_id': account_id
        })
    except Exception as e:
        return Response({
            'success': False,
            'error': str(e)
        }, status=400)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def validate_stripe_account(request):
    """
    Validate a Stripe account for a tournament.
    Returns validation status and onboarding URL if needed.
    """
    stripe.api_key = settings.STRIPE_SECRET_KEY

    # Parse the request body
    data = json.loads(request.body)
    account_id = data.get('account_id')

    if not account_id:
        return Response({
            'valid': False,
            'error': 'No account ID found to validate',
            'needs_onboarding': True
        }, status=200)

    try:
        # Validate the account with Stripe
        account = stripe.Account.retrieve(account_id)

        # Check account capabilities
        charges_enabled = account.get('charges_enabled', False)
        payouts_enabled = account.get('payouts_enabled', False)
        details_submitted = account.get('details_submitted', False)

        # Determine if the account is valid and ready
        is_valid = account.id is not None
        can_process_payments = charges_enabled and payouts_enabled
        onboarding_complete = details_submitted
        needs_onboarding = not (can_process_payments and onboarding_complete)

        return Response({
            'valid': is_valid,
            'can_process_payments': can_process_payments,
            'onboarding_complete': onboarding_complete,
            'needs_onboarding': needs_onboarding,
            'account': {
                'id': account.id,
                'charges_enabled': charges_enabled,
                'payouts_enabled': payouts_enabled,
                'details_submitted': details_submitted
            }
        })

    except stripe.error.PermissionError:
        # Account doesn't exist or isn't connected to your platform
        return Response({
            'valid': False,
            'error': 'This Stripe account is not connected to your platform or does not exist.',
            'needs_onboarding': True,
        }, status=200)

    except stripe.error.InvalidRequestError:
        return Response({
            'valid': False,
            'error': 'Invalid account ID format',
            'needs_onboarding': True,
        }, status=200)

    except Exception as e:
        return Response({
            'valid': False,
            'error': f'Unexpected error: {str(e)}',
            'needs_onboarding': True,
        }, status=200)

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def is_granted_unlimited_access(request):
    can_create = False
    if request.user and request.user.is_anonymous == False and request.user.owners:
        for owner in request.user.owners.all():
            purchases = Purchase.objects.filter(user=owner,product_id='app.padelclub.tournament.subscription.unlimited')
            for purchase in purchases:
                if purchase.is_active():
                    can_create = True
    return JsonResponse({'can_create': can_create}, status=status.HTTP_200_OK)

@api_view(['GET', 'POST'])
@permission_classes([])
def get_fft_club_tournaments(request):
    """
    API endpoint to get tournaments for a specific club
    Handles pagination automatically to get all results
    """
    try:
        if request.method == 'POST':
            data = request.data
        else:
            data = request.GET

        club_code = data.get('club_code', '62130180')
        club_name = data.get('club_name', 'TENNIS SPORTING CLUB DE CASSIS')
        start_date = data.get('start_date')
        end_date = data.get('end_date')
        paginate = data.get('paginate', 'true').lower() == 'true'

        if paginate:
            # Get all pages automatically (matching Swift behavior)
            result = scrape_fft_club_tournaments_all_pages(
                club_code=club_code,
                club_name=club_name,
                start_date=start_date,
                end_date=end_date
            )
        else:
            # Get single page
            page = int(data.get('page', 0))
            result = scrape_fft_club_tournaments(
                club_code=club_code,
                club_name=club_name,
                start_date=start_date,
                end_date=end_date,
                page=page
            )

        if result:
            return JsonResponse({
                'success': True,
                'tournaments': result.get('tournaments', []),
                'total_results': result.get('total_results', 0),
                'current_count': result.get('current_count', 0),
                'pages_scraped': result.get('pages_scraped', 1),
                'message': f'Successfully scraped {len(result.get("tournaments", []))} tournaments'
            }, status=status.HTTP_200_OK)
        else:
            return JsonResponse({
                'success': False,
                'tournaments': [],
                'total_results': 0,
                'current_count': 0,
                'message': 'Failed to scrape club tournaments'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    except Exception as e:
        logger.error(f"Error in get_fft_club_tournaments endpoint: {e}")
        return JsonResponse({
            'success': False,
            'tournaments': [],
            'message': f'Unexpected error: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['GET'])
@permission_classes([])
def get_fft_umpire_data(request, tournament_id):
    """
    API endpoint to get umpire data for a specific tournament
    Returns data that can be used to populate japPhoneNumber field
    """
    try:
        name, email, phone = get_umpire_data(tournament_id)

        return JsonResponse({
            'name': name,
            'email': email,
            'phone': phone
        }, status=status.HTTP_200_OK)

    except Exception as e:
        logger.error(f"Error in get_fft_umpire_data endpoint: {e}")
        return JsonResponse({
            'success': False,
            'umpire': None,
            'japPhoneNumber': None,
            'message': f'Unexpected error: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['GET', 'POST'])
@permission_classes([])
def get_fft_all_tournaments(request):
    """
    API endpoint to get tournaments with smart pagination:
    - page=0: Returns first page + metadata about total pages
    - page>0: Returns all remaining pages concurrently
    """
    try:
        if request.method == 'POST':
            data = request.data
        else:
            data = request.GET

        # Extract parameters
        sorting_option = data.get('sorting_option', 'dateDebut+asc')
        page = int(data.get('page', 0))
        start_date = data.get('start_date')
        end_date = data.get('end_date')
        city = data.get('city', '')
        distance = int(data.get('distance', 15))
        categories = data.getlist('categories') if hasattr(data, 'getlist') else data.get('categories', [])
        levels = data.getlist('levels') if hasattr(data, 'getlist') else data.get('levels', [])
        lat = data.get('lat')
        lng = data.get('lng')
        ages = data.getlist('ages') if hasattr(data, 'getlist') else data.get('ages', [])
        tournament_types = data.getlist('types') if hasattr(data, 'getlist') else data.get('types', [])
        national_cup = data.get('national_cup', 'false').lower() == 'true'
        max_workers = int(data.get('max_workers', 5))

        if page == 0:
            # Handle first page individually
            result = scrape_fft_all_tournaments(
                sorting_option=sorting_option,
                page=0,
                start_date=start_date,
                end_date=end_date,
                city=city,
                distance=distance,
                categories=categories,
                levels=levels,
                lat=lat,
                lng=lng,
                ages=ages,
                tournament_types=tournament_types,
                national_cup=national_cup
            )

            if result:
                tournaments = result.get('tournaments', [])
                total_results = result.get('total_results', 0)
                results_per_page = len(tournaments)

                # Calculate total pages
                if results_per_page > 0:
                    total_pages = (total_results + results_per_page - 1) // results_per_page
                else:
                    total_pages = 1

                return JsonResponse({
                    'success': True,
                    'tournaments': tournaments,
                    'total_results': total_results,
                    'current_count': len(tournaments),
                    'page': 0,
                    'total_pages': total_pages,
                    'has_more_pages': total_pages > 1,
                    'message': f'Successfully scraped page 0: {len(tournaments)} tournaments. Total: {total_results} across {total_pages} pages.'
                }, status=status.HTTP_200_OK)
            else:
                return JsonResponse({
                    'success': False,
                    'tournaments': [],
                    'total_results': 0,
                    'current_count': 0,
                    'page': 0,
                    'total_pages': 0,
                    'has_more_pages': False,
                    'message': 'Failed to scrape first page'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        else:
            # Handle all remaining pages concurrently
            result = scrape_fft_all_tournaments_concurrent(
                sorting_option=sorting_option,
                start_date=start_date,
                end_date=end_date,
                city=city,
                distance=distance,
                categories=categories,
                levels=levels,
                lat=lat,
                lng=lng,
                ages=ages,
                tournament_types=tournament_types,
                national_cup=national_cup,
                max_workers=max_workers
            )

            if result:
                return JsonResponse({
                    'success': True,
                    'tournaments': result.get('tournaments', []),
                    'total_results': result.get('total_results', 0),
                    'current_count': result.get('current_count', 0),
                    'pages_scraped': result.get('pages_scraped', 0),
                    'message': f'Successfully scraped {result.get("pages_scraped", 0)} remaining pages concurrently: {len(result.get("tournaments", []))} tournaments'
                }, status=status.HTTP_200_OK)
            else:
                return JsonResponse({
                    'success': False,
                    'tournaments': [],
                    'total_results': 0,
                    'current_count': 0,
                    'pages_scraped': 0,
                    'message': 'Failed to scrape remaining pages'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    except Exception as e:
        logger.error(f"Error in get_fft_all_tournaments endpoint: {e}")
        return JsonResponse({
            'success': False,
            'tournaments': [],
            'message': f'Unexpected error: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['GET', 'POST'])
@permission_classes([])
def get_fft_federal_clubs(request):
    """
    API endpoint to get federal clubs with filters
    """
    try:
        if request.method == 'POST':
            data = request.data
        else:
            data = request.GET

        # Extract parameters - matching the Swift query parameters
        country = data.get('country', 'fr')
        city = data.get('city', '')
        radius = float(data.get('radius', 15))
        latitude = data.get('lat')
        longitude = data.get('lng')

        # Convert latitude and longitude to float if provided
        if latitude:
            latitude = float(latitude)
        if longitude:
            longitude = float(longitude)

        result = scrape_federal_clubs(
            country=country,
            city=city,
            latitude=latitude,
            longitude=longitude,
            radius=radius
        )

        if result:
            # Return the result directly as JSON (already in correct format)
            return JsonResponse(result, status=status.HTTP_200_OK)
        else:
            # Return error in expected format
            return JsonResponse({
                "typeRecherche": "clubs",
                "nombreResultat": 0,
                "club_markers": []
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    except Exception as e:
        logger.error(f"Error in get_fft_federal_clubs endpoint: {e}")
        return JsonResponse({
            "typeRecherche": "clubs",
            "nombreResultat": 0,
            "club_markers": []
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

### biz
class CRMActivityViewSet(SoftDeleteViewSet):
    queryset = Activity.objects.all()
    serializer_class = ActivitySerializer

class CRMProspectViewSet(SoftDeleteViewSet):
    queryset = Prospect.objects.all()
    serializer_class = ProspectSerializer

class CRMEntityViewSet(SoftDeleteViewSet):
    queryset = Entity.objects.all()
    serializer_class = EntitySerializer
