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

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

# from models import *
from .. import utils
import forms
import widgets

from models import (AccountingCode, Action, DeliveryPlace, DocumentLicence,
        DocumentUsage, Entity, EntityType, History, MailNotification, Profile,
        ProfileOption, ProfileOptionChoice, Request, Role, RoleAssociation,
        Status, Transition, User)

class PolynumAdminSite(admin.AdminSite):
    pass

class BaseModelAdmin(admin.ModelAdmin):
    delete_confirmation_template = 'admin/polynum_delete_confirmation.html'
    delete_selected_confirmation_template = 'admin/polynum_delete_selected_confirmation.html'

site = PolynumAdminSite()

class UserAdmin(auth_admin.UserAdmin, BaseModelAdmin):
    pass

class GroupAdmin(auth_admin.GroupAdmin, BaseModelAdmin):
    class Media:
        css = { 'all': [ 'css/admin.css' ] }

site.register(auth_models.User, auth_admin.UserAdmin)
site.register(auth_models.Group, auth_admin.GroupAdmin)

class ProfileAdmin(BaseModelAdmin, utils.LocalizedModelAdmin):
    filter_horizontal = [ 'choices', ]
    list_display = ['id', 'order', 'name', 'display_choices', 'ppd', 'ppp']
    list_editable = [ 'order' ]
    class Media:
        css = { 'all': [ 'css/admin.css' ] }

site.register(Profile, ProfileAdmin)

class ProfileOptionChoiceInline(admin.StackedInline, utils.LocalizedModelAdmin):
    model = ProfileOptionChoice
    extra = 0

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

site.register(ProfileOption, ProfileOptionAdmin)

class AccountingCodeInline(admin.TabularInline):
    model = AccountingCode

class EntityAdmin(BaseModelAdmin):
    list_display = ['pre_code', 'get_name', 'get_description', 'entity_type']
    fields = [ 'code', 'is_active', 'name', 'description', 'entity_type', 'parent', 'depth',
            'description_override', 'name_override', 'get_children',
            'get_parents']
    readonly_fields = [ 'code', 'name', 'description', 'entity_type', 'depth',
            'get_children', 'get_parents', 'parent' ]
    list_filter = ['depth']
    search_fields = ['name', 'description', 'code', 'name_override', 'description_override']
    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):
        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))
        return qs

class HistoryInline(admin.TabularInline):
    model = History
    extra = 0

class RequestAdmin(BaseModelAdmin):
    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(BaseModelAdmin):
    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')
    extra = 0

class ActionAdmin(BaseModelAdmin):
    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(BaseModelAdmin):
    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' ]

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

site.register(Role, BaseModelAdmin)

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

site.register(DeliveryPlace, DeliveryPlaceAdmin)

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

site.register(DocumentUsage, DocumentUsageAdmin)

class DocumentLicenceAdmin(BaseModelAdmin):
    list_display = [ 'id', 'order', 'default', 'only_free_documents', 'name', 'description', 'url', 'comments' ]
    list_editable = [ 'order' ]

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

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

class MailNotificationAdmin(BaseModelAdmin):
    list_display = [ 'action', 'to', 'subject_template' ]
    list_filter = [ 'action', 'to' ]

site.register(MailNotification, MailNotificationAdmin)

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', )}
        ),
    )
    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)

site.register(User, UserAdmin)

# delegation

from polynum.delegation.models import Delegation
from polynum.delegation.admin import DelegationAdmin as BaseDelegationAdmin


class DelegationAdmin(BaseDelegationAdmin, BaseModelAdmin):
    pass


site.register(Delegation, DelegationAdmin)

# editor

from polynum.editor.models import ContentBlock
from polynum.editor.admin import ContentBlockAdmin as BaseContentBlockAdmin


class ContentBlockAdmin(BaseContentBlockAdmin, BaseModelAdmin):
    pass


site.register(ContentBlock, ContentBlockAdmin)
