from django.shortcuts import render
from django.urls import reverse, reverse_lazy
from django.views import generic
from django.http import JsonResponse, HttpResponseRedirect
from django.utils.html import escape, format_html
from django.contrib.auth import mixins
from django.contrib.auth import decorators
from django.db.models import Q, ObjectDoesNotExist
from django.contrib.messages.views import SuccessMessageMixin
from django.views.decorators.cache import cache_control

from . import ISBN
from .models import *
from .forms import *
from .search import bookSearchQ, strictSearchQ


# Create your views here.
def index(request):
    return render(request, 'BookDatabase/base.html')


class BookSearch(mixins.LoginRequiredMixin, generic.ListView):
    template_name = "BookDatabase/bookList.html"
    context_object_name = "results"
    form_class = SearchForm

    def get_queryset(self):
        if self.request.GET.get('start'):
            start = max(0, int(self.request.GET.get('start')))
        else:
            start = 0
        if self.request.GET.get('q'):
            term = self.request.GET.get('q')
            return Book.objects.filter(bookSearchQ(term))[start:start + 50]
        else:
            return Book.objects.all()[start:start + 50]

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = self.form_class(initial={})
        if self.request.GET.get('start'):
            start = max(0, int(self.request.GET.get('start')))
            if start > 0:
                context['prev'] = max(0, start - 50)
                print(context['prev'])
            context['next'] = start + 50
        else:
            context['next'] = 50
        if len(context['results']) < 50:
            context['next'] = None
        return context

    def post(self, request, *args, **kwargs):
        return HttpResponseRedirect(reverse("BookDatabase:reshelve", request.POST))


class BookUpdate(mixins.PermissionRequiredMixin, generic.UpdateView):
    permission_required = "BookDatabase.change_book"
    fields = ['ISBN', 'Name', 'Author', 'Voice', 'Date', 'Quantity', 'Shelf', 'Type', 'Notes']
    template_name = "BookDatabase/editBook.html"
    model = Book
    success_url = reverse_lazy('BookDatabase:search')

    def get_form(self, form_class=None):
        form = super().get_form(form_class)
        form.fields['Notes'].widget.attrs['rows'] = 5
        return form

    def get_success_message(self, cleaned_data):
        text = format_html('<a href="{}" target="_blank">{}</a> updated successfully',
                           reverse('BookDatabase:editBook', kwargs={'pk': self.object.id}),
                           cleaned_data['Name'])
        return text


class BookCreate(mixins.PermissionRequiredMixin, SuccessMessageMixin, generic.CreateView):
    permission_required = "BookDatabase.add_book"
    fields = ['ISBN', 'Name', 'Author', 'Voice', 'Date', 'Quantity', 'Shelf', 'Type', 'Notes']
    template_name = "BookDatabase/addBook.html"
    model = Book

    def get_success_url(self):
        return reverse_lazy('BookDatabase:add') + "?type="+str(self.object.Type)

    def get_form(self, form_class=None):
        form = super().get_form(form_class)
        form.fields['Type'].initial = self.request.GET.get('type', 1)
        form.fields['Notes'].widget.attrs['rows'] = 5
        return form

    def get_success_message(self, cleaned_data):
        text = format_html('<a href="{}" target="_blank">{}</a> added successfully as new',
                           reverse('BookDatabase:editBook', kwargs={'pk': self.object.id}),
                           cleaned_data['Name'])
        return text


class ShelfSelect(mixins.PermissionRequiredMixin, generic.ListView):
    permission_required = "BookDatabase.change_shelf"
    template_name = "BookDatabase/shelfList.html"
    context_object_name = "results"

    def get_queryset(self):
        return Shelf.objects.all().order_by("ShortDesc")


class Reshelve(mixins.PermissionRequiredMixin, SuccessMessageMixin, generic.CreateView):
    permission_required = ("BookDatabase.change_shelf", "BookDatabase.add_book", "BookDatabase.change_book")
    fields = ['ISBN', 'Name', 'Author', 'Date', 'Voice', 'Quantity', 'Shelf', 'Type', 'Notes']
    template_name = "BookDatabase/shelfEdit.html"
    model = Book

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['shelf_name']=Shelf.objects.filter(pk=self.kwargs['shelf_id']).values()[0]['Description']
        print(context)
        return context

    def get_success_url(self):
        return reverse('BookDatabase:reshelve', kwargs={'shelf_id': self.kwargs['shelf_id']})+ "?type="+str(self.object.Type)

    def get_success_message(self, cleaned_data):
        text = format_html('<a href="{}" target="_blank"'
                           '>{}</a> added to shelf successfully as new',
                           reverse('BookDatabase:editBook', kwargs={'pk': self.object.id}),
                           cleaned_data['Name'])
        return text

    def get_form(self, form_class=None):
        form = super().get_form(form_class)
        form.initial['Shelf'] = self.kwargs['shelf_id']
        form.fields['Shelf'].disabled = True
        form.fields['Type'].initial = self.request.GET.get('type', 1)
        form.fields['Notes'].widget.attrs['rows'] = 5
        return form


class FullReshelve(mixins.PermissionRequiredMixin, generic.TemplateView):
    permission_required = ("BookDatabase.change_shelf")
    template_name = "BookDatabase/confirmFull.html"

    def post(self, request, shelf_id=None):
        Book.objects.filter(Shelf__id=shelf_id).update(Shelf=None)
        return HttpResponseRedirect(reverse('BookDatabase:reshelve', kwargs={'shelf_id': shelf_id}))


@decorators.login_required
def getISBN(request):
    term = str(request.GET.get("search"))
    dtls = ISBN.ISBNlookup(term)
    print(term, dtls)
    if not dtls:
        dtls = {}
    return JsonResponse(dtls)


@decorators.login_required
def search(request):
    term = str(request.GET.get("search"))
    strict = request.GET.get("strict", 'false').lower() == "true"
    print(strict)
    if strict:
        strictQ = Book.objects.filter(strictSearchQ(term))
        if strictQ.count() > 0:
            return JsonResponse({"books": strictQ.values()[0:10:1]})
    books = Book.objects.filter(bookSearchQ(term)).values()[0:10:1]
    dtls = {"books": books}
    return JsonResponse(dtls)


@decorators.permission_required("BookDatabase.change_shelf")
def missing(request, book_id=0):
    book = Book.objects.get(pk=book_id)
    book.Shelf = None
    book.save()
    return HttpResponseRedirect(reverse("BookDatabase:search"))


@decorators.permission_required(("BookDatabase.change_book", "BookDatabase.change_shelf"))
def move(request):
    dtls = {}
    try:
        id = int(request.GET.get('id'))
        shelf = int(request.GET.get('shelf'))
        try:
            book = Book.objects.get(pk=id)
            if book.Shelf is not None:
                oldShelf = book.Shelf.Description
            else:
                oldShelf = None
            book.Shelf = Shelf.objects.get(pk=shelf)
            book.save()
            print(book)
            dtls['success'] = True
            dtls['book'] = Book.objects.filter(pk=id).values()[0]
            dtls['oldShelf'] = oldShelf
        except ObjectDoesNotExist:
            dtls['error'] = "Shelf not found"
            dtls['success'] = False
        except RuntimeError:
            dtls['error'] = "Unknown Error"
            dtls['success'] = False
    except (KeyError, TypeError):
        dtls['error'] = "id or shelf not present"
        dtls['success'] = False
    return JsonResponse(dtls)

@cache_control(public=True, max_age=31536000)
def isbnSearchJS(request):
    return render(request, "BookDatabase/isbnSearch.js", content_type='application/javascript')

@cache_control(public=True, max_age=31536000)
def isbnLookupJS(request):
    return render(request, "BookDatabase/isbnLookupSearch.js", content_type='application/javascript')
