import calendar
import json

from django import forms
from django.contrib import admin
from django.utils.html import format_html
from django.utils.safestring import mark_safe

from staff.person.models import Organization
from staff.departments.models import (
    Bonus,
    Department,
    DepartmentInterfaceSection,
    DepartmentStaff,
    DepartmentResponsible,
    DepartmentStaffCounter,
    DepartmentKind,
    DepartmentRole,
    Geography,
    HeadcountPosition,
    HrDeadline,
    Vacancy,
    DEADLINE_TYPE,
)

from staff.lib.utils.admin import StaffModelAdmin, BaseIntranetAdmin


# External models admins
class DepartmentAdmin(BaseIntranetAdmin):
    list_display = ('name', 'name_en', 'code', 'url', 'is_expanded', 'is_hidden')
    search_fields = list_display + ('short_name', 'short_name_en')
    not_required_fields = (
        'short_name',
        'short_name_en',
        'maillists',
        'clubs',
        'wiki_page',
        'jira_project',
        'description',
        'description_en',
        'is_expanded',
        'is_hidden',
        'is_cut_out',
        'section_caption',
        'section_group',
        'tags',
    )

    def has_delete_permission(self, request, obj=None):
        return False


class DepartmentInterfaceSectionAdmin(BaseIntranetAdmin):
    list_display = ('description', 'order', 'name', 'name_en')
    not_required_fields = ('name', 'name_en', 'order')


class OrganizationAdmin(BaseIntranetAdmin):
    list_display = ('name', 'chief', 'deputy', 'position', 'intranet_status')
    list_filter = 'intranet_status',
    ordering = 'position',
    search_fields = list_display
    fields = (
        'intranet_status',
        'name',
        'name_en',
        'city',
        'chief',
        'deputy',
        'color',
        'textcolor',
        'position',
        'filter_id',
    )
    required_fields = 'name', 'name_en', 'city', 'position'
    not_required_fields = (
        'chief',
        'deputy',
        'color',
        'textcolor',
    )


class DepartmentStaffAdmin(StaffModelAdmin):
    list_display = ('department', 'staff', 'role')
    required_fields = ('department', 'staff', 'role')


class DepartmentResponsibleAdmin(StaffModelAdmin):
    list_display = ('department', 'staff', 'role', 'responsible_for')


class DepartmentStaffCounterAdmin(StaffModelAdmin):
    list_display = ('department', 'day', 'staff_counter')
    list_filter = ('department', )


class DepartmentKindAdmin(BaseIntranetAdmin):
    list_display = ('id', 'slug', 'name', 'name_en')
    not_required_fields = ('name', 'name_en',)


class DepartmentRoleAdmin(BaseIntranetAdmin):
    list_display = ('id', 'slug', 'name', 'name_en', 'is_active', 'position')
    list_filter = ('is_active', 'manage_by_idm')
    filter_horizontal = 'permissions',


class HeadcountPositionAdmin(BaseIntranetAdmin):
    list_display = ('code', 'department', 'name', 'current_person', 'status', 'category_is_new')
    list_filter = ('status', 'category_is_new')
    ordering = 'code',
    search_fields = (
        'code',
        'name',
        'current_person__login',
        'current_person__first_name',
        'current_person__last_name',
        'department__name',
        'department__url',
        'department__id',
    )
    fields = (
        'code',
        'department',
        'category_is_new',
        'status',
        'name',
        'valuestream',
        'headcount',
        'current_person',
        'previous_person',
    )
    required_fields = fields
    not_required_fields = ()


class VacancyAdmin(StaffModelAdmin):
    list_display = (
        'id',
        'name',
        'offer_id',
        'headcount_position_code',
        'preprofile',
        'candidate_first_name',
        'candidate_last_name',
        'budget_position',
    )

    search_fields = (
        'id',
        'headcount_position_code',
        'offer_id',
        'budget_position_id',
        'budget_position__code',
    )

    readonly_fields = (
        'budget_position',
        'preprofile',
    )


class HrDeadlineForm(forms.ModelForm):
    class Meta:
        fields = '__all__'
        models = HrDeadline

    def clean(self):
        cd = self.cleaned_data
        type_value = cd['type']
        month_value = cd['month']
        date_value = cd['date']
        if type_value == DEADLINE_TYPE.STRUCTURE_CHANGE and date_value.month != month_value.month:
            raise ValueError('Дата структур должна быть в своем месяце')


class HrDeadlineAdmin(admin.ModelAdmin):
    form = HrDeadlineForm

    list_display = (
        'month',
        'date',
        'type',
    )
    list_filter = (
        'type',
    )
    ordering = ('-month', 'date')

    def get_month(self, obj):
        return '{} {}'.format(calendar.month_name[obj.month.month], obj.month.year)
    get_month.short_description = 'Месяц'


class GeographyForm(forms.ModelForm):
    class Meta:
        model = Geography
        fields = (
            'name',
            'name_en',
            'oebs_code',
            'oebs_description',
            'st_translation_id',
            'intranet_status',
            'department_instance',
        )

    department_instance = forms.ModelChoiceField(Department.geography.all())

    def _post_clean(self):
        with Department()._set_manager():
            super()._post_clean()


class GeographyAdmin(admin.ModelAdmin):
    list_display = (
        'name',
        'name_en',
        'oebs_code',
        'oebs_description',
        'st_translation_id',
        'intranet_status',
    )

    search_fields = (
        'name',
        'name_en',
        'oebs_code',
        'oebs_description',
    )

    form = GeographyForm

    def has_delete_permission(self, request, obj=None):
        return False


class DepartmentGeographyAdmin(DepartmentAdmin):
    class DepartmentGeography(Department):
        class Meta:
            proxy = True

    def get_queryset(self, request):
        return Department.geography.all()


class BonusModelAdmin(admin.ModelAdmin):
    list_display = [
        'scheme_id',
        'schemes_line_id',
        'name',
        'description',
        'start_date',
        'end_date',
        'non_review_bonus',
    ]

    search_fields = (
        'name',
        'description',
    )

    fields = (
        'scheme_id',
        'schemes_line_id',
        'name',
        'description',
        'start_date',
        'end_date',
        'non_review_bonus',
        'bonus_scheme',
        'scheme_data',
    )

    readonly_fields = fields

    @staticmethod
    def bonus_scheme(instance):
        def _format_scheme(scheme):
            text_data = ', '.join(f'{key}: {value}' for key, value in scheme.items())
            return format_html('<li>{}</li>', text_data)
        if not instance.scheme_data:
            return mark_safe('-')

        schemes = ''.join(_format_scheme(scheme) for scheme in json.loads(instance.scheme_data))
        return mark_safe(f'<ul>{schemes}</ul>')

    bonus_scheme.short_description = 'Scheme data'
    bonus_scheme.allow_tags = True


admin.site.register(Department, DepartmentAdmin)
admin.site.register(Geography, GeographyAdmin)
admin.site.register(DepartmentGeographyAdmin.DepartmentGeography, DepartmentGeographyAdmin)
admin.site.register(DepartmentInterfaceSection, DepartmentInterfaceSectionAdmin)
admin.site.register(Organization, OrganizationAdmin)

admin.site.register(DepartmentKind, DepartmentKindAdmin)
admin.site.register(DepartmentRole, DepartmentRoleAdmin)
admin.site.register(DepartmentStaff, DepartmentStaffAdmin)
admin.site.register(DepartmentResponsible, DepartmentResponsibleAdmin)
admin.site.register(DepartmentStaffCounter, DepartmentStaffCounterAdmin)
admin.site.register(HeadcountPosition, HeadcountPositionAdmin)
admin.site.register(Vacancy, VacancyAdmin)
admin.site.register(HrDeadline, HrDeadlineAdmin)
admin.site.register(Bonus, BonusModelAdmin)
