from rest_framework import serializers
from .models import Channel, Campaign, MediaAsset, Post
from .services import short_link_url


class ChannelSerializer(serializers.ModelSerializer):
    platform_display = serializers.CharField(source="get_platform_display", read_only=True)

    class Meta:
        model = Channel
        fields = [
            "id", "name", "platform", "platform_display", "handle", "profile_url",
            "avatar_url", "active", "notes", "created_by", "created_at", "updated_at",
        ]
        read_only_fields = ["id", "platform_display", "created_by", "created_at", "updated_at"]


class CampaignSerializer(serializers.ModelSerializer):
    post_count = serializers.SerializerMethodField()

    class Meta:
        model = Campaign
        fields = [
            "id", "name", "objective", "description", "color",
            "start_date", "end_date", "post_count",
            "created_by", "created_at", "updated_at",
        ]
        read_only_fields = ["id", "post_count", "created_by", "created_at", "updated_at"]

    def get_post_count(self, obj):
        # Use the queryset annotation when present (list view); fall back to a
        # direct count for detail/create responses.
        annotated = getattr(obj, "post_count_anno", None)
        return annotated if annotated is not None else obj.posts.count()


class MediaAssetSerializer(serializers.ModelSerializer):
    url = serializers.SerializerMethodField()

    class Meta:
        model = MediaAsset
        fields = [
            "id", "title", "kind", "file", "url", "width", "height",
            "size_bytes", "tags", "uploaded_by", "created_at",
        ]
        read_only_fields = ["id", "url", "size_bytes", "uploaded_by", "created_at"]

    def get_url(self, obj):
        if not obj.file:
            return ""
        request = self.context.get("request")
        url = obj.file.url
        return request.build_absolute_uri(url) if request else url


class PostListSerializer(serializers.ModelSerializer):
    """Compact representation for list/calendar views."""
    campaign_name = serializers.CharField(source="campaign.name", default="", read_only=True)
    campaign_color = serializers.CharField(source="campaign.color", default="", read_only=True)
    channel_count = serializers.SerializerMethodField()
    channels = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
    tracking_short_code = serializers.CharField(source="tracking_url.short_code", default="", read_only=True)
    tracking_clicks = serializers.IntegerField(source="tracking_url.clicks", default=0, read_only=True)
    tracking_target_url = serializers.CharField(source="tracking_url.original_url", default="", read_only=True)
    tracking_link = serializers.SerializerMethodField()

    class Meta:
        model = Post
        fields = [
            "id", "title", "body", "status", "scheduled_at", "published_at",
            "campaign", "campaign_name", "campaign_color",
            "channels", "channel_count", "tags", "link_url",
            "tracking_url", "tracking_short_code", "tracking_clicks", "tracking_target_url", "tracking_link",
            "author", "created_at", "updated_at",
        ]
        read_only_fields = fields

    def get_channel_count(self, obj):
        annotated = getattr(obj, "channel_count_anno", None)
        return annotated if annotated is not None else obj.channels.count()

    def get_tracking_link(self, obj):
        return short_link_url(obj.tracking_url.short_code) if obj.tracking_url_id else ""


class PostDetailSerializer(serializers.ModelSerializer):
    campaign_name = serializers.CharField(source="campaign.name", default="", read_only=True)
    tracking_short_code = serializers.CharField(source="tracking_url.short_code", default="", read_only=True)
    tracking_clicks = serializers.IntegerField(source="tracking_url.clicks", default=0, read_only=True)
    tracking_target_url = serializers.CharField(source="tracking_url.original_url", default="", read_only=True)
    tracking_link = serializers.SerializerMethodField()

    class Meta:
        model = Post
        fields = [
            "id", "title", "body", "status",
            "channels", "campaign", "campaign_name", "media",
            "scheduled_at", "published_at", "timezone_name",
            "tags", "link_url", "metrics", "error_message",
            "tracking_url", "tracking_short_code", "tracking_clicks", "tracking_target_url", "tracking_link",
            "author", "created_at", "updated_at",
        ]
        read_only_fields = [
            "id", "published_at", "metrics", "error_message", "author", "created_at", "updated_at",
            "tracking_url", "tracking_short_code", "tracking_clicks", "tracking_target_url", "tracking_link",
        ]

    def get_tracking_link(self, obj):
        return short_link_url(obj.tracking_url.short_code) if obj.tracking_url_id else ""
