from datetime import date

from django.db.models import Q
from django.utils import timezone
from rest_framework import permissions, serializers, viewsets

from apps.templates.models import PurchasedTemplate

from .models import Invoice
from .serializers import InvoiceSerializer


class InvoiceViewSet(viewsets.ModelViewSet):
    serializer_class = InvoiceSerializer
    permission_classes = [permissions.IsAuthenticated]
    filterset_fields = ['status', 'customer']

    def get_queryset(self):
        return Invoice.objects.filter(company=self.request.user.company).prefetch_related('items')

    def _consume_template_usage(self, template, previous_template_id):
        if template is None or template.id == previous_template_id:
            return
        if template.price <= 0:
            return

        purchase = (
            PurchasedTemplate.objects.filter(
                Q(uses_remaining__gt=0) | Q(uses_remaining__isnull=True),
                company=self.request.user.company,
                template=template,
            )
            .order_by('uses_remaining')
            .first()
        )
        if purchase is None:
            raise serializers.ValidationError(
                {'template': 'This template has not been purchased, or its uses are exhausted.'}
            )
        if purchase.uses_remaining is not None:
            purchase.uses_remaining -= 1
            purchase.save(update_fields=['uses_remaining'])

    @staticmethod
    def _remember_template(company, template):
        # Whatever template an invoice was just saved with — including
        # picking "Default" (None) — becomes the one pre-selected next time
        # this company starts a new invoice.
        if company.default_template_id != getattr(template, 'id', None):
            company.default_template = template
            company.save(update_fields=['default_template'])

    def perform_create(self, serializer):
        company = self.request.user.company
        year = date.today().year
        seq = Invoice.objects.filter(company=company, issue_date__year=year).count() + 1
        now = timezone.localtime()
        invoice_number = company.invoice_number_format.format(
            prefix=company.invoice_prefix,
            year=year,
            seq=seq,
            date=now.strftime('%Y%m%d'),
            time=now.strftime('%H%M'),
        )
        template = serializer.validated_data.get('template')
        self._consume_template_usage(template, previous_template_id=None)
        serializer.save(company=company, created_by=self.request.user, invoice_number=invoice_number)
        self._remember_template(company, template)

    def perform_update(self, serializer):
        previous_template_id = serializer.instance.template_id
        template = serializer.validated_data.get('template')
        self._consume_template_usage(template, previous_template_id=previous_template_id)
        serializer.save()
        self._remember_template(serializer.instance.company, template)
