import logging
from urllib.parse import urlparse

from drf_spectacular.utils import extend_schema_field
from rest_framework import exceptions, status
from rest_framework import serializers
from rest_framework.response import Response

from apps.geology.models import Geology, Photo


class GeologySerializer(serializers.ModelSerializer):
    class Meta:
        model = Geology
        fields = (
            "id",
            "name",
            "title",
            "body1",
            "body2",
            "body3",
            "banner_title",
            "banner",
            "address",
            "image",
            "location",
            "composition",
            "isp",
            "analysis",
            "category",
            "created_at",
            "updated_at",
        )

    def create(self, validated_data):
        try:
            request = self.context.get("request")
            photo_data1 = []
            photo_data2 = []

            for key in request.data:
                if key.startswith("description1[") and key.endswith("]"):
                    index = key[len("description1[") : -1]
                    file_key = f"image1[{index}]"
                    photo_desc = request.data.get(key)
                    photo_file = request.FILES.get(file_key)

                    if not photo_file:
                        return Response(
                            {
                                "error": f"File is required for photo item {index} in photos1"
                            },
                            status=status.HTTP_400_BAD_REQUEST,
                        )
                    if not photo_desc:
                        photo_desc = photo_file.name
                    photo_data1.append({"image": photo_file, "description": photo_desc})

                if key.startswith("description2[") and key.endswith("]"):
                    index = key[len("description2[") : -1]
                    file_key = f"image2[{index}]"
                    photo_desc = request.data.get(key)
                    photo_file = request.FILES.get(file_key)

                    if not photo_file:
                        return Response(
                            {
                                "error": f"File is required for photo item {index} in photos2"
                            },
                            status=status.HTTP_400_BAD_REQUEST,
                        )
                    if not photo_desc:
                        photo_desc = photo_file.name
                    photo_data2.append({"image": photo_file, "description": photo_desc})

            geology = Geology.objects.create(
                name=validated_data.get("name"),
                title=validated_data.get("title"),
                body1=validated_data.get("body1"),
                body2=validated_data.get("body2"),
                body3=validated_data.get("body3"),
                banner_title=validated_data.get("banner_title"),
                banner=validated_data.get("banner"),
                address=validated_data.get("address"),
                location=validated_data.get("location"),
                composition=validated_data.get("composition"),
                isp=validated_data.get("isp"),
                analysis=validated_data.get("analysis"),
                category=validated_data.get("category"),
            )

            for photo in photo_data1:
                photo_instance = Photo.objects.create(
                    image=photo["image"], description=photo["description"]
                )
                geology.photos1.add(photo_instance)

            for photo in photo_data2:
                photo_instance = Photo.objects.create(
                    image=photo["image"], description=photo["description"]
                )
                geology.photos2.add(photo_instance)
            return geology
        except Exception as e:
            logging.error(f"Error in create method: {str(e)}")
            raise exceptions.ValidationError({"detail": str(e)})


class GeologyDetailSerializer(serializers.ModelSerializer):
    category = serializers.SerializerMethodField()
    photos1 = serializers.SerializerMethodField()
    photos2 = serializers.SerializerMethodField()

    class Meta:
        model = Geology
        fields = (
            "id",
            "category",
            "banner_title",
            "banner",
            "name",
            "title",
            "body1",
            "address",
            "image",
            "location",
            "composition",
            "isp",
            "analysis",
            "body2",
            "photos1",
            "body3",
            "photos2",
            "created_at",
            "updated_at",
        )

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        if representation.get("banner"):
            parsed_url = urlparse(representation["banner"])
            representation["banner"] = parsed_url.path
        return representation

    @extend_schema_field(serializers.DictField())
    def get_category(self, obj):
        from apps.geology.serializers.category import CategorySerializer

        return CategorySerializer(obj.category).data

    @extend_schema_field(serializers.ListField(child=serializers.DictField()))
    def get_photos1(self, obj):
        from apps.geology.serializers.photo import PhotoSerializer

        return PhotoSerializer(obj.photos1.all(), many=True).data

    @extend_schema_field(serializers.ListField(child=serializers.DictField()))
    def get_photos2(self, obj):
        from apps.geology.serializers.photo import PhotoSerializer

        return PhotoSerializer(obj.photos2.all(), many=True).data
