from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from . import models, serializers
from mingflix.notifications import views as notification_view
from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter
from rest_auth.registration.views import SocialLoginView


class Search(APIView):

    def get(self, request, format=None):

        username = request.query_params.get('username', None)

        if username is not None:

            users = models.User.objects.filter(username__icontains=username)

            serializer = serializers.UserListSerializer(users, many=True, context={"request": request})

            return Response(data=serializer.data, status=status.HTTP_200_OK)

        else:

            return Response(status=status.HTTP_400_BAD_REQUEST)


class StreamOn(APIView):

    def put(self, request, format=None):

        user = request.user

        user.is_streaming = True
        user.save()

        return Response(status=status.HTTP_200_OK)


class StreamOff(APIView):

    def put(self, request, format=None):

        user = request.user

        user.is_streaming = False
        user.save()

        return Response(status=status.HTTP_200_OK)


class FollowUser(APIView):

    def post(self, request, user_id, format=None):

        user = request.user

        try:
            user_to_follow = models.User.objects.get(id=user_id)
        except models.User.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

        user.following.add(user_to_follow)
        user_to_follow.followers.add(user)

        user.save()
        user_to_follow.save()
        notification_view.create_notification(user, user_to_follow, 'follow')

        return Response(status=status.HTTP_200_OK)


class UnFollowUser(APIView):

    def post(self, request, user_id, format=None):

        user = request.user

        try:
            user_to_follow = models.User.objects.get(id=user_id)
        except models.User.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

        user.following.remove(user_to_follow)
        user_to_follow.followers.remove(user)

        user.save()
        user_to_follow.save()

        return Response(status=status.HTTP_200_OK)


class UserProfile(APIView):

    def get_user(self, username):

        try:
            found_user = models.User.objects.get(username=username)
            return found_user
        except models.User.DoesNotExist:
            return None

    def get(self, request, username, format=None):

        found_user = self.get_user(username)

        if found_user is None:

            return Response(status=status.HTTP_404_NOT_FOUND)

        serializer = serializers.UserProfileSerializer(found_user, context={"request": request})

        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def put(self, request, username, format=None):

        user = request.user

        found_user = self.get_user(username)

        if found_user is None:

            return Response(status=status.HTTP_404_NOT_FOUND)

        elif found_user.username != user.username:

            return Response(status=status.HTTP_400_BAD_REQUEST)

        else:

            serializer = serializers.UserProfileSerializer(
                found_user, data=request.data, partial=True, context={"request": request})

            if serializer.is_valid():

                serializer.save()

                return Response(data=serializer.data, status=status.HTTP_200_OK)

            else:

                return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class UserChannel(APIView):

    def get_channel(self, username):

        try:
            found_channel = models.Channel.objects.get(creator__username=username)
            return found_channel
        except models.Channel.DoesNotExist:
            return None

    def get(self, request, username, format=None):

        found_channel = self.get_channel(username)

        if found_channel is None:

            return Response(status=status.HTTP_404_NOT_FOUND)

        serializer = serializers.ChannelSerializer(found_channel)

        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def post(self, request, username, format=None):

        user = request.user

        exist_channel = self.get_channel(username)

        if exist_channel is None:

            serializer = serializers.ChannelSerializer(data=request.data)

            if serializer.is_valid():

                serializer.save(creator=user)

                return Response(data=serializer.data, status=status.HTTP_201_CREATED)

            else:
                return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        else:

            return Response(status=status.HTTP_302_FOUND)

    def put(self, request, username, format=None):

        user = request.user

        found_channel = self.get_channel(username)

        if found_channel is None:

            return Response(status=status.HTTP_404_NOT_FOUND)

        elif found_channel.creator.username != user.username:

            return Response(status=status.HTTP_400_BAD_REQUEST)

        else:

            serializer = serializers.ChannelSerializer(found_channel, data=request.data, partial=True)

            if serializer.is_valid():

                serializer.save(creator=user)

                return Response(data=serializer.data, status=status.HTTP_200_OK)

            else:

                return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class UserFollowers(APIView):

    def get(self, request, username, format=None):

        try:
            found_user = models.User.objects.get(username=username)
        except models.User.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

        user_followers = found_user.followers.all()

        serializer = serializers.UserListSerializer(user_followers, many=True, context={"request": request})

        return Response(data=serializer.data, status=status.HTTP_200_OK)


class UserFollowing(APIView):

    def get(self, request, username, format=None):

        try:
            found_user = models.User.objects.get(username=username)
        except models.User.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

        user_following = found_user.following.all()

        serializer = serializers.UserListSerializer(user_following, many=True, context={"request": request})

        return Response(data=serializer.data, status=status.HTTP_200_OK)


class ChangePassword(APIView):

    def put(self, request, username, format=None):

        user = request.user

        if user.username == username:

            current_password = request.data.get('current_password', None)

            if current_password is not None:

                passwords_match = user.check_password(current_password)

                if passwords_match:

                    new_password = request.data.get('new_password', None)

                    if new_password is not None:

                        user.set_password(<PASSWORD>password)

                        user.save()

                        return Response(status.HTTP_200_OK)

                    else:
                        return Response(status=status.HTTP_400_BAD_REQUEST)
                else:
                    return Response(status=status.HTTP_400_BAD_REQUEST)
            else:
                return Response(status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST)


class FacebookLogin(SocialLoginView):
    adapter_class = FacebookOAuth2Adapter

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from . import models, serializers
from mingflix.notifications import views as notification_view
from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter
from rest_auth.registration.views import SocialLoginView


class Search(APIView):

    def get(self, request, format=None):

        username = request.query_params.get('username', None)

        if username is not None:

            users = models.User.objects.filter(username__icontains=username)

            serializer = serializers.UserListSerializer(users, many=True, context={"request": request})

            return Response(data=serializer.data, status=status.HTTP_200_OK)

        else:

            return Response(status=status.HTTP_400_BAD_REQUEST)


class StreamOn(APIView):

    def put(self, request, format=None):

        user = request.user

        user.is_streaming = True
        user.save()

        return Response(status=status.HTTP_200_OK)


class StreamOff(APIView):

    def put(self, request, format=None):

        user = request.user

        user.is_streaming = False
        user.save()

        return Response(status=status.HTTP_200_OK)


class FollowUser(APIView):

    def post(self, request, user_id, format=None):

        user = request.user

        try:
            user_to_follow = models.User.objects.get(id=user_id)
        except models.User.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

        user.following.add(user_to_follow)
        user_to_follow.followers.add(user)

        user.save()
        user_to_follow.save()
        notification_view.create_notification(user, user_to_follow, 'follow')

        return Response(status=status.HTTP_200_OK)


class UnFollowUser(APIView):

    def post(self, request, user_id, format=None):

        user = request.user

        try:
            user_to_follow = models.User.objects.get(id=user_id)
        except models.User.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

        user.following.remove(user_to_follow)
        user_to_follow.followers.remove(user)

        user.save()
        user_to_follow.save()

        return Response(status=status.HTTP_200_OK)


class UserProfile(APIView):

    def get_user(self, username):

        try:
            found_user = models.User.objects.get(username=username)
            return found_user
        except models.User.DoesNotExist:
            return None

    def get(self, request, username, format=None):

        found_user = self.get_user(username)

        if found_user is None:

            return Response(status=status.HTTP_404_NOT_FOUND)

        serializer = serializers.UserProfileSerializer(found_user, context={"request": request})

        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def put(self, request, username, format=None):

        user = request.user

        found_user = self.get_user(username)

        if found_user is None:

            return Response(status=status.HTTP_404_NOT_FOUND)

        elif found_user.username != user.username:

            return Response(status=status.HTTP_400_BAD_REQUEST)

        else:

            serializer = serializers.UserProfileSerializer(
                found_user, data=request.data, partial=True, context={"request": request})

            if serializer.is_valid():

                serializer.save()

                return Response(data=serializer.data, status=status.HTTP_200_OK)

            else:

                return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class UserChannel(APIView):

    def get_channel(self, username):

        try:
            found_channel = models.Channel.objects.get(creator__username=username)
            return found_channel
        except models.Channel.DoesNotExist:
            return None

    def get(self, request, username, format=None):

        found_channel = self.get_channel(username)

        if found_channel is None:

            return Response(status=status.HTTP_404_NOT_FOUND)

        serializer = serializers.ChannelSerializer(found_channel)

        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def post(self, request, username, format=None):

        user = request.user

        exist_channel = self.get_channel(username)

        if exist_channel is None:

            serializer = serializers.ChannelSerializer(data=request.data)

            if serializer.is_valid():

                serializer.save(creator=user)

                return Response(data=serializer.data, status=status.HTTP_201_CREATED)

            else:
                return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        else:

            return Response(status=status.HTTP_302_FOUND)

    def put(self, request, username, format=None):

        user = request.user

        found_channel = self.get_channel(username)

        if found_channel is None:

            return Response(status=status.HTTP_404_NOT_FOUND)

        elif found_channel.creator.username != user.username:

            return Response(status=status.HTTP_400_BAD_REQUEST)

        else:

            serializer = serializers.ChannelSerializer(found_channel, data=request.data, partial=True)

            if serializer.is_valid():

                serializer.save(creator=user)

                return Response(data=serializer.data, status=status.HTTP_200_OK)

            else:

                return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class UserFollowers(APIView):

    def get(self, request, username, format=None):

        try:
            found_user = models.User.objects.get(username=username)
        except models.User.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

        user_followers = found_user.followers.all()

        serializer = serializers.UserListSerializer(user_followers, many=True, context={"request": request})

        return Response(data=serializer.data, status=status.HTTP_200_OK)


class UserFollowing(APIView):

    def get(self, request, username, format=None):

        try:
            found_user = models.User.objects.get(username=username)
        except models.User.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

        user_following = found_user.following.all()

        serializer = serializers.UserListSerializer(user_following, many=True, context={"request": request})

        return Response(data=serializer.data, status=status.HTTP_200_OK)


class ChangePassword(APIView):

    def put(self, request, username, format=None):

        user = request.user

        if user.username == username:

            current_password = request.data.get('current_password', None)

            if current_password is not None:

                passwords_match = user.check_password(current_password)

                if passwords_match:

                    new_password = request.data.get('new_password', None)

                    if new_password is not None:

                        user.set_password(<PASSWORD>password)

                        user.save()

                        return Response(status.HTTP_200_OK)

                    else:
                        return Response(status=status.HTTP_400_BAD_REQUEST)
                else:
                    return Response(status=status.HTTP_400_BAD_REQUEST)
            else:
                return Response(status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST)


class FacebookLogin(SocialLoginView):
    adapter_class = FacebookOAuth2Adapter
