from django.contrib import admin
from django.contrib.auth.admin import (
    UserAdmin as DjangoUserAdmin,
    GroupAdmin as DjangoGroupAdmin,
)
from django.contrib.auth.models import Group
from django.forms import ModelForm, IntegerField
from django.utils.translation import ugettext_lazy as _

from intranet.femida.src.core.exceptions import SimpleValidationError
from intranet.femida.src.staff.tasks import sync_users
from .models import User, UserAbsence


def sync_users_action(modeladmin, request, queryset):
    sync_users.delay()


sync_users_action.short_description = 'Запустить синхронизацию пользователей'


class UserAdmin(DjangoUserAdmin):

    actions = [sync_users_action]

    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        (_('Personal info'), {
            'fields': (
                'first_name',
                'first_name_en',
                'last_name',
                'last_name_en',
                'email',
                'staff_id',
                'uid',
                'phone',
                'work_phone',
                'is_dismissed',
                'gender',
                'lang',
                'timezone',
                'is_intern',
            )}),
        (_('Permissions'), {
            'fields': (
                'is_active',
                'is_staff',
                'is_superuser',
                'groups',
                'user_permissions',
            )}),
        (_('Important dates'), {
            'fields': (
                'last_login',
                'date_joined',
            )}),
    )


class UserAbsenceAdmin(admin.ModelAdmin):

    date_hierarchy = 'date'

    list_display = (
        'id',
        'user',
        'date',
    )

    list_select_related = (
        'user',
    )

    raw_id_fields = (
        'user',
    )

    search_fields = (
        'user__username',
    )


class GroupAddForm(ModelForm):
    """
    Форма создания группы для админки.
    Позволяет явно задать ID группы.
    """
    id = IntegerField(
        required=True,
        help_text=(
            'ID группы задаётся явно, т.к. дальше этот ID используется для ролей в IDM, '
            'а также иногда используется непосредственно в коде Фемиды. '
            'Удобно, когда ID групп совпадает во всех окружениях'
        ),
    )

    def clean_id(self):
        group_id = self.cleaned_data['id']
        if Group.objects.filter(id=group_id).exists():
            raise SimpleValidationError('group_already_exists')
        return group_id


class GroupAdmin(DjangoGroupAdmin):
    """
    Админка для групп, которая позволяет создавать группы с заданным ID
    """
    list_display = ('id', 'name')
    ordering = ('-id',)

    def get_form(self, request, obj=None, change=False, **kwargs):
        self.form = GroupAddForm if obj is None else ModelForm
        return super().get_form(request, obj, change, **kwargs)

    def get_changeform_initial_data(self, request):
        initial = super().get_changeform_initial_data(request)
        if 'id' not in initial:
            last_group_id = Group.objects.values_list('id', flat=True).order_by('id').last()
            if last_group_id:
                initial['id'] = last_group_id + 1
        return initial

    def save_model(self, request, obj, form, change):
        obj.id = form.cleaned_data.get('id') or obj.id
        return super().save_model(request, obj, form, change)


admin.site.register(User, UserAdmin)
admin.site.register(UserAbsence, UserAbsenceAdmin)

# Убираем стандартную админку групп и регистрируем свою
admin.site.unregister(Group)
admin.site.register(Group, GroupAdmin)
