from snippets.models import Snippet, Tag
from snippets.serializers import SnippetSerializer, TagSerializer
from rest_framework import generics
from django.contrib.auth.models import User
from snippets.serializers import UserSerializer
from rest_framework import permissions
from snippets.permissions import IsOwnerOrReadOnly
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
from rest_framework import renderers
from rest_framework.response import Response
from rest_framework.decorators import detail_route
from rest_framework import viewsets
from rest_framework.renderers import TemplateHTMLRenderer
from django.shortcuts import render
from django.http import HttpResponseRedirect
import datetime
from snippets.models import SnippetForm, TagForm
from django.template import Context, RequestContext, Template, loader
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.views.generic.detail import DetailView
from django.db import models
from django.views.generic.edit import DeleteView, UpdateView, View
from django.core.urlresolvers import reverse_lazy
from django.http import HttpResponse
import json
from django.core import serializers
from django.db.models import F
from django.shortcuts import redirect
from rest_framework import renderers

class SnippetViewSet(viewsets.ModelViewSet):

    renderer_classes = (TemplateHTMLRenderer,)
    template_name = 'base_frontpage.html'
    """
    This viewset automatically provides `list`, `create`, `retrieve`,
    `update` and `destroy` actions.
    Additionally we also provide an extra `highlight` action.
    """
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly,)

    def perform_create(self, serializer):
        template_name = 'snippet_detail.html'
        serializer.save(owner=self.request.user)
        return redirect('/snippets/')

    def retrieve(self, request, pk=None):
        template_name = 'snippet_detail.html'
        # Get the desired snippet
        snippet = Snippet.objects.get(pk=pk)
        snippet_pk = pk
        owner = snippet.owner
        # If user is owner, return true
        if owner == request.user:
            is_owner = True
        else:
            is_owner = False
        # Get the username
        username = None
        # If user is logged in show user name
        if request.user.is_authenticated():
            username = request.user.username
        return render(request, template_name, {'snippet': snippet, 'snippet_pk': snippet_pk, 'is_owner': is_owner, 'username': username})

    def destroy(request, id):
        Snippet.objects.get(id=id).delete()
        return redirect('/snippets/')

    def asjson(self, pk=None):
        # Find the snippet with same pk
        queryset = Snippet.objects.filter(pk=pk)
        # Show only some of the fields
        result_list = list(queryset.values('title','code','tags'))
        # Dump as Json
        return HttpResponse(json.dumps(result_list))

    def newpost(request):
        form = SnippetForm(initial={'owner': request.user})
        # Default user is blank
        username = None
        # If user is logged in show user name
        if request.user.is_authenticated():
            username = request.user.username
        return render(request, 'base_form.html', {'form': form, 'username': username})

    def create(self, request):
        form = SnippetForm(request.POST)
        # If form is correctly filled
        if form.is_valid():
            # Save snippet
            form.save()
            # And return to main page
            return HttpResponseRedirect('/snippets/')
        # Otherwise render form
        return render(request, 'base_form.html', {'form': form})
       
    def list(self, request, format=None):
        # Use Templates
        renderer_classes = (TemplateHTMLRenderer,)
        template_name = 'base_frontpage.html'
        # Query & serialize
        queryset = Snippet.objects.all()
        serializer = SnippetSerializer(queryset, many=True)
        snippets_count = Snippet.objects.count()
        # Tags
        tagset = Tag.objects.order_by('-created')[:10]
        # Show 5 post per page
        queryset_reversed = Snippet.objects.order_by('-created')
        paginator = Paginator(queryset_reversed, 5)
        # Pagination
        page = request.GET.get('page')
        try:
            snippetset = paginator.page(page)
        except PageNotAnInteger:
            snippetset = paginator.page(1)
        except EmptyPage:
            snippetset = paginator.page(paginator.num_pages)
        # Default user is blank
        username = None
        # If user is logged in show user name
        if request.user.is_authenticated():
            username = request.user.username
        # Render result
        return render(request, template_name, {'snippets': snippetset, 'username': username, 'snippets_count': snippets_count, 'tags':tagset})
    
class UserViewSet(viewsets.ReadOnlyModelViewSet):
    """
    This viewset automatically provides `list` and `detail` actions.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer

class SnippetDelete(DeleteView):
    model = Snippet
    success_url = '/snippets/'
    template_name = 'snippet_delete.html'

class SnippetUpdate(UpdateView):
    model = Snippet
    success_url = '/snippets/'
    template_name = 'snippet_update.html'

class TagViewSet(viewsets.ModelViewSet):
    model = Tag
    queryset = Tag.objects.all()
    serializer_class = TagSerializer
    template_name = 'base_form.html'

    def create(self, request):
        form = TagForm(request.POST)
        # If form is correctly filled
        if form.is_valid():
            # Save snippet
            form.save()
            # And return to main page
            return HttpResponseRedirect('/newpost/')
        # Otherwise render form
        return render(request, 'base_form.html', {'form': form})

    def retrieve(self, request, pk=None):
        # Use Templates
        renderer_classes = (TemplateHTMLRenderer,)
        template_name = 'base_frontpage.html'
        # Query & serialize
        queryset = Snippet.objects.all()
        serializer = SnippetSerializer(queryset, many=True)
        snippets_count = Snippet.objects.count()
        # Show 10 tags per page
        tagset = Tag.objects.order_by('-created')[:10]
        # Show 5 post per page
        queryset_reversed = Snippet.objects.filter(tags=pk)
        tags_count = queryset_reversed.count()
        paginator = Paginator(queryset_reversed, 5)
        # Pagination
        page = request.GET.get('page')
        try:
            snippetset = paginator.page(page)
        except PageNotAnInteger:
            snippetset = paginator.page(1)
        except EmptyPage:
            snippetset = paginator.page(paginator.num_pages)
        # Default user is blank
        username = None
        # If user is logged in show user name
        if request.user.is_authenticated():
            username = request.user.username
        # Render result
        return render(request, template_name, {'snippets': snippetset, 'username': username, 'snippets_count': tags_count, 'tags':tagset})

    def list(self, request, format=None):
        # Use Templates
        renderer_classes = (TemplateHTMLRenderer,)
        template_name = 'all_tags.html'
        # Query & serialize
        queryset = Snippet.objects.all()
        serializer = SnippetSerializer(queryset, many=True)
        # Alll the tags
        tagset = Tag.objects.order_by('-created')
        # Default user is blank
        username = None
        # If user is logged in show user name
        if request.user.is_authenticated():
            username = request.user.username
        # Render result
        return render(request, template_name, {'username': username, 'tags': tagset})