from rest_framework import serializers
from rest_framework.reverse import reverse

from ichec_django_core.serializers import (
    NestedHyperlinkedModelSerializer,
    FormSerializer,
)

from marinerg_test_access.models import AccessCall, AccessCallFacilityReview


class AccessCallBaseSerializer(NestedHyperlinkedModelSerializer):

    class Meta:
        model = AccessCall
        fields = NestedHyperlinkedModelSerializer.base_fields + (
            "title",
            "description",
            "status",
            "closing_date",
            "selectable_facilities",
            "resolved_contact_email",
        )
        read_only_fields = NestedHyperlinkedModelSerializer.base_fields + (
            "resolved_contact_email",
        )


class AccessCallListSerializer(AccessCallBaseSerializer):
    pass


class AccessCallPublicDetailSerializer(AccessCallBaseSerializer):
    form = FormSerializer()

    class Meta:
        model = AccessCall
        fields = AccessCallBaseSerializer.Meta.fields + ("form",)
        read_only_fields = AccessCallBaseSerializer.Meta.read_only_fields

    def to_representation(self, instance):
        rep = super().to_representation(instance)

        for group in rep["form"]["groups"]:
            for field in group["fields"]:
                if field["template"]:
                    field["template"] = reverse(
                        "access_call_field_download",
                        args=[instance.id, field["id"]],
                        request=self.context["request"],
                    )
                else:
                    field["template"] = None
        return rep


class AccessCallReviewerDetailSerializer(AccessCallPublicDetailSerializer):

    review_template = serializers.HyperlinkedIdentityField(
        read_only=True, view_name="accesscall-review_template"
    )

    class Meta:
        model = AccessCall
        fields = AccessCallPublicDetailSerializer.Meta.fields + (
            "coordinator",
            "board_chair",
            "review_template",
        )
        read_only_fields = AccessCallPublicDetailSerializer.Meta.read_only_fields + (
            "review_template",
        )

    def to_representation(self, instance):
        rep = super().to_representation(instance)
        if not instance.review_template:
            rep["review_template"] = None
        return rep


class AccessCallDetailSerializer(AccessCallReviewerDetailSerializer):

    applications_summary = serializers.HyperlinkedIdentityField(
        read_only=True, view_name="accesscall-applications_summary"
    )

    class Meta:
        model = AccessCall
        fields = AccessCallReviewerDetailSerializer.Meta.fields + (
            "board_members",
            "public",
            "use_facility_review",
            "applications_summary",
        )
        read_only_fields = AccessCallReviewerDetailSerializer.Meta.read_only_fields + (
            "applications_summary",
        )

    def to_representation(self, instance):
        rep = super().to_representation(instance)
        if not instance.applications_summary:
            rep["applications_summary"] = None
        return rep

    def create(self, validated_data):

        form = validated_data.pop("form")
        form_instance = FormSerializer().create(form)

        many_to_many = self.pop_many_to_many(validated_data)
        instance = AccessCall.objects.create(form=form_instance, **validated_data)
        self.add_many_to_many(instance, many_to_many)
        return instance

    def update(self, instance, validated_data):
        form = validated_data.pop("form")

        instance = super().update(instance, validated_data)

        serializer = FormSerializer()
        serializer.update(instance.form, form)

        return instance


class AccessCallFacilityReviewSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = AccessCallFacilityReview
        fields = ["decision", "comments", "call", "facility"]
