import sequences
from django.core.files.base import ContentFile
from django.db import transaction
from weasyprint import CSS, HTML

from oscar.core.loading import get_model

import oscar_invoices.utils

from ocyan.core.fender import config

LegalEntity = get_model("oscar_invoices", "LegalEntity")


class InvoiceCreator(oscar_invoices.utils.InvoiceCreator):
    def __init__(self, **context):
        self.context = context

    def get_legal_entity(self, **kwargs):
        order = kwargs.get("order")
        if order is not None:
            legal_entity = LegalEntity.objects.filter(shop_name=order.site.name).first()

            if legal_entity:
                return legal_entity

        return super().get_legal_entity()

    def create_invoice_model(self, **kwargs):
        kwargs["legal_entity"] = self.get_legal_entity(order=kwargs.get("order"))
        return super().create_invoice_model(**kwargs)

    def generate_invoice_number(self, order, **kwargs):
        return "%06d" % sequences.get_next_value("oscar_invoices")

    def generate_document(self, invoice, **kwargs):
        """
        Create and save invoice document (as *.html file).
        """

        # adds use_path so logo will be rendered as file:// locally accesible
        html = HTML(
            string=self.render_document(
                invoice, use_path=True, **self.context, **kwargs
            )
        )
        css = CSS(string="@page { size: A4; margin: 1cm }")
        content = html.write_pdf(stylesheets=[css])
        return ContentFile(content)

    def get_invoice_filename(self, invoice):
        invoice_file_name = config.get(
            "oscar_communications", "invoice_file_name", "invoice_"
        )
        return "%s%s.pdf" % (invoice_file_name, invoice.order.number)

    def get_or_create_invoice(self, order, **extra_kwargs):
        with transaction.atomic():
            Invoice = self.get_invoice_model()
            try:
                return Invoice.objects.get(order=order)
            except Invoice.DoesNotExist:
                return self.create_invoice(order, **extra_kwargs)
