from django.contrib import admin, messages
from django.core.urlresolvers import reverse
from django.utils.encoding import force_text
from django.utils.safestring import mark_safe

from .models import (
    Document, Cost, Good, CostUse, GoodUse, Service, ServiceUse)


class GoodInline(admin.TabularInline):
    model = Good
    extra = 0
    exclude = ['description_html']


class CostInline(admin.TabularInline):
    model = Cost
    extra = 0
    exclude = ['description_html']


class ServiceInline(admin.TabularInline):
    model = Service
    fields = (
        'name', 'subscriptions_count',
        'monthly_unit_cost', 'new_subscriber_cost')
    readonly_fields = (
        'name', 'subscriptions_count',
        'monthly_unit_cost', 'new_subscriber_cost')
    show_change_link = True
    extra = 0

    def monthly_unit_cost(self, obj):
        return '{:.2f}€'.format(obj.get_prices()['unit_recurring_price'])
    monthly_unit_cost.short_description = "Coût de revient mensuel"

    def new_subscriber_cost(self, obj):
        return '{:.2f}€'.format(obj.get_prices()['total_goods_value_share'])
    new_subscriber_cost.short_description = "Coût nouv. abo"


@admin.register(Document)
class DocumentAdmin(admin.ModelAdmin):
    list_display = ('name', 'date', 'type')
    actions = ['copy']
    inlines = [ServiceInline, GoodInline, CostInline]
    save_on_top = True

    def copy(self, request, queryset):
        for i in queryset.all():
            new = i.copy()
            edit_url = reverse('admin:costs_document_change', args=(new.pk,))
            self.message_user(
                request, mark_safe(
                    "{} copié, pensez à <a href=\"{}\">L'éditer</a>".format(
                        new, edit_url)))
    copy.short_description = 'Copier'


class AbstractUseInline(admin.TabularInline):
    """ An inline with some knowledge of the currently edited Document
    """
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "resource" and getattr(request, 'document', None):
            kwargs["queryset"] = db_field.related_model.objects.filter(
                document=request.document)
        return super().formfield_for_foreignkey(
            db_field, request, **kwargs)


class GoodUseInline(AbstractUseInline):
    model = GoodUse
    extra = 1


class CostUseInline(AbstractUseInline):
    model = CostUse
    extra = 1


class ServiceUseInline(AbstractUseInline):
    model = ServiceUse
    extra = 1
    fk_name = 'service'


class DirectDocumentFilter(admin.SimpleListFilter):
    title = 'Document'

    parameter_name = 'document'

    def queryset(self, request, queryset):
        document = self.value()
        if not document:
            return queryset.none()
        else:
            return queryset.filter(document=document)

    def lookups(self, request, model_admin):
        for i in Document.objects.all():
            yield i.pk, str(i)

    def choices(self, changelist):
        """ Same as base SimpleListFilter but do not display the "All" choice
        """
        for lookup, title in self.lookup_choices:
            yield {
                'selected': self.value() == force_text(lookup),
                'query_string': changelist.get_query_string(
                    {self.parameter_name: lookup}, []),
                'display': title,
            }


@admin.register(Service)
class ServiceAdmin(admin.ModelAdmin):
    list_display = (
        'name', 'subscriptions_count', 'document',
        'monthly_unit_cost', 'new_subscriber_cost')
    inlines = (CostUseInline, GoodUseInline, ServiceUseInline)
    list_filter = [DirectDocumentFilter]
    fieldsets = (
        (None, {
            'fields': (
                ('name', 'document'), 'description', 'subscriptions_count'),
        }),
        ('Ré-utilisabilité', {
            'fields': ('reusable',)
        })
    )
    save_on_top = True

    def get_form(self, request, obj=None, **kwargs):
        if obj:
            # anotate the request with some context
            request.document = obj.document
        else:
            doc_pk = request.GET.get('document')
            if doc_pk:
                request.document = Document.objects.get(pk=doc_pk)
            else:
                request.document = None
                if request.method == 'GET':
                    self.message_user(
                        request,
                        'Il est nécessaire de faire "Enregistrer et continuer"'
                        ' pour ajouter des ressources au service',
                        messages.WARNING)

        return super().get_form(request, obj, **kwargs)

    def get_inline_instances(self, request, obj=None):
        if getattr(request, 'document', None):
            return super().get_inline_instances(request, obj)
        else:
            return []

    def monthly_unit_cost(self, obj):
        return '{:.2f}€'.format(obj.get_prices()['unit_recurring_price'])

    def new_subscriber_cost(self, obj):
        return '{:.2f}€'.format(obj.get_prices()['total_goods_value_share'])
