import bleach
import os

from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import redirect
from django.db.models import F
from django.views.generic import DetailView

from tickets.forms import TicketForm
from tickets.models import Attachment, Comment, Ticket
from tickets.utils import UserCanReadTicketMixin


class TicketDetailView(LoginRequiredMixin, UserCanReadTicketMixin, DetailView):
    model = Ticket
    template_name = 'tickets/ticket_detail.html'
    context_object_name = 'ticket'

    def get_queryset(self):
        queryset = super().get_queryset()
        return queryset.select_related("created_by", "assigned_to")

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = TicketForm(self.request.user, instance=self.object)
        context['comment_list'] = Comment.objects.filter(ticket=self.object.pk).order_by("-date").annotate(
            author_username=F("author__username"), author_email=F("author__email")
        )
        context['attachments'] = Attachment.objects.filter(ticket=self.object.pk).select_related("added_by")
        
        # List with statuses codes & their names
        available_statuses_with_names = []
        available_statuses = self.object.get_available_statuses()
        if available_statuses:
            for status_code in available_statuses:
                status_name = Ticket.TICKET_STATUSES_NAMES.get(status_code)
                available_statuses_with_names.append([status_code, status_name])
        context["available_statuses"] = available_statuses_with_names

        return context

    def post(self, request, *args, **kwargs):
        ticket = self.get_object()

        if request.POST.get("ticket-status"):
            status = request.POST.get("ticket-status")
            
            if int(status) in ticket.get_available_statuses():
                ticket.status = int(status)
                ticket.save()
                messages.success(request, f"Status successfully changed.")
            else:
                messages.error(request, f"Status change error.")

        if request.POST.get("comment-body"):
            Comment.objects.create(
                author=request.user,
                ticket=ticket,
                body=bleach.clean(request.POST.get("comment-body"), strip=True)
            )
            messages.success(request, "Comment posted. Notification email sent to thread participants.")

        if request.FILES.get("attachment_file_input"):
            uploaded_file = request.FILES.get("attachment_file_input")
            name, extension = os.path.splitext(uploaded_file.name)

            if uploaded_file.size > 5000000:
                messages.error(request, f"File exceeds maximum attachment size.")
            elif extension not in [".jpg", ".gif", ".png", ".csv", ".pdf", ".zip", ".txt"]:
                messages.error(request, f"This site does not allow upload of {extension} files.")
            else:
                Attachment.objects.create(ticket=ticket, added_by=request.user, file=uploaded_file)
                messages.success(request, f"File attached successfully.")

        return redirect("tickets:ticket_detail", pk=ticket.pk)
