from rest_framework import serializers

from .models import Spot, SpotImage, Ward


class SpotSerializer(serializers.ModelSerializer):
    id = serializers.CharField(source="spot_id")
    lon = serializers.FloatField()
    lat = serializers.FloatField()

    class Meta:
        model = Spot
        fields = ["id", "spot", "lon", "lat", "category", "status"]


class WardSerializer(serializers.ModelSerializer):
    city = serializers.CharField(source="city.name", read_only=True)
    totalSpots = serializers.SerializerMethodField()
    spots = SpotSerializer(many=True, read_only=True)
    trend = serializers.FloatField()
    score = serializers.FloatField()

    def get_totalSpots(self, obj):
        return obj.spots.count()

    class Meta:
        model = Ward
        fields = [
            "ward", "name", "city", "rank", "score", "trend",
            "volunteers", "kendras", "partnerships", "totalSpots",
            "photos", "center", "boundary", "spots",
        ]


class SpotDetailSerializer(serializers.ModelSerializer):
    id = serializers.CharField(source="spot_id")
    lon = serializers.FloatField()
    lat = serializers.FloatField()
    score = serializers.FloatField()
    trend = serializers.FloatField()
    reported = serializers.SerializerMethodField()
    photos = serializers.SerializerMethodField()

    class Meta:
        model = Spot
        fields = [
            "id", "spot", "kind", "category", "status", "reported",
            "address", "score", "trend", "photos",
        ]

    def get_reported(self, obj):
        return obj.reported_date.strftime("%-d %b %Y") if obj.reported_date else None

    def get_photos(self, obj):
        by_type = {image.image_type: image.url for image in obj.images.all()}
        ordered = ["reality", "potential", "transformation"]
        return [by_type[t] for t in ordered if t in by_type]


class RealityPotentialSerializer(serializers.ModelSerializer):
    reality_image_url = serializers.SerializerMethodField()
    potential_image_url = serializers.SerializerMethodField()
    transformation_image_url = serializers.SerializerMethodField()
    lat = serializers.FloatField()
    long = serializers.FloatField(source="lon")
    created_date_time = serializers.DateTimeField(source="created_at")
    transformation_date_time = serializers.DateTimeField(source="transformation_at", allow_null=True)
    shortlisted_yes_no = serializers.BooleanField(source="shortlisted")
    tags = serializers.SerializerMethodField()

    class Meta:
        model = Spot
        fields = [
            "reality_image_url", "potential_image_url", "transformation_image_url",
            "lat", "long", "spot_name", "address", "tags", "created_date_time",
            "transformation_date_time", "shortlisted_yes_no",
        ]

    def _image(self, obj, image_type):
        for image in obj.images.all():
            if image.image_type == image_type:
                return image.url
        return None

    def get_reality_image_url(self, obj):
        return self._image(obj, "reality")

    def get_potential_image_url(self, obj):
        return self._image(obj, "potential")

    def get_transformation_image_url(self, obj):
        return self._image(obj, "transformation")

    def get_tags(self, obj):
        return list(obj.tags.values_list("name", flat=True))
