from django.utils import timezone
from rest_framework import serializers

from apps.master import models as master_models
from apps.master.serializers import insurance_serializers
from apps.vehicle.models import VehicleInsurance
from base.serializers import DynamicFieldsModelSerializer


class VehicleInsuranceSerializers(DynamicFieldsModelSerializer):
    """
    Serializer class for serializing and deserializing VehicleInsurance instances.

    This serializer class includes fields for 'id', 'user_vehicle', 'insurance_company',
    'insurance_type', 'user', 'start_date', 'end_date', and 'policy'. It also
    dynamically filters the 'insurance_type' field based on the selected 'insurance_company'.

    Attributes:
        Meta.model: The model class to which this serializer applies.
        Meta.fields: The fields to include in the serialized representation.
        Meta.read_only_fields: The fields that should be treated as read-only during updates.

        insurance_company_data: Serializer field for 'insurance_company' with read-only fields 'id' and 'name'.
        insurance_type_data: Serializer field for 'insurance_type' with read-only fields 'id' and 'name'.
        is_insurance_expired: Serializer method field indicating whether the insurance has expired.

    Methods:
        __init__: Initialize the VehicleInsuranceSerializers instance. Dynamically filter the 'insurance_type'
            field queryset based on the selected 'insurance_company'.

        to_representation: Override the default to_representation method to add 'file_size' to the serialized representation.

        get_is_insurance_expired: Method to determine if the insurance has expired based on the 'end_date'.
    """

    insurance_company_data = insurance_serializers.InsuranceCompanyMasterSerializers(
        source="insurance_company", read_only=True, fields=["id", "name"]
    )
    insurance_types_data = insurance_serializers.InsuranceTypeMasterSerializers(
        source="insurance_types", read_only=True, fields=["id", "name"], many=True
    )
    is_insurance_expired = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = VehicleInsurance
        fields = (
            "id",
            "user_vehicle",
            "insurance_company",
            "insurance_types",
            "user",
            "start_date",
            "end_date",
            "insurance_company_data",
            "insurance_types_data",
            "is_insurance_expired",
            "policy",
        )
        read_only_fields = ["id", "user"]
        extra_kwargs = {
            "user_vehicle": {"write_only": True},
            "insurance_company": {"write_only": True},
            "insurance_types": {"write_only": True},
        }

    def __init__(self, *args, **kwargs):
        """
        Initialize the VehicleInsuranceSerializers instance.

        Dynamically filter the 'insurance_type' field queryset based on the selected 'insurance_company'.

        Args:
            *args: Variable length argument list.
            **kwargs: Arbitrary keyword arguments.
        """
        super(VehicleInsuranceSerializers, self).__init__(*args, **kwargs)

        # Dynamic filtering of the insurance type queryset based on the selected insurance_company
        if "context" in kwargs and "request" in kwargs["context"]:
            request = kwargs["context"]["request"]
            if "insurance_company" in request.data:
                selected_company = request.data["insurance_company"]
                self.fields[
                    "insurance_types"
                ].queryset = master_models.InsuranceTypeMaster.objects.filter(
                    insurance_company=selected_company
                )

    def to_representation(self, instance):
        """
        Override the default to_representation method to add 'file_size' to the serialized representation.

        Args:
            instance: The instance being serialized.

        Returns:
            dict: The serialized representation of the instance.
        """
        representation = super().to_representation(instance)
        file_size_bytes = instance.policy.size

        # Determine whether the file size should be in KB or MB
        if file_size_bytes >= 1024 * 1024:
            # Convert file size to MB with two decimal places
            file_size = f"{file_size_bytes / (1024 * 1024):.2f} MB"
        else:
            # Convert file size to KB with two decimal places
            file_size = f"{file_size_bytes / 1024:.2f} KB"

        # Add the 'file_size' to the serialized representation
        representation["file_size"] = file_size
        return representation

    def get_is_insurance_expired(self, obj):
        """
        Method to determine if the insurance has expired based on the 'end_date'.

        Args:
            obj: The VehicleInsurance instance.

        Returns:
            bool: True if the insurance has expired, False otherwise.
        """
        current_date = timezone.now().date()
        return obj.end_date < current_date
