from django.conf import settings
from django.utils import timezone
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from greg.models import Identity
from gregui.models import GregUserProfile


class IdentitySerializer(serializers.ModelSerializer):
    """Serializer for the Identity model with validation of various fields"""

    class Meta:
        model = Identity
        fields = "__all__"
        read_only_fields = [
            "id",
            "person",
            "type",
            "source",
            "value",
            "verified",
            "verified_by",
        ]

    def _get_sponsor(self):
        """
        Fetch the sponsor doing the request

        Since the ViewSet using this Serializer uses the IsSponsor permission, we know
        that the user is connect to a GregUserProfile with a sponsor object.
        """
        user = None
        request = self.context.get("request")
        if request and hasattr(request, "user"):
            user = request.user
        return GregUserProfile.objects.get(user=user).sponsor

    def validate(self, attrs):
        """
        Set values automatically when updating.

        - All updates are manual from the ui endpoints.
        - The one verifying must be the logged in user which we know is a sponsor since
          the user passed the IsSponsor permission in the view using this serializer.
        - No point leaving setting the verified_at time to anyone other than the
          server itself.

        Note: Get requests do not use this method, making it safe.
        """
        # Prevent nin verification. (This will only trigger if someone is posting the
        # requests themselves. The frontend has its own setting disabling the button
        # used against this endpoint.)
        if settings.DISABLE_NIN_VERIFY and self.instance.type == str(
            Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER
        ):
            raise ValidationError(
                detail="NIN verification currently disabled.",
            )
        attrs["verified"] = Identity.Verified.MANUAL
        attrs["verified_by"] = self._get_sponsor()
        attrs["verified_at"] = timezone.now()
        return attrs


class PartialIdentitySerializer(serializers.ModelSerializer):
    class Meta:
        model = Identity
        fields = ["id", "value", "type", "verified_at"]