from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status, permissions
from django.shortcuts import get_object_or_404
from .models import CarouselBanner, Movie, Category, Series, Banner, Tag, AdUnit
from .serializers import (
    CarouselBannerSerializer, MovieRequestSerializer, MovieSerializer, CategorySerializer, 
    RegisterSerializer, SeriesSerializer, BannerSerializer, AdUnitSerializer,PasswordResetSerializer
)
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from django.contrib.auth.hashers import make_password

from rest_framework.permissions import IsAuthenticatedOrReadOnly

class AdUnitListView(APIView):
    permission_classes = [IsAuthenticatedOrReadOnly]

    def get(self, request):
        platform = request.query_params.get('platform', None)
        ad_type = request.query_params.get('ad_type', None)
        
        ad_units = AdUnit.objects.filter(is_active=True)
        if platform:
            ad_units = ad_units.filter(platform=platform)
        if ad_type:
            ad_units = ad_units.filter(ad_type=ad_type)
        
        serializer = AdUnitSerializer(ad_units, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)    

class CategoryListView(APIView):
    def get(self, request):
        categories = Category.objects.all()
        serializer = CategorySerializer(categories, many=True)
        return Response(serializer.data)

class MoviesByCategoryView(APIView):
    def get(self, request, category_name):
        category = get_object_or_404(Category, name__iexact=category_name)
        movies = Movie.objects.filter(category=category)
        serializer = MovieSerializer(movies, many=True)
        return Response({
            'category': category.name,
            'movies': serializer.data
        })

class SeriesByCategoryView(APIView):
    def get(self, request, category_name):
        category = get_object_or_404(Category, name__iexact=category_name)
        series = Series.objects.filter(category=category)
        serializer = SeriesSerializer(series, many=True)
        return Response({
            'category': category.name,
            'series': serializer.data
        })

class MovieListCreateView(APIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]

    def get(self, request):
        movies = Movie.objects.all()
        serializer = MovieSerializer(movies, many=True)
        return Response(serializer.data)

    def post(self, request):
        if not request.user.is_staff:
            return Response({'error': 'Only admins can upload movies'}, status=status.HTTP_403_FORBIDDEN)

        serializer = MovieSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class SeriesListView(APIView):
    def get(self, request):
        series = Series.objects.all()
        serializer = SeriesSerializer(series, many=True)
        return Response(serializer.data)

class MovieDetailView(APIView):
    def get(self, request, pk):
        movie = get_object_or_404(Movie, pk=pk)
        serializer = MovieSerializer(movie)
        return Response(serializer.data)

class SeriesDetailView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, pk):
        series = get_object_or_404(Series, pk=pk)
        serializer = SeriesSerializer(series)
        return Response(serializer.data)

class BannerListView(APIView):
    def get(self, request):
        banners = Banner.objects.filter(is_active=True)
        serializer = BannerSerializer(banners, many=True)
        return Response(serializer.data)

class SeriesByCategoryAndTagView(APIView):
    def get(self, request, category_name, tag_name):
        category = get_object_or_404(Category, name__iexact=category_name)
        tag = get_object_or_404(Tag, name__iexact=tag_name)
        series = Series.objects.filter(category=category, tags=tag)
        serializer = SeriesSerializer(series, many=True)
        return Response(serializer.data)
    
class MoviesByCategoryAndTagView(APIView):
    def get(self, request, category_name, tag_name):
        category = get_object_or_404(Category, name__iexact=category_name)
        tag = get_object_or_404(Tag, name__iexact=tag_name)
        movies = Movie.objects.filter(category=category, tags=tag)
        serializer = MovieSerializer(movies, many=True)
        return Response(serializer.data)
    
class MoviesByTagAPIView(APIView):
    def get(self, request, tag_name):
        tag = get_object_or_404(Tag, name__iexact=tag_name)
        movies = Movie.objects.filter(tags=tag)
        series = Series.objects.filter(tags=tag)
        
        movies_serializer = MovieSerializer(movies, many=True)
        series_serializer = SeriesSerializer(series, many=True)

        return Response({
            "tag": tag_name,
            "movies": movies_serializer.data,
            "series": series_serializer.data
        })
    
class TagsAPIView(APIView):
    def get(self, request):
        tags = Tag.objects.all()
        tags_with_movies_series = []
        for tag in tags:
            movies = MovieSerializer(tag.movies.all(), many=True).data
            series = SeriesSerializer(tag.series.all(), many=True).data
            tags_with_movies_series.append({
                "tag": tag.name,
                "movies": movies,
                "series": series,
            })
        return Response(tags_with_movies_series, status=status.HTTP_200_OK)

class CarouselBannerListView(APIView):
    def get(self, request):
        banners = CarouselBanner.objects.filter(is_active=True)
        serializer = CarouselBannerSerializer(banners, many=True)
        return Response(serializer.data)
    
class SearchView(APIView):
    def get(self, request):
        query = request.query_params.get('q', '').strip()
        if not query:
            return Response({"error": "Query parameter 'q' is required."}, status=status.HTTP_400_BAD_REQUEST)

        movies = Movie.objects.filter(title__icontains=query)
        series = Series.objects.filter(title__icontains=query)

        movie_data = MovieSerializer(movies, many=True).data
        series_data = SeriesSerializer(series, many=True).data

        return Response({
            "movies": movie_data,
            "series": series_data,
        }, status=status.HTTP_200_OK)
    
class MovieRequestView(APIView):
    def post(self, request):
        serializer = MovieRequestSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({"message": "Movie request submitted successfully."}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
class RegisterView(APIView):
    def post(self, request):
        serializer = RegisterSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            refresh = RefreshToken.for_user(user)
            access_token = str(refresh.access_token)
            return Response({
                "message": "User registered successfully.",
                "access_token": access_token,
                "refresh_token": str(refresh)
            }, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

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

        user = authenticate(username=username, password=password)
        if user is not None:
            refresh = RefreshToken.for_user(user)
            return Response({
                "message": "Login successful",
                "access_token": str(refresh.access_token),
                "refresh_token": str(refresh)
            }, status=status.HTTP_200_OK)
        return Response({"error": "Invalid credentials"}, status=status.HTTP_400_BAD_REQUEST)
        
class PasswordResetView(APIView):
    def post(self, request):
        serializer = PasswordResetSerializer(data=request.data)
        if serializer.is_valid():
            username_or_email = serializer.validated_data['username_or_email']
            new_password = serializer.validated_data['new_password']
            
            # Try to find user by username or email
            try:
                user = User.objects.get(username=username_or_email)
            except User.DoesNotExist:
                try:
                    user = User.objects.get(email=username_or_email)
                except User.DoesNotExist:
                    return Response({"error": "User with this username or email does not exist."}, status=status.HTTP_400_BAD_REQUEST)

            # Update the user's password
            user.password = make_password(new_password)
            user.save()
            return Response({"message": "Password reset successfully."}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)