# Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later

from django.contrib import admin
from django.contrib.admin import ModelAdmin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _
from polymorphic.admin import PolymorphicChildModelAdmin, PolymorphicChildModelFilter, PolymorphicInlineSupportMixin, \
    PolymorphicParentModelAdmin, StackedPolymorphicInline

from .models import CoachRegistration, ParticipantRegistration, Payment, Registration, \
    StudentRegistration, VolunteerRegistration


class RegistrationInline(StackedPolymorphicInline):
    class StudentRegistrationInline(StackedPolymorphicInline.Child):
        model = StudentRegistration
        autocomplete_fields = ('team',)
        show_change_link = True

    class CoachRegistrationInline(StackedPolymorphicInline.Child):
        model = CoachRegistration
        autocomplete_fields = ('team',)
        show_change_link = True

    class VolunteerRegistrationInline(StackedPolymorphicInline.Child):
        model = VolunteerRegistration
        show_change_link = True

    model = Registration
    child_inlines = (
        StudentRegistrationInline,
        CoachRegistrationInline,
        VolunteerRegistrationInline,
    )


class PaymentInline(admin.TabularInline):
    model = Payment
    extra = 0
    autocomplete_fields = ('registrations',)


@admin.register(Registration)
class RegistrationAdmin(PolymorphicParentModelAdmin):
    child_models = (StudentRegistration, CoachRegistration, VolunteerRegistration,)
    list_display = ('user', 'first_name', 'last_name', 'type', 'email_confirmed',)
    list_filter = (PolymorphicChildModelFilter, 'email_confirmed',)
    search_fields = ('user__first_name', 'user__last_name', 'user__email',)
    polymorphic_list = True

    @admin.display(description=_('first name'), ordering='user__first_name')
    def first_name(self, record):
        return record.user.first_name

    @admin.display(description=_('last name'), ordering='user__last_name')
    def last_name(self, record):
        return record.user.last_name


@admin.register(ParticipantRegistration)
class ParticipantRegistrationAdmin(PolymorphicChildModelAdmin):
    list_display = ('user', 'first_name', 'last_name', 'type', 'team', 'email_confirmed',)
    list_filter = ('email_confirmed',)
    search_fields = ('user__first_name', 'user__last_name', 'user__email',)
    autocomplete_fields = ('user', 'team',)

    @admin.display(description=_('first name'), ordering='user__first_name')
    def first_name(self, record):
        return record.user.first_name

    @admin.display(description=_('last name'), ordering='user__last_name')
    def last_name(self, record):
        return record.user.last_name


@admin.register(StudentRegistration)
class StudentRegistrationAdmin(PolymorphicChildModelAdmin):
    list_display = ('user', 'first_name', 'last_name', 'team', 'email_confirmed',)
    list_filter = ('email_confirmed',)
    search_fields = ('user__first_name', 'user__last_name', 'user__email',)
    autocomplete_fields = ('user', 'team',)

    @admin.display(description=_('first name'), ordering='user__first_name')
    def first_name(self, record):
        return record.user.first_name

    @admin.display(description=_('last name'), ordering='user__last_name')
    def last_name(self, record):
        return record.user.last_name


@admin.register(CoachRegistration)
class CoachRegistrationAdmin(PolymorphicChildModelAdmin):
    list_display = ('user', 'first_name', 'last_name', 'team', 'email_confirmed',)
    list_filter = ('email_confirmed',)
    search_fields = ('user__first_name', 'user__last_name', 'user__email',)
    autocomplete_fields = ('user', 'team',)

    @admin.display(description=_('first name'), ordering='user__first_name')
    def first_name(self, record):
        return record.user.first_name

    @admin.display(description=_('last name'), ordering='user__last_name')
    def last_name(self, record):
        return record.user.last_name


@admin.register(VolunteerRegistration)
class VolunteerRegistrationAdmin(PolymorphicChildModelAdmin):
    list_display = ('user', 'first_name', 'last_name', 'tournaments', 'email_confirmed',)
    list_filter = ('organized_tournaments', 'email_confirmed',)
    search_fields = ('user__first_name', 'user__last_name', 'user__email',)
    autocomplete_fields = ('user',)

    @admin.display(description=_('first name'), ordering='user__first_name')
    def first_name(self, record):
        return record.user.first_name

    @admin.display(description=_('last name'), ordering='user__last_name')
    def last_name(self, record):
        return record.user.last_name

    @admin.display(description=_("tournaments"))
    def tournaments(self, record):
        return ', '.join(tr.name for tr in record.interesting_tournaments) or None


@admin.register(Payment)
class PaymentAdmin(ModelAdmin):
    list_display = ('concerned_people', 'tournament', 'team', 'grouped', 'type', 'amount', 'final', 'valid', )
    search_fields = ('registrations__user__last_name', 'registrations__user__first_name', 'registrations__user__email',
                     'registrations__team__name', 'registrations__team__participation__team__trigram',)
    list_filter = ('registrations__team__participation__valid', 'type',
                   'grouped', 'valid', 'registrations__team__participation__tournament', 'final',)
    autocomplete_fields = ('registrations',)
    actions = ('mark_as_valid', 'mark_as_pending', 'mark_as_invalid',)

    @admin.display(description=_('concerned people'))
    def concerned_people(self, record: Payment):
        return ", ".join(f"{reg.user.first_name} {reg.user.last_name}" for reg in record.registrations.all())

    @admin.action(description=_('Mark as valid'))
    def mark_as_valid(self, request, queryset):
        queryset.update(valid=True)

    @admin.action(description=_('Mark as pending'))
    def mark_as_pending(self, request, queryset):
        queryset.update(valid=None)

    @admin.action(description=_('Mark as invalid'))
    def mark_as_invalid(self, request, queryset):
        queryset.update(valid=False)


admin.site.unregister(User)


@admin.register(User)
class UserCustomAdmin(PolymorphicInlineSupportMixin, UserAdmin):
    inlines = [RegistrationInline]