from django.http import HttpResponseBadRequest, HttpResponseForbidden, HttpResponseNotAllowed, HttpResponseNotFound, HttpResponseServerError
from django.shortcuts import redirect
from django.utils import translation
from django.views.generic.base import View
from django.views.generic import TemplateView, ListView
from django.views import View
from django.shortcuts import render
from django.views.generic.list import QuerySet
from django.db.models import Q
from django.views.static import loader
from requests import request

from .forms import MainSearchForm
from .models import Link, Searchable

from abc import ABC

import logging
logger = logging.getLogger(__name__)


class SearchableView(View, ABC):
    """
    This abstract view implements some traits of views that should show up
    in the main search
    """
    title: str
    subtitle: str
    desc: str
    date: None = None
    keywords: list[str]


class Index(TemplateView, SearchableView):
    """
    The index page of the gawa app.

    Utilizes a generic view, because I will do so for all views, 
    a regular view function would suffice.
    """

    template_name: str = "start/index.html"


class Professional(TemplateView, SearchableView):
    """
    Professional informations that might interest a professional employer
    """
    # TODO
    template_name: str = "start/legalinfo.html"


class LegalInfo(TemplateView, SearchableView):
    """
    Legal info that the german authorities want.
    """
    # TODO
    template_name: str = "start/legalinfo.html"


class ActivateLanguage(View):
    """
    Set the language to whatever
    """
    language_code = ''
    redirect_to = ''

    def get(self, request, *args, **kwargs):
        self.redirect_to = request.META.get('HTTP_REFERER')
        self.language_code = kwargs.get('language_code')
        translation.activate(self.language_code)
        request.session[translation.LANGUAGE_SESSION_KEY] = self.language_code
        return redirect(self.redirect_to)


class MainSearch(ListView):
    """
    Search for anything.
    """

    model = Searchable
    object_list = []    # this is only declaration, the view breaks without it.
    template_name: str = "start/search.html"

    def get_queryset(self) -> QuerySet:
        search = self.request.GET.get("search")
        object_list = Searchable.objects.filter(
            Q(title_de__icontains=search) | Q(title_en__icontains=search) |
            Q(subtitle_de__icontains=search) | Q(subtitle_en__icontains=search) |
            Q(desc_de__icontains=search) | Q(desc_en__icontains=search) |
            Q(public=True)
        )
        object_list = object_list.filter(public=True)
        return object_list

    def get(self, request, *args, **kwargs):
        form = MainSearchForm(request.GET)
        if not form.is_valid():
            return render(request, "errors/bad_request.html")
        return super().get(request, *args, **kwargs)


class Links(ListView):
    """
    This View contains links to various interesting sites.
    """
    model = Link
    context_object_name = "links"
    template_name = "start/links.html"

    def get_queryset(self) -> QuerySet:
        object_list = Link.objects.filter(
            status=True, public=True, personal=False
        )
        return object_list

    def get_queryset_personal_links(self) -> QuerySet:
        object_list = Link.objects.filter(
            status=True, public=True, personal=True
        )
        return object_list

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(object_list=object_list, **kwargs)
        context['personal_links'] = self.get_queryset_personal_links()
        return context
