# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django import forms
from django.contrib import admin
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.conf.urls import url
from django.contrib.admin.util import flatten_fieldsets

from coin.filtering_queryset import LimitedAdminInlineMixin
from coin.billing.models import Invoice, InvoiceDetail, Payment
from coin.billing.utils import get_invoice_from_id_or_number
from coin.offers.models import OfferSubscription
import autocomplete_light


class InvoiceDetailInline(LimitedAdminInlineMixin, admin.StackedInline):
    model = InvoiceDetail
    extra = 0
    fields = (('label', 'amount', 'quantity', 'tax'),
        ('offersubscription','period_from', 'period_to'))

    def get_filters(self, obj):
        """
        Le champ "Abonnement" est filtré afin de n'afficher que les abonnements
        du membre choisi dans la facture. Si pas de membre alors renvoi
        une liste vide
        """
        if obj and obj.member:
            return (('offersubscription', {'member':obj.member}),)
        else:
            return (('offersubscription', None),)

    def get_readonly_fields(self, request, obj=None):
        if not obj or not obj.member:
            return self.readonly_fields + ('offersubscription',)
        return self.readonly_fields


class InvoiceDetailInlineReadOnly(admin.StackedInline):
    """
    Lorsque la facture est validée, il n'est plus possible de la modifier
    Ce inline est donc identique à InvoiceDetailInline, mais tous
    les champs sont en lecture seule
    """
    model = InvoiceDetail
    extra = 0
    fields = InvoiceDetailInline.fields
    can_delete = False

    def has_add_permission(self, request):
        return False

    def get_readonly_fields(self, request, obj=None):
        if self.declared_fieldsets:
            result = flatten_fieldsets(self.declared_fieldsets)
        else:
            result = list(set(
                    [field.name for field in self.opts.local_fields] +
                    [field.name for field in self.opts.local_many_to_many]
                ))
            result.remove('id')
        return result


class PaymentInline(admin.StackedInline):
    model = Payment
    extra = 0
    fields = (('date', 'payment_mean', 'amount'),)


class InvoiceAdmin(admin.ModelAdmin):
    list_display = ('number', 'date', 'status', 'amount', 'member', 'validated')
    list_display_links = ('number', 'date')
    fields = (('number', 'date', 'status'),
       ('date_due'),
       ('member'),
       ('amount','amount_paid'),
       ('validated', 'pdf'))
    readonly_fields = ('amount','amount_paid','validated','pdf')
    form = autocomplete_light.modelform_factory(Invoice)

    def get_readonly_fields(self, request, obj=None):
        """
        Si la facture est validée, passe tous les champs en readonly
        """
        if obj and obj.validated:
            if self.declared_fieldsets:
                return flatten_fieldsets(self.declared_fieldsets)
            else:
                return list(set(
                    [field.name for field in self.opts.local_fields] +
                    [field.name for field in self.opts.local_many_to_many]
                ))
        return self.readonly_fields

    def get_inline_instances(self, request, obj=None):
        """
        Renvoi les inlines selon le context :
        * Si création, alors ne renvoi aucun inline
        * Si modification, renvoi InvoiceDetail et PaymentInline
        * Si facture validée, renvoi InvoiceDetail en ReadOnly et PaymentInline
        """
        inlines = []
        inline_instances = []

        if obj is not None:
            if obj.validated:
                inlines = [InvoiceDetailInlineReadOnly]
            else:
                inlines = [InvoiceDetailInline]

            inlines += [PaymentInline]

        for inline_class in inlines:
            inline = inline_class(self.model, self.admin_site)

            if request:
                if not (inline.has_add_permission(request) or
                        inline.has_change_permission(request) or
                        inline.has_delete_permission(request)):
                    continue
                if not inline.has_add_permission(request):
                    inline.max_num = 0
            inline_instances.append(inline)

        return inline_instances

    def get_urls(self):
        """
        Custom admin urls
        """
        urls = super(InvoiceAdmin, self).get_urls()
        my_urls = [
            url(r'^validate/(?P<id>.+)$', self.admin_site.admin_view(self.validate_view),
                name='invoice_validate'),
        ]
        return my_urls + urls

    def validate_view(self, request, id):
        """
        Vue appelée lorsque l'admin souhaite valider une facture (et générer le pdf)
        """
        #TODO : Add better perm here
        if request.user.is_superuser:
            invoice = get_invoice_from_id_or_number(id)
            invoice.validate()
            messages.success(request, 'La facture a été validée.')
        else:
            messages.error(request, 'Vous n\'avez pas l\'autorisation de valider une facture.')

        return HttpResponseRedirect(request.META["HTTP_REFERER"])

admin.site.register(Invoice, InvoiceAdmin)
