
from copy import deepcopy
from datetime import datetime
import json

from django.contrib.auth import get_user_model
from django.http import HttpResponse
from django.utils.dateparse import parse_datetime
import requests
from rest_framework import status
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView

from ammico.models import Book, Slide
from ammico.serializers import BookSerializer, SlideSerializer
from settings import URL_JAMESPOT


#from django.contrib.auth import login, logout
User = get_user_model()

def populateVisit(user):
    # send request with usermail to get the visits of this user and add it to the database 
    #r = requests.get('http://fui-ammico.jamespot.pro/api/api.php?&k=6c8bfcea247e8a5841288269887d88f0&d=2016-01-31&m=EXT-IRI&v=2.0&f=get&o=article&idArticle=169')

    #simulate the request
    params = {'o': 'article', 'f': 'list', 'idUser': user.idUser} 
    r = requests.get(URL_JAMESPOT, params=params)
    visits = json.loads(r.content.decode('utf-8'))
    
    for visit in visits['VAL']:
        params = {'o' : 'article', 'f' : 'get', 'idArticle' : visit['idArticle']}
        r = requests.get(URL_JAMESPOT, params=params)
        visitInfo = json.loads(r.content.decode('utf-8'))['VAL']
        
        
        if (not Book.objects.filter(idArticle=visit['idArticle']).exists()):
            book = Book.objects.create(
                user=user,
                idArticle=visitInfo['idArticle'],
                title = visitInfo['title'],
                description = visitInfo['description'],
                image = visitInfo['image'],
                date = parse_datetime(visitInfo['dateCreation'])
            )
            populateSlide(json.loads(visitInfo['steps']), book)

def populateSlide(steps, book):
    for step in steps:
        if (step['stop'] != None and step['stop'] != ''):
            
            if 'comment' in step:
                description = step['comment']
            else:
                description = ""
            
            Slide.objects.update_or_create(
                book=book,
                idStop=step['stop'],
                defaults={
                    'description' : description,
                    'date' : parse_datetime(str(datetime.strptime(step['DATE'] + " " + step['TIME'], "%d/%m/%Y %H:%M:%S")))
                }
            )
            
class PublicBooks(APIView):
    """
    Send back published books
    """
    
    authentication_classes = (TokenAuthentication,)
    permission_classes = (AllowAny,)

    def get(self, request):
        """
        Return a list of all Books.
        """
        books = Book.objects.filter(public=True)
        serializer = BookSerializer(books, many=True)
        return Response(serializer.data)
            
class ListBooks(APIView):
    """
    Views to list all books.
    """
    
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get(self, request):
        """
        Return a list of all Books.
        """
        books = Book.objects.filter(user = request.user.id)
        serializer = BookSerializer(books, many=True)
        return Response(serializer.data)
    
    def post(self, request):
        """
        Add a Book
        """
        
        DEFAULTS = {
            "user":request.user.id,
        }
        
        if ('idParent' in request.data):
            try:
                book = Book.objects.get(user = request.user.id, id=request.data['idParent'])
            except Book.DoesNotExist:
                return Response(status=status.HTTP_400_BAD_REQUEST)
            new_book = deepcopy(book)
            new_book.title = request.data['title']
            new_book.idArticle = None
            new_book.parent_visit = book
            new_book.id = None
            new_book.save()
            for i in book.slides.all():
                print (i)
                new_slide = deepcopy(i)
                new_slide.id = None
                new_slide.book = new_book
                new_slide.save()
            serializer = BookSerializer(new_book)
            return Response(serializer.data)
        else:
            request.data.update(DEFAULTS)
            serializer = BookSerializer(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 InfoBook(APIView):
    """
    View relative to a book
    """
    
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get(self, request, idBook):
        """
        Get information from a book
        """
        try:
            book = Book.objects.get(user = request.user.id, id=idBook)
        except Book.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        
        serializer = BookSerializer(book)
        return Response(serializer.data)
    
    def put(self, request, idBook):
        """
        update a Book
        """
        try:
            book = Book.objects.get(user = request.user.id, id=idBook)
        except Book.DoesNotExist:
            return Response(status=status.HTTP_204_NO_CONTENT)
        
        if (book.idArticle):
            return Response(status=status.HTTP_403_FORBIDDEN)
        
        serializer = BookSerializer(book, 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)
    
    def delete(self, request, idBook):
        """
        delete a book
        """
        try:
            book = Book.objects.get(user = request.user.id, id = idBook)
        except Book.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        
        if (book.idArticle):
            return Response(status=status.HTTP_403_FORBIDDEN)
        
        book.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
    

class SlidesOrder(APIView):
    """
    Manage Slides order
    """
    
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get(self, request, idBook):
        """
        Get slides order
        """
        try:
            book = Book.objects.get(user = request.user.id, id=idBook)
        except Book.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        response = {}
        response["order"] = book.get_slide_order()
        return Response(response)
    
    def post(self, request, idBook):
        """
        Set Slides order
        """
        try:
            book = Book.objects.get(user = request.user.id, id=idBook)
        except Book.DoesNotExist:
            return Response(status=status.HTTP_204_NO_CONTENT)
        
        if (book.idArticle):
            return Response(status=status.HTTP_403_FORBIDDEN)
        
        book.set_slide_order(request.data['order'])
        return Response(status=status.HTTP_200_OK)

class ListSlides(APIView):
    """
    Views to list all slides.
    """
    
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get(self, request):
        """
        Return a list of slide
        """
        if 'idBook' in request.GET:
            if 'limit' in request.GET:
                limit = int(request.GET['limit'])
            else:
                limit= None;
            slides = Slide.objects.filter(book__user = request.user.id, book = request.GET['idBook'])[:limit]
        else:
            slides = Slide.objects.filter(book__user = request.user.id)
    
        serializer = SlideSerializer(slides, many=True)
        return Response(serializer.data)
    
    def post(self, request):
        """
        Add a slide
        """
        print (request.data)
        if 'book' in request.data:
            try:
                book = Book.objects.get(user = request.user.id, id=request.data['book'])
            except Book.DoesNotExist:
                return Response(status=status.HTTP_204_NO_CONTENT)
            if (book.idArticle):
                return Response(status=status.HTTP_403_FORBIDDEN)
            
        serializer = SlideSerializer(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 InfoSlide(APIView):
    """
    View to get slide detailed informations.
    """
    
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get(self, request, idSlide):
        """
        Get information from a slide
        """
        try:
            slide = Slide.objects.get(book__user = request.user.id, id=idSlide)
        except Slide.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        
        serializer = SlideSerializer(slide)
        return Response(serializer.data)
    
    def put(self, request, idSlide):
        """
        Update slide information
        """
        try:
            slide = Slide.objects.get(book__user = request.user.id, id=idSlide)
        except Slide.DoesNotExist:
            return HttpResponse(status=status.HTTP_204_NO_CONTENT)
        
        if (slide.book.idArticle):
            return Response(status=status.HTTP_403_FORBIDDEN)
        
        serializer = SlideSerializer(slide, 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)
    
    def delete(self, request, idSlide):
        """
        Delete a slide
        """
        try:
            slide = Slide.objects.get(book__user = request.user.id, id = idSlide)
        except Slide.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        
        if (slide.book.idArticle):
            return Response(status=status.HTTP_403_FORBIDDEN)
        
        slide.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)