from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError
from accounts.models import UserProfile
from liuyao.models import liuyao
from datetime import datetime
from django.core.validators import RegexValidator
from bazi.models import Person as BaziPerson

User = get_user_model()

class UserProfileRegistrationSerializer(serializers.ModelSerializer):
    birth_date = serializers.DateField(
        required=False,
        help_text='Birth date (optional) - format: YYYY-MM-DD'
    )
    birth_time = serializers.TimeField(
        required=False,
        help_text='Birth time (optional) - format: HH:MM:SS'
    )
    twin_type = serializers.IntegerField(
        required=False,
        help_text='Twin type (optional) - choices: 0 (Not a twin), 1 (Elder twin), 2 (Younger twin)'
    )
    father_dob = serializers.DateField(
        required=False,
        help_text='Father date of birth (optional) - format: YYYY-MM-DD'
    )
    mother_dob = serializers.DateField(
        required=False,
        help_text='Mother date of birth (optional) - format: YYYY-MM-DD'
    )
    can_regenerate_ai = serializers.BooleanField(
        required=False,
        default=False,
        help_text='AI regeneration permission (optional) - boolean, defaults to False'
    )
    
    class Meta:
        model = UserProfile
        fields = ['birth_date', 'birth_time', 'twin_type', 'father_dob', 'mother_dob', 'can_regenerate_ai']
        extra_kwargs = {
            'birth_date': {'required': False},
            'birth_time': {'required': False},
            'twin_type': {'required': False},
            'father_dob': {'required': False},
            'mother_dob': {'required': False},
            'can_regenerate_ai': {'required': False}
        }

class UserRegistrationSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=True, style={'input_type': 'password'})
    password2 = serializers.CharField(style={'input_type': 'password'}, write_only=True, required=False)
    profile = UserProfileRegistrationSerializer(required=False)
    gender = serializers.CharField(required=False)
    
    class Meta:
        model = User
        fields = ['phone', 'email', 'password', 'password2', 'first_name', 'last_name', 'gender', 'profile']
        extra_kwargs = {
            'password': {'write_only': True},
            'first_name': {'required': False},
            'last_name': {'required': False},
            'gender': {'required': False}
        }
    
    def validate(self, data):
        if 'password2' in data and data['password'] != data['password2']:
            raise serializers.ValidationError({"password2": "Password fields didn't match."})
        
        try:
            validate_password(data['password'])
        except ValidationError as e:
            raise serializers.ValidationError({"password": list(e.messages)})
        
        # Validate twin type requirements if provided
        profile_data = data.get('profile', {})
        twin_type = profile_data.get('twin_type')
        if twin_type == 1 and not profile_data.get('father_dob'):
            raise serializers.ValidationError({"profile": {"father_dob": ["双大需要填写父亲出生日期"]}})
        elif twin_type == 2 and not profile_data.get('mother_dob'):
            raise serializers.ValidationError({"profile": {"mother_dob": ["双小需要填写母亲出生日期"]}})
        
        return data
    
    def create(self, validated_data):
        # Remove password2 as it's not needed for user creation
        validated_data.pop('password2', None)
        
        # Extract profile data if it exists
        profile_data = validated_data.pop('profile', None)
        
        # Create the user
        user = User.objects.create_user(**validated_data)
        
        # Update the profile if data was provided
        if profile_data:
            # Get or create the profile
            profile, created = UserProfile.objects.get_or_create(user=user)
            
            # Update the profile with the provided data
            for field, value in profile_data.items():
                setattr(profile, field, value)
            profile.save()
        
        return user

class LoginSerializer(serializers.Serializer):
    phone = serializers.CharField(required=True)
    password = serializers.CharField(required=True, write_only=True)

class PasswordResetRequestSerializer(serializers.Serializer):
    email = serializers.CharField(required=True)

class PasswordResetConfirmSerializer(serializers.Serializer):
    uidb64 = serializers.CharField(required=True)
    token = serializers.CharField(required=True)
    password = serializers.CharField(write_only=True, required=True)
    password2 = serializers.CharField(write_only=True, required=True)

    def validate(self, attrs):
        # Check that the two passwords match
        if attrs['password'] != attrs['password2']:
            raise serializers.ValidationError({"password": "Password fields didn't match."})
        return attrs

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('birth_date', 'birth_time', 'twin_type', 'father_dob', 'mother_dob', 'can_regenerate_ai')
        extra_kwargs = {
            'birth_date': {'required': False},
            'birth_time': {'required': False},
            'twin_type': {'required': False},
            'father_dob': {'required': False},
            'mother_dob': {'required': False},
            'can_regenerate_ai': {'read_only': True}  # Make this field read-only as it's controlled by admin
        }

class UserSerializer(serializers.ModelSerializer):
    profile = UserProfileSerializer(required=False)

    class Meta:
        model = User
        fields = ('id', 'phone', 'email', 'first_name', 'last_name', 'gender', 'profile', 'is_temporary_user')
        extra_kwargs = {
            'phone': {'required': False},
            'email': {'required': False},
            'first_name': {'required': False},
            'last_name': {'required': False},
            'gender': {'required': False}
        }

    def update(self, instance, validated_data):
        profile_data = validated_data.pop('profile', None)
        
        # Update user fields
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()

        # Update profile if data is provided
        if profile_data is not None:
            from accounts.models import UserProfile
            profile, created = UserProfile.objects.get_or_create(user=instance)
            for attr, value in profile_data.items():
                setattr(profile, attr, value)
            profile.save()

        return instance

# Liuyao Serializers
class LiuyaoSerializer(serializers.ModelSerializer):
    data = serializers.JSONField(
        help_text="Contains the complete calculation result with the same structure as returned by the /api/liuyao/calc endpoint. "
                 "See the /api/liuyao/calc endpoint documentation for the detailed structure."
    )
    
    class Meta:
        model = liuyao
        fields = '__all__'
        read_only_fields = ('user', 'uuid', 'created_at', 'last_modified_at')

class LiuyaoRequestSerializer(serializers.ModelSerializer):
    """Serializer for request documentation - excludes read-only fields"""
    data = serializers.JSONField(
        required=False,
        help_text="JSON data containing calculation results (optional)"
    )
    
    class Meta:
        model = liuyao
        fields = ['qdate', 'question', 'y1', 'y2', 'y3', 'y4', 'y5', 'y6', 'reading', 'feedback', 'data']

class LiuyaoCalculatorSerializer(serializers.ModelSerializer):
    usecur = serializers.BooleanField(required=False, default=False)
    year = serializers.IntegerField(max_value=9999, min_value=1000, required=False)
    month = serializers.IntegerField(max_value=12, min_value=1, required=False)
    day = serializers.IntegerField(max_value=31, min_value=1, required=False)
    time = serializers.CharField(
        max_length=5,
        required=False,
        validators=[
            RegexValidator(
                regex=r"^\d{2}:\d{2}$",
                message="Invalid time format. Use 'HH:MM'."
            )
        ]
    )

    class Meta:
        model = liuyao
        fields = ['y1', 'y2', 'y3', 'y4', 'y5', 'y6', 'question', 'usecur', 'year', 'month', 'day', 'time']

    def validate(self, attrs):
        usecur = attrs.get('usecur', False)
        year = attrs.get('year')
        month = attrs.get('month')
        day = attrs.get('day')
        time = attrs.get('time', "00:00")

        # Validate date
        if not usecur and (year is not None and month is not None and day is not None):
            try:
                datetime(year, month, day)  # Validate if date is valid
            except ValueError:
                raise serializers.ValidationError({
                    'year': f"Invalid date ({year}-{month:02d}-{day:02d}).",
                    'month': f"Invalid date ({year}-{month:02d}-{day:02d}).",
                    'day': f"Invalid date ({year}-{month:02d}-{day:02d}).",
                })

        # Validate time format
        try:
            hours, minutes = map(int, time.split(':'))
            if not (0 <= hours <= 23 and 0 <= minutes <= 59):
                raise ValueError
        except ValueError:
            raise serializers.ValidationError({
                'time': "Invalid time format. Use 'HH:MM'."
            })

        return attrs 

# Bazi Serializers
class BaziSerializer(serializers.ModelSerializer):
    """Serializer for Bazi Person model with full fields"""
    class Meta:
        model = BaziPerson
        # Exclude count fields from API response for compactness (counts can be derived from arrays)
        exclude = ('relation_good_count', 'relation_bad_count')
        read_only_fields = ('created_by', 'created_at', 'updated_at', 'bazi_result')

class BaziRequestSerializer(serializers.ModelSerializer):
    """Serializer for Bazi request documentation - excludes read-only fields"""
    class Meta:
        model = BaziPerson
        fields = ['name', 'gender', 'birth_date', 'birth_time', 'twin_type', 'father_dob', 'mother_dob', 'notes']

# Tongshu Serializers
class TongshuCalendarQuerySerializer(serializers.Serializer):
    """Serializer for querying calendar data"""
    year = serializers.IntegerField(required=False, help_text="Year (defaults to current year if not provided)")
    month = serializers.IntegerField(required=False, help_text="Month (1-12, defaults to current month if not provided)")
    extra_days = serializers.IntegerField(required=False, help_text="Number of extra days to include before/after the month (default varies based on month layout, maximum 100, negative values treated as 0)")

class LunarDateSerializer(serializers.Serializer):
    """Serializer for lunar date data"""
    y = serializers.IntegerField(help_text="Lunar year")
    m = serializers.IntegerField(help_text="Lunar month")
    d = serializers.IntegerField(help_text="Lunar day")
    leap = serializers.BooleanField(required=False, help_text="Whether this is a leap month")

class BaziPillarForTongshuSerializer(serializers.Serializer):
    """Serializer for Bazi pillar in Tongshu API"""
    god = serializers.CharField(help_text="Heavenly stem (天干) in Chinese")
    earth = serializers.CharField(help_text="Earthly branch (地支) in Chinese")

class BaziForTongshuSerializer(serializers.Serializer):
    """Serializer for Bazi data in Tongshu API"""
    year = BaziPillarForTongshuSerializer(help_text="Year pillar")
    month = BaziPillarForTongshuSerializer(help_text="Month pillar")
    day = BaziPillarForTongshuSerializer(help_text="Day pillar")
    hour = BaziPillarForTongshuSerializer(help_text="Hour pillar")

class DayDataSerializer(serializers.Serializer):
    """Serializer for detailed day data"""
    date = serializers.CharField(help_text="Date in YYYY-MM-DD format")
    day = serializers.IntegerField(help_text="Day of month")
    is_adjacent_month = serializers.BooleanField(help_text="Whether this day belongs to adjacent month")
    is_today = serializers.BooleanField(help_text="Whether this day is today")
    bazi = BaziForTongshuSerializer(help_text="Four pillars information")
    lunar = LunarDateSerializer(help_text="Raw lunar date information")
    lunar_formatted = serializers.CharField(help_text="Formatted lunar date in Chinese characters")
    lunar_title = serializers.CharField(help_text="Lunar month or solar term name")
    lunar_desc = serializers.CharField(help_text="Lunar day or solar term time")
    lunar_leap = serializers.CharField(help_text="Leap month indicator (if applicable)")
    jianchu = serializers.CharField(help_text="Jianchu (建除) cycle value in Chinese")
    has_solar_term = serializers.BooleanField(help_text="Whether this day has a solar term")
    solar_term_index = serializers.IntegerField(help_text="Index of the solar term (0-23)")
    month_earth = serializers.CharField(help_text="Month's earthly branch in Chinese")
    month_element = serializers.CharField(help_text="Month's five element in English")

class SolarTermSerializer(serializers.Serializer):
    """Serializer for solar term data"""
    name = serializers.CharField(help_text="Name of the solar term in Chinese")
    date = serializers.CharField(help_text="Date and time of the solar term in ISO format")
    index = serializers.IntegerField(help_text="Index of the solar term (0-23)")

class CalendarMonthSerializer(serializers.Serializer):
    """Serializer for full month calendar data"""
    year = serializers.IntegerField(help_text="Gregorian year")
    month = serializers.IntegerField(help_text="Gregorian month")
    days = serializers.ListField(
        child=serializers.ListField(
            child=DayDataSerializer(),
            help_text="Array of days in a week"
        ),
        help_text="Two-dimensional array of days (organized by weeks)"
    )
    solar_terms = serializers.ListField(
        child=SolarTermSerializer(),
        help_text="Solar terms in this month"
    )
    prev_month = TongshuCalendarQuerySerializer(help_text="Previous month reference")
    next_month = TongshuCalendarQuerySerializer(help_text="Next month reference")

class Calendar10kQuerySerializer(serializers.Serializer):
    """Serializer for querying calendar10k data"""
    year = serializers.IntegerField(required=True, help_text="Year to retrieve calendar data for (range: 1900-2100)")

class YearDataSerializer(serializers.Serializer):
    """Serializer for year data in Calendar10k"""
    element = serializers.CharField(help_text="Year's element in English (wood/fire/earth/metal/water)")
    animal = serializers.CharField(help_text="Chinese zodiac animal")
    star = serializers.CharField(help_text="Flying star")

class MonthCycleSerializer(serializers.Serializer):
    """Serializer for a monthly cycle with two solar terms"""
    first = serializers.DictField(help_text="First solar term data of the month")
    second = serializers.DictField(help_text="Second solar term data of the month")
    count = serializers.IntegerField(help_text="Count of days in this month")
    star = serializers.CharField(help_text="Flying star for this month")

class PaginationSerializer(serializers.Serializer):
    """Serializer for pagination information"""
    prev = serializers.IntegerField(required=False, allow_null=True, help_text="Previous year (or false if at lower boundary)")
    next = serializers.IntegerField(required=False, allow_null=True, help_text="Next year (or false if at upper boundary)")

class Calendar10kSerializer(serializers.Serializer):
    """Serializer for full year calendar10k data"""
    year = serializers.IntegerField(help_text="Gregorian year")
    year_data = YearDataSerializer(help_text="Information about the year")
    cycles = serializers.ListField(child=MonthCycleSerializer(), help_text="Monthly cycles with solar terms")
    paginate = PaginationSerializer(help_text="Pagination information")

class TempLoginSerializer(serializers.Serializer):
    """
    Serializer for temporary user login endpoint.
    Migrates temp user data to existing user account.
    """
    phone = serializers.CharField(required=True)
    password = serializers.CharField(required=True, write_only=True)

class TempRegisterSerializer(serializers.ModelSerializer):
    """
    Serializer for temporary user registration endpoint.
    Converts temporary user to permanent user (only phone & email required).
    """
    password = serializers.CharField(
        write_only=True, 
        required=False, 
        style={'input_type': 'password'},
        help_text='Password (optional) - if provided, password2 is required for confirmation'
    )
    password2 = serializers.CharField(
        style={'input_type': 'password'}, 
        write_only=True, 
        required=False,
        help_text='Password confirmation (optional) - required if password is provided, must match password'
    )
    profile = UserProfileRegistrationSerializer(
        required=False,
        help_text='Profile data (optional) - contains birth_date, birth_time, twin_type, father_dob, mother_dob'
    )
    
    class Meta:
        model = User
        fields = ['phone', 'email', 'password', 'password2', 'first_name', 'last_name', 'gender', 'profile']
        extra_kwargs = {
            'phone': {'help_text': 'Phone number (required) - max 16 characters'},
            'email': {'help_text': 'Email address (required) - max 50 characters, must be unique'},
            'first_name': {'required': False, 'help_text': 'First name (optional) - max 150 characters'},
            'last_name': {'required': False, 'help_text': 'Last name (optional) - max 150 characters'},
            'gender': {'required': False, 'help_text': 'Gender (optional) - choices: M (Male), F (Female), N (Not specified)'}
        }
    
    def validate(self, data):
        # Password validation only if password is provided
        if 'password' in data and data['password']:
            if 'password2' in data and data['password'] != data['password2']:
                raise serializers.ValidationError({"password2": "Password fields didn't match."})
            
            try:
                validate_password(data['password'])
            except ValidationError as e:
                raise serializers.ValidationError({"password": list(e.messages)})
        
        # Validate twin type requirements if provided
        profile_data = data.get('profile', {})
        twin_type = profile_data.get('twin_type')
        if twin_type == 1 and not profile_data.get('father_dob'):
            raise serializers.ValidationError({"profile": {"father_dob": ["双大需要填写父亲出生日期"]}})
        elif twin_type == 2 and not profile_data.get('mother_dob'):
            raise serializers.ValidationError({"profile": {"mother_dob": ["双小需要填写母亲出生日期"]}})
        
        return data
    
    def validate_phone(self, value):
        """Check if phone number is not already taken by another user"""
        # Check if phone number is already taken by another user
        user = self.context.get('user')  # Current temp user
        if user and User.objects.filter(phone=value).exclude(id=user.id).exists():
            raise serializers.ValidationError("此电话号码已被使用")
        elif not user and User.objects.filter(phone=value).exists():
            raise serializers.ValidationError("此电话号码已被使用")
        return value
    
    def validate_email(self, value):
        """Check if email is valid and not already taken by another user"""
        # Validate email format
        from django.core.validators import validate_email
        from django.core.exceptions import ValidationError as DjangoValidationError
        try:
            validate_email(value)
        except DjangoValidationError:
            raise serializers.ValidationError("请输入有效的电子邮箱地址")
        
        # Check if email is already taken by another user
        user = self.context.get('user')  # Current temp user
        if user and User.objects.filter(email=value).exclude(id=user.id).exists():
            raise serializers.ValidationError("此电子邮箱已被使用")
        elif not user and User.objects.filter(email=value).exists():
            raise serializers.ValidationError("此电子邮箱已被使用")
        return value

class PasswordChangeSerializer(serializers.Serializer):
    """
    Serializer for password change endpoint.
    Requires the current password and new password with confirmation.
    """
    current_password = serializers.CharField(
        required=True, 
        write_only=True,
        style={'input_type': 'password'}
    )
    new_password = serializers.CharField(
        required=True, 
        write_only=True,
        style={'input_type': 'password'}
    )
    new_password2 = serializers.CharField(
        required=True,
        write_only=True,
        style={'input_type': 'password'}
    )

    def validate_current_password(self, value):
        user = self.context['request'].user
        if not user.check_password(value):
            raise serializers.ValidationError("Current password is incorrect.")
        return value

    def validate(self, attrs):
        # Check that the two new passwords match
        if attrs['new_password'] != attrs['new_password2']:
            raise serializers.ValidationError({"new_password": "Password fields didn't match."})
        return attrs 

class AccountDeletionRequestSerializer(serializers.Serializer):
    """
    Serializer for initiating account deletion request.
    """
    reason = serializers.CharField(
        required=False,
        allow_blank=True,
        max_length=500,
        help_text='Optional reason for account deletion'
    )


class TempUserCreateSerializer(serializers.Serializer):
    """
    Serializer for creating temporary users.
    All fields are optional and will be used for user profile creation.
    """
    name = serializers.CharField(
        required=False,
        max_length=255,
        help_text='Full name (optional) - will be split into first/last name automatically'
    )
    gender = serializers.CharField(
        required=False,
        max_length=1,
        help_text='Gender (optional) - M for male, F for female, N for not specified'
    )
    birth_date = serializers.DateField(
        required=False,
        help_text='Birth date (optional) - format: YYYY-MM-DD'
    )
    birth_time = serializers.TimeField(
        required=False,
        help_text='Birth time (optional) - format: HH:MM'
    )
    twin_type = serializers.IntegerField(
        required=False,
        min_value=0,
        max_value=2,
        help_text='Twin type (optional) - 0: not a twin, 1: elder twin, 2: younger twin'
    )
    father_dob = serializers.DateField(
        required=False,
        help_text='Father date of birth (optional) - format: YYYY-MM-DD'
    )
    mother_dob = serializers.DateField(
        required=False,
        help_text='Mother date of birth (optional) - format: YYYY-MM-DD'
    )
    birth_city = serializers.CharField(
        required=False,
        max_length=255,
        help_text='Birth city (optional)'
    )
    timezone = serializers.CharField(
        required=False,
        max_length=50,
        help_text='Timezone (optional) - e.g., Asia/Shanghai'
    )
    
    def validate(self, data):
        # Explicitly reject phone and email fields - these should only be handled by the system
        if 'phone' in data:
            raise serializers.ValidationError({
                "phone": "Phone field is not allowed. Phone numbers are system-generated for temporary users."
            })
        
        if 'email' in data:
            raise serializers.ValidationError({
                "email": "Email field is not allowed. Email addresses are system-generated for temporary users."
            })
        
        # Validate twin type requirements
        twin_type = data.get('twin_type')
        if twin_type == 1 and not data.get('father_dob'):
            raise serializers.ValidationError({
                "father_dob": "Father's birth date is required for elder twin."
            })
        elif twin_type == 2 and not data.get('mother_dob'):
            raise serializers.ValidationError({
                "mother_dob": "Mother's birth date is required for younger twin."
            })
        
        return data
    
    def validate_gender(self, value):
        if value and value not in ['M', 'F', 'N']:
            raise serializers.ValidationError(
                "Gender must be 'M' (male), 'F' (female), or 'N' (not specified)."
            )
        return value 


# Report Submission Serializers

class ReportSubmissionSerializer(serializers.Serializer):
    """Serializer for submitting AI analysis reports"""
    
    category = serializers.ChoiceField(
        choices=BaziPerson.REPORT_CATEGORY_CHOICES,
        help_text='Report category - reason for reporting the analysis'
    )
    message = serializers.CharField(
        max_length=1000, 
        required=False, 
        allow_blank=True,
        help_text='Optional message with additional details about the report'
    )
    
    def validate_category(self, value):
        """Validate the report category is one of the allowed choices"""
        valid_categories = [choice[0] for choice in BaziPerson.REPORT_CATEGORY_CHOICES]
        if value not in valid_categories:
            raise serializers.ValidationError(f"Invalid category. Must be one of: {valid_categories}")
        return value


class BaziReportSerializer(serializers.ModelSerializer):
    """Serializer for viewing BaZi analysis report details"""
    
    category_display = serializers.CharField(source='get_bazi_report_category_display', read_only=True)
    status_display = serializers.CharField(source='get_bazi_report_status_display', read_only=True)
    resolved_by_name = serializers.CharField(source='bazi_report_resolved_by.get_full_name', read_only=True)
    
    class Meta:
        model = BaziPerson
        fields = [
            'id', 'name', 'bazi_analysis_reported', 'bazi_report_category', 'category_display',
            'bazi_report_message', 'bazi_report_timestamp', 'bazi_report_status', 'status_display',
            'bazi_report_admin_notes', 'bazi_admin_action', 'resolved_by_name', 'bazi_report_resolved_at'
        ]
        read_only_fields = [
            'id', 'name', 'bazi_report_timestamp', 'category_display', 'status_display', 
            'resolved_by_name', 'bazi_report_resolved_at'
        ]


class NumberReportSerializer(serializers.ModelSerializer):
    """Serializer for viewing Number analysis report details"""
    
    category_display = serializers.CharField(source='get_number_report_category_display', read_only=True)
    status_display = serializers.CharField(source='get_number_report_status_display', read_only=True)
    resolved_by_name = serializers.CharField(source='number_report_resolved_by.get_full_name', read_only=True)
    
    class Meta:
        model = BaziPerson
        fields = [
            'id', 'name', 'number_analysis_reported', 'number_report_category', 'category_display',
            'number_report_message', 'number_report_timestamp', 'number_report_status', 'status_display',
            'number_report_admin_notes', 'number_admin_action', 'resolved_by_name', 'number_report_resolved_at'
        ]
        read_only_fields = [
            'id', 'name', 'number_report_timestamp', 'category_display', 'status_display',
            'resolved_by_name', 'number_report_resolved_at'
        ]


class LiuYaoReportSerializer(serializers.ModelSerializer):
    """Serializer for viewing LiuYao analysis report details"""
    
    category_display = serializers.CharField(source='get_report_category_display', read_only=True)
    status_display = serializers.CharField(source='get_report_status_display', read_only=True)
    resolved_by_name = serializers.CharField(source='report_resolved_by.get_full_name', read_only=True)
    
    class Meta:
        model = liuyao
        fields = [
            'id', 'question', 'analysis_reported', 'report_category', 'category_display',
            'report_message', 'report_timestamp', 'report_status', 'status_display',
            'report_admin_notes', 'admin_action', 'resolved_by_name', 'report_resolved_at'
        ]
        read_only_fields = [
            'id', 'question', 'report_timestamp', 'category_display', 'status_display',
            'resolved_by_name', 'report_resolved_at'
        ]


# Conversation serializers
from ai.models import Conversation, Message, ConversationConfig


class MessageSerializer(serializers.ModelSerializer):
    """Serializer for Message model"""
    
    class Meta:
        model = Message
        fields = ['id', 'role', 'content', 'created_at', 'provider', 'model', 'meta', 'status', 'error_message']
        read_only_fields = ['id', 'created_at']


class ConversationSerializer(serializers.ModelSerializer):
    """Serializer for Conversation model with messages"""
    
    person_id = serializers.SerializerMethodField()
    person_name = serializers.SerializerMethodField()
    message_count = serializers.IntegerField(source='get_message_count', read_only=True)
    last_message = serializers.SerializerMethodField()
    last_message_at = serializers.DateTimeField(source='updated_at', read_only=True)
    messages = MessageSerializer(many=True, read_only=True)
    
    class Meta:
        model = Conversation
        fields = [
            'id', 'person_id', 'person_name', 'title', 'last_message', 
            'last_message_at', 'message_count', 'created_at', 'updated_at', 'messages'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']
    
    def get_person_id(self, obj):
        """Get person ID from subject or legacy person field"""
        if obj.subject and obj.subject.content_type == 'bazi':
            return obj.subject.object_id
        elif obj.person:
            return obj.person.id
        return None
    
    def get_person_name(self, obj):
        """Get person name from subject or legacy person field"""
        if obj.subject and obj.subject.content_type == 'bazi':
            subject_obj = obj.subject.get_object()
            if subject_obj and hasattr(subject_obj, 'name'):
                return subject_obj.name
        elif obj.person:
            return obj.person.name
        return None
    
    def get_last_message(self, obj):
        """Get the last message content"""
        last_msg = obj.get_last_message()
        return last_msg.content[:100] + '...' if last_msg and len(last_msg.content) > 100 else (last_msg.content if last_msg else '')


class ConversationListSerializer(serializers.ModelSerializer):
    """Serializer for listing conversations (without full messages)"""
    
    person_id = serializers.SerializerMethodField()
    person_name = serializers.SerializerMethodField()
    message_count = serializers.IntegerField(source='get_message_count', read_only=True)
    last_message = serializers.SerializerMethodField()
    last_message_at = serializers.DateTimeField(source='updated_at', read_only=True)
    
    class Meta:
        model = Conversation
        fields = [
            'id', 'person_id', 'person_name', 'title', 'last_message',
            'last_message_at', 'message_count', 'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']
    
    def get_person_id(self, obj):
        """Get person ID from subject or legacy person field"""
        if obj.subject and obj.subject.content_type == 'bazi':
            return obj.subject.object_id
        elif obj.person:
            return obj.person.id
        return None
    
    def get_person_name(self, obj):
        """Get person name from subject or legacy person field"""
        if obj.subject and obj.subject.content_type == 'bazi':
            subject_obj = obj.subject.get_object()
            if subject_obj and hasattr(subject_obj, 'name'):
                return subject_obj.name
        elif obj.person:
            return obj.person.name
        return None
    
    def get_last_message(self, obj):
        """Get the last message content"""
        last_msg = obj.get_last_message()
        return last_msg.content[:100] + '...' if last_msg and len(last_msg.content) > 100 else (last_msg.content if last_msg else '')


class CreateConversationSerializer(serializers.Serializer):
    """Serializer for creating a new conversation"""
    pass  # No fields needed - conversation is created for a specific person


class SendMessageSerializer(serializers.Serializer):
    """Serializer for sending a message in a conversation"""
    
    message = serializers.CharField(
        required=True,
        max_length=2000,
        help_text='User message text (max 2000 characters)'
    )
    language = serializers.ChoiceField(
        choices=[('zh-hans', 'Chinese (Simplified)'), ('en', 'English')],
        required=False,
        default='zh-hans',
        help_text='Language for response'
    )
    provider = serializers.ChoiceField(
        choices=[('groq', 'Groq'), ('openai', 'OpenAI')],
        required=False,
        allow_null=True,
        help_text='AI provider override (requires can_regenerate_ai privilege)'
    )
    model = serializers.CharField(
        required=False,
        allow_null=True,
        help_text='AI model override (requires can_regenerate_ai privilege)'
    )
    
    def validate_message(self, value):
        """Validate message length"""
        if len(value.strip()) == 0:
            raise serializers.ValidationError("Message cannot be empty")
        if len(value) > 2000:
            raise serializers.ValidationError("Message cannot exceed 2000 characters")
        return value.strip()


class ConversationConfigSerializer(serializers.Serializer):
    """Serializer for conversation configuration"""
    
    max_messages = serializers.IntegerField(
        read_only=True,
        help_text='Maximum number of messages allowed per conversation (only messages with status="sent" count)'
    )