import copy

from dal_admin_filters import AutocompleteFilter
from django.contrib import admin
from django.utils.html import format_html
from fieldsets_with_inlines import FieldsetsInlineMixin
from import_export import resources
from nested_inline.admin import (
    NestedModelAdmin,
    NestedStackedInline,
    NestedTabularInline,
)
from rangefilter.filters import DateRangeFilter

from shared.admin import MarkdownxGuardedModelAdmin

from .forms import ContractAdminForm, ContractFileAdminForm, SigneeAdminForm
from .models import (
    Contract,
    Contractee,
    ContracteeSignature,
    ContracteeSignatureRepresentative,
    ContractFile,
    ContractFilingArea,
    ContractIntent,
    ContractIssue,
    ContractType,
    Signee,
    SigneeSignature,
    SigneeSignatureRepresentative,
)


class ContractResource(resources.ModelResource):
    class Meta:
        model = Contract


class IndexHiddenModelAdmin(MarkdownxGuardedModelAdmin):
    def has_module_permission(self, request):
        return False


# BEGIN Autocompletes


class ContractAuthorPlaceholderFilter(AutocompleteFilter):
    title = "Autor"
    field_name = "created_by"
    autocomplete_url = "users:select2_djhacker_user_autocomplete"


# END Autocompletes


# BEGIN Contracts


class ContractFileAdmin(IndexHiddenModelAdmin):
    form = ContractFileAdminForm


class ContracteeSignatureRepresentativeInline(NestedStackedInline):
    model = ContracteeSignatureRepresentative
    extra = 0


class ContracteeSignatureInline(NestedStackedInline):
    model = ContracteeSignature
    inlines = (ContracteeSignatureRepresentativeInline,)
    extra = 0


class SigneeSignatureRepresentativeInline(NestedStackedInline):
    model = SigneeSignatureRepresentative
    extra = 0


class SigneeSignatureInline(NestedStackedInline):
    model = SigneeSignature
    inlines = (SigneeSignatureRepresentativeInline,)
    extra = 0


class ContractFileInline(admin.TabularInline):
    model = ContractFile
    form = ContractFileAdminForm
    extra = 0


class ContractIntentInline(admin.TabularInline):
    model = ContractIntent
    extra = 0


class ContractAdmin(FieldsetsInlineMixin, MarkdownxGuardedModelAdmin, NestedModelAdmin):
    form = ContractAdminForm

    readonly_fields = ("created_by",)

    fieldsets_with_inlines = [
        (
            "Základní informace",
            {
                "fields": [
                    "name",
                    "id_number",
                    "types",
                    "summary",
                    "is_public",
                    "publishing_rejection_comment",
                    "legal_state",
                    "primary_contract",
                ]
            },
        ),
        (
            "Data",
            {
                "fields": [
                    "valid_start_date",
                    "valid_end_date",
                ]
            },
        ),
        (
            "Náklady",
            {
                "fields": [
                    "cost_amount",
                    "cost_unit",
                ]
            },
        ),
        ContractFileInline,
        ContracteeSignatureInline,
        SigneeSignatureInline,
        (
            "Odkazy",
            {
                "fields": [
                    "tender_url",
                    "agreement_url",
                ]
            },
        ),
        ContractIntentInline,
        (
            "Fyzický dokument",
            {
                "fields": [
                    "paper_form_state",
                    "filing_area",
                ]
            },
        ),
        (
            "Doplňující informace",
            {
                "fields": [
                    "issues",
                    "notes",
                ]
            },
        ),
    ]

    def get_fieldsets(self, request, obj=None):
        fieldsets_with_inlines = copy.deepcopy(self.fieldsets_with_inlines)

        if request.user.is_superuser or request.user.has_perm("approve", self):
            fieldsets_with_inlines.insert(
                8,
                ("Schválení", {"fields": ["is_approved"]}),
            )

        return [
            self.make_placeholder(index, fieldset)
            for index, fieldset in enumerate(fieldsets_with_inlines)
        ]

    def save_model(self, request, obj, form, change) -> None:
        if obj.created_by is None:
            obj.created_by = request.user

        if obj.valid_start_date is None:
            last_signature_date = None

            for signature_set in (
                obj.contractee_signatures.all(),
                obj.signee_signatures.all(),
            ):
                for signature in signature_set:
                    if (
                        last_signature_date is None
                        or last_signature_date < signature.date
                    ):
                        last_signature_date = signature.date

            obj.valid_start_date = last_signature_date

        super().save_model(request, obj, form, change)

    list_filter = (
        "types",
        "is_approved",
        "legal_state",
        "is_public",
        "paper_form_state",
        ContractAuthorPlaceholderFilter,
        "issues",
        ("all_parties_sign_date", DateRangeFilter),
        ("valid_start_date", DateRangeFilter),
        ("valid_end_date", DateRangeFilter),
    )

    list_display = (
        "name",
        "is_approved",
        "is_public",
    )


# END Contracts

# BEGIN Signing parties


class SigneeAdmin(MarkdownxGuardedModelAdmin):
    form = SigneeAdminForm

    fields = (
        "name",
        "entity_type",
        "address_street_with_number",
        "address_district",
        "address_zip",
        "address_country",
        "ico_number",
        "load_ares_data_button",
        "date_of_birth",
        "department",
        "role",
    )

    readonly_fields = ("load_ares_data_button",)

    list_filter = ("entity_type",)
    list_display = ("name", "entity_type")

    def load_ares_data_button(self, obj):
        return format_html(
            '<button type="button" id="load_ares_data">Načíst data</button>'
        )

    load_ares_data_button.allow_tags = True
    load_ares_data_button.short_description = "ARES"


# END Signing parties


for model in (
    SigneeSignature,
    ContracteeSignature,
    ContracteeSignatureRepresentative,
    SigneeSignatureRepresentative,
    ContractIntent,
):
    admin.site.register(model, IndexHiddenModelAdmin)

admin.site.register(ContractFile, ContractFileAdmin)

for model in (
    Contractee,
    ContractFilingArea,
    ContractIssue,
    ContractType,
):
    admin.site.register(model, MarkdownxGuardedModelAdmin)

admin.site.register(Signee, SigneeAdmin)

admin.site.register(Contract, ContractAdmin)