"""
Chat Service — DRF Serializers.
"""
from rest_framework import serializers

from .models import (
    Channel,
    ChannelMember,
    Message,
    MessageAttachment,
    MessageReadReceipt,
    UserPresence,
)


# ──────────────────────────────────────────────────────────────
# User mini serializer (avoid circular import)
# ──────────────────────────────────────────────────────────────

class ChatUserSerializer(serializers.Serializer):
    id = serializers.UUIDField()
    email = serializers.EmailField()
    display_name = serializers.CharField()
    first_name = serializers.CharField()
    last_name = serializers.CharField()
    avatar = serializers.ImageField(allow_null=True)


# ──────────────────────────────────────────────────────────────
# Channel
# ──────────────────────────────────────────────────────────────

class ChannelListSerializer(serializers.ModelSerializer):
    member_count = serializers.SerializerMethodField()
    unread_count = serializers.SerializerMethodField()
    created_by_name = serializers.SerializerMethodField()
    members = serializers.SerializerMethodField()

    class Meta:
        model = Channel
        fields = [
            'id', 'name', 'description', 'channel_type', 'visibility',
            'source_type', 'source_id', 'is_archived',
            'last_message_at', 'message_count', 'member_count',
            'unread_count', 'created_by', 'created_by_name', 'created_at',
            'members',
        ]
        read_only_fields = fields

    def get_member_count(self, obj):
        return obj.members.filter(
            status__in=['active', 'muted'],
        ).count()

    def get_unread_count(self, obj):
        request = self.context.get('request')
        if not request or not hasattr(request, 'user'):
            return 0
        user = request.user
        try:
            member = obj.members.get(user=user)
            return member.unread_count
        except (ChannelMember.DoesNotExist, Exception):
            return 0

    def get_created_by_name(self, obj):
        if obj.created_by:
            return obj.created_by.get_full_name() or obj.created_by.email
        return None

    def get_members(self, obj):
        """Return members for DM channels (to resolve display names in frontend)."""
        if obj.channel_type != 'direct':
            return None
        members = obj.members.filter(
            status__in=['active', 'muted'],
        ).select_related('user')[:2]
        return ChannelMemberSerializer(members, many=True).data


class ChannelDetailSerializer(ChannelListSerializer):
    members = serializers.SerializerMethodField()

    class Meta(ChannelListSerializer.Meta):
        fields = ChannelListSerializer.Meta.fields + [
            'avatar', 'max_members', 'slug', 'updated_at',
        ]

    def get_members(self, obj):
        members = obj.members.filter(
            status__in=['active', 'muted'],
        ).select_related('user')[:50]
        return ChannelMemberSerializer(members, many=True).data


class ChannelCreateSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=200, required=False, default='')
    channel_type = serializers.ChoiceField(choices=['direct', 'group', 'public', 'project'])
    visibility = serializers.ChoiceField(
        choices=['public', 'private', 'project'],
        required=False,
        default='private',
    )
    description = serializers.CharField(required=False, default='')
    member_ids = serializers.ListField(
        child=serializers.UUIDField(),
        required=False,
        default=[],
    )
    source_type = serializers.CharField(required=False, default='')
    source_id = serializers.UUIDField(required=False, allow_null=True, default=None)


class DirectChatSerializer(serializers.Serializer):
    user_id = serializers.IntegerField(required=True)


# ──────────────────────────────────────────────────────────────
# Channel Member
# ──────────────────────────────────────────────────────────────

class ChannelMemberSerializer(serializers.ModelSerializer):
    user_info = serializers.SerializerMethodField()

    class Meta:
        model = ChannelMember
        fields = [
            'id', 'user', 'role', 'status', 'unread_count',
            'notifications_enabled', 'last_read_at', 'joined_at',
            'user_info',
        ]
        read_only_fields = fields

    def get_user_info(self, obj):
        u = obj.user
        return {
            'id': str(u.id),
            'email': u.email,
            'display_name': getattr(u, 'display_name', '') or '',
            'first_name': u.first_name,
            'last_name': u.last_name,
        }


class AddMemberSerializer(serializers.Serializer):
    user_id = serializers.IntegerField()
    role = serializers.ChoiceField(
        choices=['member', 'admin', 'guest'],
        required=False,
        default='member',
    )


# ──────────────────────────────────────────────────────────────
# Message
# ──────────────────────────────────────────────────────────────

class MessageAttachmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = MessageAttachment
        fields = ['id', 'stored_file_id', 'file_name', 'file_size', 'mime_type']
        read_only_fields = fields


class MessageSerializer(serializers.ModelSerializer):
    sender_info = serializers.SerializerMethodField()
    attachments = MessageAttachmentSerializer(many=True, read_only=True)
    reply_to_preview = serializers.SerializerMethodField()

    class Meta:
        model = Message
        fields = [
            'id', 'channel', 'sender', 'sender_info',
            'message_type', 'content', 'reply_to', 'reply_to_preview',
            'is_edited', 'edited_at', 'is_deleted',
            'attachments', 'metadata', 'created_at',
        ]
        read_only_fields = fields

    def get_sender_info(self, obj):
        if not obj.sender:
            return None
        return {
            'id': str(obj.sender.id),
            'email': obj.sender.email,
            'display_name': getattr(obj.sender, 'display_name', '') or '',
            'first_name': obj.sender.first_name,
            'last_name': obj.sender.last_name,
        }

    def get_reply_to_preview(self, obj):
        if not obj.reply_to:
            return None
        sender_name = ''
        if obj.reply_to.sender:
            sender_name = obj.reply_to.sender.get_full_name() or obj.reply_to.sender.email
        return {
            'id': str(obj.reply_to.id),
            'content': obj.reply_to.content[:100] if obj.reply_to.content else '',
            'sender_name': sender_name,
        }


class SendMessageSerializer(serializers.Serializer):
    content = serializers.CharField(required=False, default='', allow_blank=True)
    message_type = serializers.ChoiceField(
        choices=['text', 'file', 'image', 'system'],
        required=False,
        default='text',
    )
    reply_to = serializers.UUIDField(required=False, allow_null=True, default=None)
    attachments = serializers.ListField(
        child=serializers.JSONField(),
        required=False,
        default=[],
        help_text='List of UUID strings or dicts with file_id/file_name/file_size/mime_type',
    )


class EditMessageSerializer(serializers.Serializer):
    content = serializers.CharField()


class MarkReadSerializer(serializers.Serializer):
    message_id = serializers.UUIDField()


# ──────────────────────────────────────────────────────────────
# Presence
# ──────────────────────────────────────────────────────────────

class UserPresenceSerializer(serializers.ModelSerializer):
    user_info = serializers.SerializerMethodField()

    class Meta:
        model = UserPresence
        fields = ['id', 'user', 'user_info', 'status', 'last_seen', 'custom_status']
        read_only_fields = fields

    def get_user_info(self, obj):
        u = obj.user
        return {
            'id': str(u.id),
            'email': u.email,
            'display_name': getattr(u, 'display_name', '') or '',
        }


class SetPresenceSerializer(serializers.Serializer):
    status = serializers.ChoiceField(choices=['online', 'away', 'busy', 'offline'])
    custom_status = serializers.CharField(required=False, default='')


# ──────────────────────────────────────────────────────────────
# Search
# ──────────────────────────────────────────────────────────────

class SearchMessageSerializer(serializers.Serializer):
    query = serializers.CharField(min_length=2)
