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

from rest_framework import viewsets, permissions
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

from shared.discord import send_discord_log_message

@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 TournamentViewSet(SoftDeleteViewSet):
    queryset = Tournament.objects.all()
    serializer_class = TournamentSerializer

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

    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
