# -*- coding: utf-8 -*-

from django.contrib import admin
import django.forms.models
from django.contrib.sites.models import Site
from django.contrib.auth import models as auth_models
from django.contrib.auth import admin as auth_admin
from django.utils.translation import ugettext_lazy as _
from django.db.models import Q

from models import *
import forms
import widgets

class ProfileAdmin(admin.ModelAdmin):
    filter_horizontal = [ 'choices', ]
    list_display = ['id', 'order', 'name', 'display_choices', 'ppd', 'ppp']
    list_editable = ['name', 'order', 'ppd', 'ppp']

admin.site.register(Profile, ProfileAdmin)

class ProfileOptionChoiceInline(admin.StackedInline):
    model = ProfileOptionChoice

class ProfileOptionAdmin(admin.ModelAdmin):
    inlines = [ ProfileOptionChoiceInline, ]
    list_display = ['id', 'order', 'name', 'visible', 'list_type', 'display_choices']
    list_editable = ['name', 'order', 'visible', 'list_type']

admin.site.register(ProfileOption, ProfileOptionAdmin)

class AccountingCodeInline(admin.TabularInline):
    model = AccountingCode

class EntityAdmin(admin.ModelAdmin):
    list_display = ['pre_code', 'get_name', 'get_description']
    fields = [ 'code', 'is_active', 'name', 'description', 'types', 'depth',
            'description_override', 'name_override', 'get_children',
            'get_parents' ]
    readonly_fields = [ 'code', 'name', 'description', 'types', 'depth',
            'get_children', 'get_parents']
    list_filter = ['depth']
    search_fields = ['name', 'description', 'code']
    inlines = [AccountingCodeInline]
    exclude = ['left_bound', 'right_bound']

    def get_children(self, instance):
        a = [ u'<li><a href="../{0}/">{1}</a></li>'.format(child.id, child.get_name()) for child in instance.children().filter(depth=instance.depth+1).order_by('name')]
        if a:
            return u'<ul>{0}</ul>'.format(''.join(a))
        else:
            return ''
    get_children.allow_tags = True
    get_children.short_description = _(u'Entités filles')

    def get_parents(self, instance):
        try:
            parent = instance.parents().get(depth=instance.depth-1)
            return u'<a href="../{0}/">{1}</a>'.format(parent.id, parent.name)
        except Entity.DoesNotExist:
            return ''
    get_parents.allow_tags = True
    get_parents.short_description = _(u'Entité parent')

    def pre_code(self, instance):
        return u'<pre>+%s  %s</pre>' % ('-+'*instance.depth, instance.code)
    pre_code.allow_tags = True
    pre_code.short_description = _(u'Code')

    def get_readonly_fields(self, request, obj=None):
        if not request.user.is_superuser:
            return self.readonly_fields + \
                    [ 'is_active', 'name_override', 'description_override' ]
        return self.readonly_fields

    def queryset(self, request):
        qs = super(EntityAdmin, self).queryset(request)
        if not request.user.is_superuser:
            filters = []
            ras = RoleAssociation.objects.filter(user=request.user)
            for ra in ras.select_related('entity'):
                filters.append(Q(left_bound__gte=ra.entity.left_bound,
                                    left_bound__lt=ra.entity.right_bound))
            if not filters:
                return Entity.objects.none()
            qs = qs.filter(reduce(Q.__or__, filters))
        # Override default query handling
        if request.GET.get('q'):
            query = request.GET.get('q')
            children = Entity.objects.filter(Q(name__icontains=query)
                    | Q(description__icontains=query)
                    | Q(name_override__icontains=query)
                    | Q(description_override__icontains=query)
                    | Q(code__icontains=query))
            if 0 < len(children) < 100:
                request.GET = request.GET.copy()
                del request.GET['q']
                filters = [ Q(left_bound__lte=child.left_bound,
                    right_bound__gte=child.right_bound) for child in children ]
                qs = qs.filter(reduce(Q.__or__, filters))
        return qs

class HistoryInline(admin.TabularInline):
    model = History

class RequestAdmin(admin.ModelAdmin):
    raw_id_fields = [ 'entity' ]
    list_display = ['id', 'user', 'uploadfile', 'name', 'nb_pages', 'entity',  ]
    date_hierarchy = 'delivery_date'
    list_filter = ['status', 'delivery_date', 'creation_date', 'usage',
            'licence', 'copyright', 'usage' ]
    inlines = [ HistoryInline ]

class TransitionAdmin(admin.ModelAdmin):
    list_display = [ 'id', 'role', 'source', 'get_name', 'destination',
            'default', 'warn' ]
    list_filter = [ 'role', 'source', 'action', 'destination' ]

class MailNotificationInline(admin.TabularInline):
    model = MailNotification
    list_display = ('action', 'to', 'subject')
    list_filter = ('action', 'to')

class ActionAdmin(admin.ModelAdmin):
    inlines = [ MailNotificationInline ]
    list_display = ('id', 'name', 'comment', 'special_type', 'pages',
            'validate_request' )
    list_filter = ('comment', 'special_type', 'validate_request')
    list_editable = [ 'name', 'comment', 'special_type', 'validate_request' ]

class StatusAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'order', 'visible', 'default', 'start', 'end')
    list_editable = ('name', 'order', 'visible', 'default', 'start', 'end')
    list_filter = ('visible', 'default', 'start', 'end')
    filter_horizontal = [ 'visible_by' ]

admin.site.register(Entity, EntityAdmin)
admin.site.register(EntityType)

admin.site.register(Role)

class DeliveryPlaceAdmin(admin.ModelAdmin):
    list_display = [ 'id', 'order', 'name', 'description', 'comments' ]
    list_editable = [ 'order', 'name', 'description', 'comments' ]

admin.site.register(DeliveryPlace, DeliveryPlaceAdmin)

class DocumentUsageAdmin(admin.ModelAdmin):
    list_display = [ 'id', 'order', 'name', 'description', 'url', 'comments' ]
    list_editable = [ 'order', 'name', 'description', 'url', 'comments' ]

admin.site.register(DocumentUsage, DocumentUsageAdmin)

class DocumentLicenceAdmin(admin.ModelAdmin):
    list_display = [ 'id', 'order', 'name', 'description', 'url', 'comments' ]
    list_editable = [ 'order', 'name', 'description', 'url', 'comments' ]

admin.site.register(DocumentLicence, DocumentLicenceAdmin)
admin.site.register(Request, RequestAdmin)

admin.site.register(Status, StatusAdmin)
admin.site.register(Action, ActionAdmin)
admin.site.register(Transition, TransitionAdmin)

class MailNotificationAdmin(admin.ModelAdmin):
    list_display = [ 'action', 'to', 'subject_template' ]
    list_filter = [ 'action', 'to' ]

admin.site.register(MailNotification, MailNotificationAdmin)

# don't show the "Site" model
admin.site.unregister(Site)
admin.site.unregister(auth_models.User)

class RoleAssociationInline(admin.TabularInline):
    model = RoleAssociation
    fields = ('role', 'entity')
    raw_id_fields = ('entity',)
    template = 'polynum/admin_tabular.html'

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        """
        Get a form Field for a ForeignKey.
        """
        db = kwargs.get('using')
        if db_field.name in self.raw_id_fields:
            kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel,
                                    self.admin_site, using=db)
        return db_field.formfield(**kwargs)

class UserAdmin(auth_admin.UserAdmin):
    readonly_fields = ('first_name', 'last_name', 'email',
            'affectation','last_login', 'date_joined')
    fieldsets = (
        (None, {'fields': ('username',)}),
        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email', 'affectation')}),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('username', )}
        ),
    )
    filter_horizontal = ('groups',)
    inlines = [ RoleAssociationInline ]
    add_form = forms.UserCreationForm
    form = django.forms.models.modelform_factory(User)

    def affectation(self, user):
        attr = user.get_ldap_attributes()
        affectation = attr.get('supannEntiteAffectation', [])
        return u', '.join(affectation)

admin.site.register(User, UserAdmin)
