from django.shortcuts import HttpResponse, redirect
from django.urls import reverse
from django.views.generic import ListView, RedirectView
from django.views.generic.edit import FormMixin

from iconolab.conf import settings
from iconolab.models import Collection
from iconolab.search_indexes.forms import IconolabSearchForm

import logging

logger = logging.getLogger(__name__)


class IconolabSearchView(ListView):

    template_name = "search/default_search.html"
    templates_map = {
        "images": "search/image_search.html",
        "annotations": "search/annotation_search.html"
    }
    paginate_by = settings.ICONOLAB_SEARCH_PAGE_SIZE

    def get_template_names(self):
        try:
            model_type = self.kwargs.get('model_type', None)
            template = IconolabSearchView.templates_map[model_type]
        except KeyError:
            template = IconolabSearchView.template_name
        finally:
            return [template]

    def complete_url(self, url, tags_only):
        query = self.request.GET.get("q", None)
        page = self.request.GET.get("page", None)

        queryargs = []
        query_string = ""

        if query is not None:
            queryargs.append("q=" + query)

        if page is not None:
            queryargs.append("page=" + page)

        if tags_only:
            queryargs.append("tags=1")

        if len(queryargs):
            query_string = "&".join(queryargs)
            url += "?" + query_string

        return url

    def get(self, request, *args, **kwargs):

        self.model_type = request.GET.get('model_type', None)
        self.paginate_by = request.GET.get(
            'perpage', settings.ICONOLAB_SEARCH_PAGE_SIZE)
        self.collection_name = self.kwargs.get('collection_name', None)

        tags_only = False
        if (self.model_type == 'tags'):
            self.model_type = 'annotations'
            tags_only = True

        if self.model_type is not None:
            if self.collection_name is None:
                # redirect to all_model_type
                redirect_url = reverse('search_indexes:model_search', kwargs={
                                       'model_type': self.model_type})
                return redirect(self.complete_url(redirect_url, tags_only))
            else:
                redirect_url = reverse('search_indexes:collection_with_model_search', kwargs={
                                       'collection_name': self.collection_name, 'model_type': self.model_type})
                return redirect(self.complete_url(redirect_url, tags_only))
        else:
            has_error, redirectView = self.check_kwargs(**kwargs)
            if has_error:
                return redirectView(request)
            return super().get(request, *args, **kwargs)


    def check_kwargs(self, **kwargs):
        self.collection = None
        if self.collection_name:
            self.collection = Collection.objects.filter(name=self.collection_name).first()
        if not self.collection_name or self.collection:
            return (False, None)
        else:
            return (True, RedirectView.as_view(url=reverse('404error')))

        result = (False, None)
        try:
            collection_name = kwargs.get('collection_name', None)
            if collection_name is None:
                return result
            collection = Collection.objects.get(name=kwargs.get('collection_name'))
        except Collection.DoesNotExist:
            result = (True, RedirectView.as_view(url=reverse('404error')))
        finally:
            return result


    def get_form(self, initial=None):

        form_kwargs = {
            'collection_name': self.kwargs.get('collection_name', None),
            'model_type': self.kwargs.get('model_type', None)
        }

        if initial is not None:
            form_kwargs['initial'] : initial
        else:
            form_kwargs['data'] = self.request.GET
        return IconolabSearchForm(**form_kwargs)

    def get_queryset(self):
        form = self.get_form()
        if form.is_valid():
            return form.search()
        else:
            return []

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['collection_name'] = self.collection_name
        context['collection'] = self.collection
        context['form'] = self.get_form(initial=self.request.GET)

        return context
