from datetime import date, timedelta

from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.db.models.functions import Lower
from django.http import HttpResponse
from django.urls import reverse_lazy
from django.views.generic import (
    CreateView, DeleteView, ListView, TemplateView, UpdateView, View
)

from .forms import ChantEditForm, MembreEditForm
from .models import Agenda, Chant, Document, Membre


class HomeView(TemplateView):
    template_name="index.html"

    def get_context_data(self, **kwargs):
        return {
            **super().get_context_data(**kwargs),
            "items": Agenda.objects.filter(
                date_heure__date__gte=date.today(), statut=Agenda.Statuts.PUBLIC,
            ).order_by("date_heure")[:2],
        }


class ManifestView(TemplateView):
    template_name = "manifest.json"
    content_type = "application/json"


class MediaServeView(LoginRequiredMixin, View):
    subdir = ""

    def get(self, request, *args, **kwargs):
        if request.get_host() == "localhost:8000":
            from django.views.static import serve

            return serve(request, f"{self.subdir}/{kwargs['path']}", document_root=settings.MEDIA_ROOT)
        filepath = settings.MEDIA_ROOT / self.subdir / kwargs["path"]
        return HttpResponse(headers={
            "Content-Type": "application/force-download",
            "Content-Disposition": f'attachment; filename="{filepath.name}"',
            "X-Sendfile": str(filepath).encode("utf-8"),
        })


class PresentationView(TemplateView):
    template_name="presentation.html"

    def get_context_data(self, **kwargs):
        return {
            **super().get_context_data(**kwargs),
            "next_event": Agenda.objects.filter(
                date_heure__date__gte=date.today(), statut=Agenda.Statuts.PUBLIC,
            ).order_by("date_heure").first(),
        }


class AgendaView(ListView):
    model = Agenda
    template_name = "agenda.html"

    def get_queryset(self):
        qs = Agenda.objects.filter(
            date_heure__gt=date.today() - timedelta(days=3),
        ).order_by("date_heure")
        if self.request.user.is_authenticated:
            qs = qs.prefetch_related("programme")
        else:
            qs = qs.filter(statut=Agenda.Statuts.PUBLIC)
        return qs


class MediaView(ListView):
    model = Document
    template_name = "media.html"
    prive = False

    def get_queryset(self):
        return Document.objects.filter(prive=self.prive).order_by("-quand", "titre")

    def get_context_data(self, **kwargs):
        return {
            **super().get_context_data(**kwargs),
            "title": {
                False: "Enregistrements, photos et vidéos de la chorale",
                True: "Documents privés",
            }.get(self.prive)
        }


class EspaceMembresView(LoginRequiredMixin, TemplateView):
    template_name = "membres/index.html"


class ListeMembresView(LoginRequiredMixin, ListView):
    model = Membre
    template_name = "membres/liste.html"

    def get_queryset(self):
        return super().get_queryset().order_by("nom")


class MembreAddView(PermissionRequiredMixin, CreateView):
    model = Membre
    form_class = MembreEditForm
    permission_required = "beesgospel.add_membre"
    template_name = "membres/edit.html"
    success_url = reverse_lazy("liste-membres")


class MembreEditView(PermissionRequiredMixin, UpdateView):
    model = Membre
    form_class = MembreEditForm
    permission_required = "beesgospel.change_membre"
    template_name = "membres/edit.html"
    success_url = reverse_lazy("liste-membres")


class MembreDeleteView(PermissionRequiredMixin, DeleteView):
    model = Membre
    permission_required = "beesgospel.delete_membre"
    success_url = reverse_lazy("liste-membres")

    def form_valid(self, form):
        msg = f"{self.object} a bien été effacé·e de la liste"
        self.object.user.delete()
        messages.success(self.request, msg)
        return super().form_valid(form)


class ListeChantsView(LoginRequiredMixin, ListView):
    model = Chant
    template_name = "membres/liste_chants.html"

    def get_queryset(self):
        return super().get_queryset().prefetch_related("chantdoc_set").order_by(Lower("titre"))


class ChantAddView(PermissionRequiredMixin, CreateView):
    model = Chant
    form_class = ChantEditForm
    permission_required = "beesgospel.add_chant"
    template_name = "membres/chant_edit.html"
    success_url = reverse_lazy("liste-chants")


class ChantEditView(PermissionRequiredMixin, UpdateView):
    model = Chant
    form_class = ChantEditForm
    permission_required = "beesgospel.change_chant"
    template_name = "membres/chant_edit.html"
    success_url = reverse_lazy("liste-chants")


class ChantDeleteView(PermissionRequiredMixin, DeleteView):
    model = Chant
    permission_required = "beesgospel.delete_chant"
    success_url = reverse_lazy("liste-chants")
