"""
Platform Serializers
Serializers for platform-level operations (viewing tenants, users, metrics)
"""
from rest_framework import serializers
from smoothschedule.identity.core.models import Tenant, Domain
from smoothschedule.identity.users.models import User
from .models import TenantInvitation, PlatformSettings, SubscriptionPlan, PlatformEmailAddress


class PlatformSettingsSerializer(serializers.Serializer):
    """Serializer for platform settings (read-only, with masked keys)"""
    stripe_secret_key_masked = serializers.SerializerMethodField()
    stripe_publishable_key_masked = serializers.SerializerMethodField()
    stripe_webhook_secret_masked = serializers.SerializerMethodField()
    stripe_account_id = serializers.CharField(read_only=True)
    stripe_account_name = serializers.CharField(read_only=True)
    stripe_keys_validated_at = serializers.DateTimeField(read_only=True)
    stripe_validation_error = serializers.CharField(read_only=True)
    has_stripe_keys = serializers.SerializerMethodField()
    stripe_keys_from_env = serializers.SerializerMethodField()
    email_check_interval_minutes = serializers.IntegerField(read_only=True)
    updated_at = serializers.DateTimeField(read_only=True)

    def get_stripe_secret_key_masked(self, obj):
        return obj.mask_key(obj.get_stripe_secret_key())

    def get_stripe_publishable_key_masked(self, obj):
        return obj.mask_key(obj.get_stripe_publishable_key())

    def get_stripe_webhook_secret_masked(self, obj):
        return obj.mask_key(obj.get_stripe_webhook_secret())

    def get_has_stripe_keys(self, obj):
        return obj.has_stripe_keys()

    def get_stripe_keys_from_env(self, obj):
        return obj.stripe_keys_from_env()


class StripeKeysUpdateSerializer(serializers.Serializer):
    """Serializer for updating Stripe keys"""
    stripe_secret_key = serializers.CharField(required=False, allow_blank=True)
    stripe_publishable_key = serializers.CharField(required=False, allow_blank=True)
    stripe_webhook_secret = serializers.CharField(required=False, allow_blank=True)


class OAuthSettingsSerializer(serializers.Serializer):
    """Serializer for OAuth settings"""
    oauth_allow_registration = serializers.BooleanField(required=False, default=True)

    # Google
    oauth_google_enabled = serializers.BooleanField(required=False, default=False)
    oauth_google_client_id = serializers.CharField(required=False, allow_blank=True)
    oauth_google_client_secret = serializers.CharField(required=False, allow_blank=True)

    # Apple
    oauth_apple_enabled = serializers.BooleanField(required=False, default=False)
    oauth_apple_client_id = serializers.CharField(required=False, allow_blank=True)
    oauth_apple_client_secret = serializers.CharField(required=False, allow_blank=True)
    oauth_apple_team_id = serializers.CharField(required=False, allow_blank=True)
    oauth_apple_key_id = serializers.CharField(required=False, allow_blank=True)

    # Facebook
    oauth_facebook_enabled = serializers.BooleanField(required=False, default=False)
    oauth_facebook_client_id = serializers.CharField(required=False, allow_blank=True)
    oauth_facebook_client_secret = serializers.CharField(required=False, allow_blank=True)

    # LinkedIn
    oauth_linkedin_enabled = serializers.BooleanField(required=False, default=False)
    oauth_linkedin_client_id = serializers.CharField(required=False, allow_blank=True)
    oauth_linkedin_client_secret = serializers.CharField(required=False, allow_blank=True)

    # Microsoft
    oauth_microsoft_enabled = serializers.BooleanField(required=False, default=False)
    oauth_microsoft_client_id = serializers.CharField(required=False, allow_blank=True)
    oauth_microsoft_client_secret = serializers.CharField(required=False, allow_blank=True)
    oauth_microsoft_tenant_id = serializers.CharField(required=False, allow_blank=True)

    # Twitter
    oauth_twitter_enabled = serializers.BooleanField(required=False, default=False)
    oauth_twitter_client_id = serializers.CharField(required=False, allow_blank=True)
    oauth_twitter_client_secret = serializers.CharField(required=False, allow_blank=True)

    # Twitch
    oauth_twitch_enabled = serializers.BooleanField(required=False, default=False)
    oauth_twitch_client_id = serializers.CharField(required=False, allow_blank=True)
    oauth_twitch_client_secret = serializers.CharField(required=False, allow_blank=True)


class OAuthSettingsResponseSerializer(serializers.Serializer):
    """Response serializer for OAuth settings (with masked secrets)"""
    oauth_allow_registration = serializers.BooleanField()
    google = serializers.DictField()
    apple = serializers.DictField()
    facebook = serializers.DictField()
    linkedin = serializers.DictField()
    microsoft = serializers.DictField()
    twitter = serializers.DictField()
    twitch = serializers.DictField()


class SubscriptionPlanSerializer(serializers.ModelSerializer):
    """Serializer for subscription plans"""

    class Meta:
        model = SubscriptionPlan
        fields = [
            'id', 'name', 'description', 'plan_type',
            'stripe_product_id', 'stripe_price_id',
            'price_monthly', 'price_yearly',
            'features', 'limits', 'permissions',
            'transaction_fee_percent', 'transaction_fee_fixed',
            # SMS & Communication Settings
            'sms_enabled', 'sms_price_per_message_cents',
            # Masked Calling Settings
            'masked_calling_enabled', 'masked_calling_price_per_minute_cents',
            # Proxy Number Settings
            'proxy_number_enabled', 'proxy_number_monthly_fee_cents',
            # Contracts Feature
            'contracts_enabled',
            # Default Credit Settings
            'default_auto_reload_enabled', 'default_auto_reload_threshold_cents',
            'default_auto_reload_amount_cents',
            # Status flags
            'is_active', 'is_public', 'is_most_popular', 'show_price',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']


class SubscriptionPlanCreateSerializer(serializers.ModelSerializer):
    """Serializer for creating subscription plans with optional Stripe integration"""
    create_stripe_product = serializers.BooleanField(default=False, write_only=True)

    class Meta:
        model = SubscriptionPlan
        fields = [
            'name', 'description', 'plan_type',
            'stripe_product_id', 'stripe_price_id',
            'price_monthly', 'price_yearly',
            'features', 'limits', 'permissions',
            'transaction_fee_percent', 'transaction_fee_fixed',
            # SMS & Communication Settings
            'sms_enabled', 'sms_price_per_message_cents',
            # Masked Calling Settings
            'masked_calling_enabled', 'masked_calling_price_per_minute_cents',
            # Proxy Number Settings
            'proxy_number_enabled', 'proxy_number_monthly_fee_cents',
            # Contracts Feature
            'contracts_enabled',
            # Default Credit Settings
            'default_auto_reload_enabled', 'default_auto_reload_threshold_cents',
            'default_auto_reload_amount_cents',
            # Status flags
            'is_active', 'is_public', 'is_most_popular', 'show_price',
            'create_stripe_product'
        ]

    def create(self, validated_data):
        create_stripe = validated_data.pop('create_stripe_product', False)

        if create_stripe and validated_data.get('price_monthly'):
            # Create Stripe product and price
            import stripe
            from django.conf import settings

            stripe.api_key = settings.STRIPE_SECRET_KEY

            try:
                # Create product
                product = stripe.Product.create(
                    name=validated_data['name'],
                    description=validated_data.get('description', ''),
                    metadata={'plan_type': validated_data.get('plan_type', 'base')}
                )
                validated_data['stripe_product_id'] = product.id

                # Create price
                price = stripe.Price.create(
                    product=product.id,
                    unit_amount=int(validated_data['price_monthly'] * 100),  # Convert to cents
                    currency='usd',
                    recurring={'interval': 'month'}
                )
                validated_data['stripe_price_id'] = price.id

            except stripe.error.StripeError as e:
                raise serializers.ValidationError({'stripe': str(e)})

        return super().create(validated_data)


class TenantSerializer(serializers.ModelSerializer):
    """Serializer for Tenant (Business) listing"""
    subdomain = serializers.SerializerMethodField()
    tier = serializers.SerializerMethodField()
    user_count = serializers.SerializerMethodField()
    owner = serializers.SerializerMethodField()
    # Entitlements from billing system
    limits = serializers.SerializerMethodField()
    features = serializers.SerializerMethodField()

    class Meta:
        model = Tenant
        fields = [
            'id', 'name', 'subdomain', 'tier', 'is_active',
            'created_on', 'user_count', 'owner', 'contact_email', 'phone',
            'limits', 'features',
        ]
        read_only_fields = fields

    def get_subdomain(self, obj):
        """Get primary subdomain for this tenant"""
        primary_domain = obj.domains.filter(is_primary=True, is_custom_domain=False).first()
        if primary_domain:
            # Extract subdomain from domain (e.g., 'business1.lvh.me' -> 'business1')
            return primary_domain.domain.split('.')[0]
        return obj.schema_name

    def get_tier(self, obj):
        """Get subscription tier from billing system"""
        if hasattr(obj, 'billing_subscription') and obj.billing_subscription:
            subscription = obj.billing_subscription
            if subscription.plan_version and subscription.plan_version.plan:
                return subscription.plan_version.plan.name
        return 'Free'

    def get_user_count(self, obj):
        """Get count of users in this tenant's schema"""
        # This requires querying the tenant schema
        # For now, return 0 - we can optimize this with annotations
        return 0

    def get_owner(self, obj):
        """Get the tenant owner user"""
        # Query public schema for users with this tenant as their business
        try:
            owner = User.objects.filter(
                role=User.Role.TENANT_OWNER,
                tenant=obj
            ).first()

            if owner:
                return {
                    'id': owner.id,
                    'username': owner.username,
                    'full_name': owner.full_name,
                    'email': owner.email,
                    'role': owner.role.lower(),
                    'email_verified': owner.email_verified,
                }
        except:
            pass
        return None

    def get_limits(self, obj):
        """Get limit entitlements from billing system"""
        limits = {}
        limit_keys = ['max_users', 'max_resources', 'max_locations', 'max_pages']
        for key in limit_keys:
            limits[key] = obj.get_limit(key)
        return limits

    def get_features(self, obj):
        """Get feature entitlements from billing system"""
        features = {}
        feature_keys = [
            'sms_reminders', 'webhooks', 'api_access', 'custom_domain',
            'white_label', 'custom_oauth', 'automations', 'can_create_automations',
            'tasks', 'export_data', 'video_conferencing', 'two_factor_auth',
            'masked_calling', 'pos_system', 'mobile_app', 'contracts',
            'multi_location',
        ]
        for key in feature_keys:
            features[key] = obj.has_feature(key)
        return features


class TenantUpdateSerializer(serializers.ModelSerializer):
    """
    Serializer for updating Tenant (platform admins only).

    Note: Feature permissions and limits are now managed via the billing system
    (Subscription model). Use the billing API to update entitlements.
    """

    class Meta:
        model = Tenant
        fields = [
            'id', 'name', 'is_active', 'contact_email', 'phone',
        ]
        read_only_fields = ['id']

    def update(self, instance, validated_data):
        """Update tenant with validated data"""
        from django_tenants.utils import schema_context

        for attr, value in validated_data.items():
            setattr(instance, attr, value)

        # Must save in public schema
        with schema_context('public'):
            instance.save()
        return instance


class TenantCreateSerializer(serializers.Serializer):
    """
    Serializer for creating a new Tenant with domain.

    Note: Feature permissions and limits are now managed via the billing system.
    The tenant will be assigned a default Free plan on creation.
    """
    # Required fields
    name = serializers.CharField(max_length=100)
    subdomain = serializers.CharField(max_length=63)  # Max subdomain length

    # Optional fields with defaults
    is_active = serializers.BooleanField(default=True)
    contact_email = serializers.EmailField(required=False, allow_blank=True)
    phone = serializers.CharField(max_length=20, required=False, allow_blank=True)

    # Owner details (optional - create owner user if provided)
    owner_email = serializers.EmailField(required=False)
    owner_name = serializers.CharField(max_length=150, required=False)
    owner_password = serializers.CharField(max_length=128, required=False, write_only=True)

    def validate_subdomain(self, value):
        """Validate subdomain is unique and valid"""
        import re

        # Check format (lowercase alphanumeric and hyphens, must start with letter)
        if not re.match(r'^[a-z][a-z0-9-]*$', value.lower()):
            raise serializers.ValidationError(
                "Subdomain must start with a letter and contain only lowercase letters, numbers, and hyphens"
            )

        # Check if subdomain already exists as schema_name
        if Tenant.objects.filter(schema_name=value.lower()).exists():
            raise serializers.ValidationError("This subdomain is already taken")

        # Check if domain already exists
        domain_name = f"{value.lower()}.lvh.me"  # TODO: Make base domain configurable
        if Domain.objects.filter(domain=domain_name).exists():
            raise serializers.ValidationError("This subdomain is already taken")

        # Reserved subdomains
        reserved = ['www', 'api', 'admin', 'platform', 'app', 'mail', 'smtp', 'ftp', 'public']
        if value.lower() in reserved:
            raise serializers.ValidationError("This subdomain is reserved")

        return value.lower()

    def validate(self, attrs):
        """Cross-field validation"""
        # If owner email is provided, name and password should also be provided
        owner_email = attrs.get('owner_email')
        owner_name = attrs.get('owner_name')
        owner_password = attrs.get('owner_password')

        if owner_email:
            if not owner_name:
                raise serializers.ValidationError({
                    'owner_name': 'Owner name is required when creating an owner'
                })
            if not owner_password:
                raise serializers.ValidationError({
                    'owner_password': 'Owner password is required when creating an owner'
                })
            # Check if email already exists
            if User.objects.filter(email=owner_email).exists():
                raise serializers.ValidationError({
                    'owner_email': 'A user with this email already exists'
                })

        return attrs

    def create(self, validated_data):
        """Create tenant, domain, and optionally owner user"""
        from django.db import transaction
        from django_tenants.utils import schema_context

        subdomain = validated_data.pop('subdomain')
        owner_email = validated_data.pop('owner_email', None)
        owner_name = validated_data.pop('owner_name', None)
        owner_password = validated_data.pop('owner_password', None)

        # Must create tenant in public schema
        with schema_context('public'):
            with transaction.atomic():
                # Create tenant
                tenant = Tenant.objects.create(
                    schema_name=subdomain,
                    name=validated_data.get('name'),
                    is_active=validated_data.get('is_active', True),
                    contact_email=validated_data.get('contact_email', ''),
                    phone=validated_data.get('phone', ''),
                )

                # Create primary domain
                domain_name = f"{subdomain}.lvh.me"  # TODO: Make base domain configurable
                Domain.objects.create(
                    domain=domain_name,
                    tenant=tenant,
                    is_primary=True,
                    is_custom_domain=False,
                )

                # Create owner user if details provided
                if owner_email and owner_name and owner_password:
                    # Split name into first/last
                    name_parts = owner_name.split(' ', 1)
                    first_name = name_parts[0]
                    last_name = name_parts[1] if len(name_parts) > 1 else ''

                    User.objects.create_user(
                        username=owner_email,  # Use email as username
                        email=owner_email,
                        password=owner_password,
                        first_name=first_name,
                        last_name=last_name,
                        role=User.Role.TENANT_OWNER,
                        tenant=tenant,
                    )

        return tenant


class PlatformUserSerializer(serializers.ModelSerializer):
    """Serializer for User listing (platform view)"""
    business = serializers.SerializerMethodField()
    business_name = serializers.SerializerMethodField()
    business_subdomain = serializers.SerializerMethodField()
    full_name = serializers.SerializerMethodField()
    role = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = [
            'id', 'email', 'username', 'first_name', 'last_name', 'full_name', 'role',
            'is_active', 'is_staff', 'is_superuser', 'email_verified', 'permissions',
            'business', 'business_name', 'business_subdomain',
            'date_joined', 'last_login', 'created_at'
        ]
        read_only_fields = fields

    def get_role(self, obj):
        return obj.role.lower()

    def get_full_name(self, obj):
        """Get user's full name"""
        return obj.full_name

    def get_business(self, obj):
        """Get tenant ID if user belongs to a tenant"""
        if obj.tenant:
            return obj.tenant.id
        return None

    def get_business_name(self, obj):
        """Get tenant name if user belongs to a tenant"""
        if obj.tenant:
            return obj.tenant.name
        return None

    def get_business_subdomain(self, obj):
        """Get tenant subdomain if user belongs to a tenant"""
        if obj.tenant:
            primary_domain = obj.tenant.domains.filter(is_primary=True, is_custom_domain=False).first()
            if primary_domain:
                return primary_domain.domain.split('.')[0]
            return obj.tenant.schema_name
        return None


class PlatformMetricsSerializer(serializers.Serializer):
    """Serializer for platform dashboard metrics"""
    total_tenants = serializers.IntegerField()
    active_tenants = serializers.IntegerField()
    total_users = serializers.IntegerField()
    mrr = serializers.DecimalField(max_digits=10, decimal_places=2)
    growth_rate = serializers.FloatField()


class TenantInvitationSerializer(serializers.ModelSerializer):
    """Serializer for TenantInvitation model"""
    invited_by_email = serializers.ReadOnlyField(source='invited_by.email')
    created_tenant_name = serializers.ReadOnlyField(source='created_tenant.name')
    created_user_email = serializers.ReadOnlyField(source='created_user.email')

    class Meta:
        model = TenantInvitation
        fields = [
            'id', 'email', 'token', 'status', 'suggested_business_name',
            'subscription_tier', 'custom_max_users', 'custom_max_resources',
            'permissions', 'limits', 'personal_message', 'invited_by',
            'invited_by_email', 'created_at', 'expires_at', 'accepted_at',
            'created_tenant', 'created_tenant_name', 'created_user', 'created_user_email',
        ]
        read_only_fields = ['id', 'token', 'status', 'created_at', 'expires_at', 'accepted_at',
                            'created_tenant', 'created_tenant_name', 'created_user', 'created_user_email',
                            'invited_by_email']
        extra_kwargs = {
            'invited_by': {'write_only': True}, # Only send on creation
        }

    def validate_permissions(self, value):
        """Validate that permissions is a dictionary with boolean values"""
        if not isinstance(value, dict):
            raise serializers.ValidationError("Permissions must be a dictionary.")
        for key, val in value.items():
            if not isinstance(val, bool):
                raise serializers.ValidationError(f"Permission '{key}' must be a boolean.")
        return value

    def validate_limits(self, value):
        """Validate that limits is a dictionary with valid values"""
        if not isinstance(value, dict):
            raise serializers.ValidationError("Limits must be a dictionary.")

        # Validate each key's value type
        boolean_keys = [
            'can_add_video_conferencing', 'can_connect_to_api', 'can_book_repeated_events',
            'can_require_2fa', 'can_download_logs', 'can_delete_data',
            'can_use_masked_phone_numbers', 'can_use_pos', 'can_use_mobile_app'
        ]
        integer_keys = ['max_event_types', 'max_calendars_connected']

        for key, val in value.items():
            if key in boolean_keys and not isinstance(val, bool):
                raise serializers.ValidationError(f"Limit '{key}' must be a boolean.")
            if key in integer_keys and val is not None and not isinstance(val, int):
                raise serializers.ValidationError(f"Limit '{key}' must be an integer or null.")

        return value


class TenantInvitationCreateSerializer(serializers.ModelSerializer):
    """Serializer for creating TenantInvitations - sets invited_by automatically"""
    class Meta:
        model = TenantInvitation
        fields = [
            'email', 'suggested_business_name', 'subscription_tier',
            'custom_max_users', 'custom_max_resources', 'permissions', 'limits',
            'personal_message',
        ]

    def validate_limits(self, value):
        """Validate that limits is a dictionary with valid values"""
        if not isinstance(value, dict):
            raise serializers.ValidationError("Limits must be a dictionary.")

        # Validate each key's value type
        boolean_keys = [
            'can_add_video_conferencing', 'can_connect_to_api', 'can_book_repeated_events',
            'can_require_2fa', 'can_download_logs', 'can_delete_data',
            'can_use_masked_phone_numbers', 'can_use_pos', 'can_use_mobile_app'
        ]
        integer_keys = ['max_event_types', 'max_calendars_connected']

        for key, val in value.items():
            if key in boolean_keys and not isinstance(val, bool):
                raise serializers.ValidationError(f"Limit '{key}' must be a boolean.")
            if key in integer_keys and val is not None and not isinstance(val, int):
                raise serializers.ValidationError(f"Limit '{key}' must be an integer or null.")

        return value

    def create(self, validated_data):
        validated_data['invited_by'] = self.context['request'].user
        return super().create(validated_data)


class TenantInvitationAcceptSerializer(serializers.Serializer):
    """Serializer for accepting a TenantInvitation"""
    email = serializers.EmailField()
    password = serializers.CharField(max_length=128, write_only=True)
    first_name = serializers.CharField(max_length=150)
    last_name = serializers.CharField(max_length=150)
    business_name = serializers.CharField(max_length=100)
    subdomain = serializers.CharField(max_length=63)
    contact_email = serializers.EmailField(required=False, allow_blank=True)
    phone = serializers.CharField(max_length=20, required=False, allow_blank=True)

    def validate_subdomain(self, value):
        """Validate subdomain is unique and valid"""
        import re
        from smoothschedule.identity.core.models import Tenant, Domain

        # Check format (lowercase alphanumeric and hyphens, must start with letter)
        if not re.match(r'^[a-z][a-z0-9-]*$', value.lower()):
            raise serializers.ValidationError(
                "Subdomain must start with a letter and contain only lowercase letters, numbers, and hyphens"
            )

        # Check if subdomain already exists as schema_name
        if Tenant.objects.filter(schema_name=value.lower()).exists():
            raise serializers.ValidationError("This subdomain is already taken")

        # Check if domain already exists
        domain_name = f"{value.lower()}.lvh.me"  # TODO: Make base domain configurable
        if Domain.objects.filter(domain=domain_name).exists():
            raise serializers.ValidationError("This subdomain is already taken")

        # Reserved subdomains
        reserved = ['www', 'api', 'admin', 'platform', 'app', 'mail', 'smtp', 'ftp', 'public']
        if value.lower() in reserved:
            raise serializers.ValidationError("This subdomain is reserved")

        return value.lower()

    def validate_email(self, value):
        """Validate email is unique for owner user"""
        if User.objects.filter(email=value).exists():
            raise serializers.ValidationError("A user with this email already exists.")
        return value


class TenantInvitationDetailSerializer(TenantInvitationSerializer):
    """Serializer to display invitation details without requiring authentication"""
    class Meta(TenantInvitationSerializer.Meta):
        read_only_fields = ['id', 'email', 'token', 'status', 'suggested_business_name',
                            'subscription_tier', 'custom_max_users', 'custom_max_resources',
                            'permissions', 'personal_message', 'created_at', 'expires_at',
                            'accepted_at', 'created_tenant', 'created_user', 'invited_by_email',
                            'created_tenant_name', 'created_user_email']
        extra_kwargs = {
            'invited_by': {'read_only': True},
        }


class AssignedUserSerializer(serializers.Serializer):
    """Lightweight serializer for assigned user info."""
    id = serializers.IntegerField(read_only=True)
    email = serializers.EmailField(read_only=True)
    first_name = serializers.CharField(read_only=True)
    last_name = serializers.CharField(read_only=True)
    full_name = serializers.SerializerMethodField()

    def get_full_name(self, obj):
        return obj.get_full_name() or obj.email


class PlatformEmailAddressListSerializer(serializers.ModelSerializer):
    """Lightweight serializer for listing platform email addresses."""
    email_address = serializers.ReadOnlyField()
    effective_sender_name = serializers.ReadOnlyField()
    assigned_user = AssignedUserSerializer(read_only=True)

    class Meta:
        model = PlatformEmailAddress
        fields = [
            'id', 'display_name', 'sender_name', 'effective_sender_name',
            'local_part', 'domain', 'email_address', 'color',
            'assigned_user',
            'is_active', 'is_default', 'mail_server_synced',
            'last_check_at', 'emails_processed_count',
            'created_at', 'updated_at'
        ]
        read_only_fields = [
            'email_address', 'effective_sender_name', 'mail_server_synced',
            'last_check_at', 'emails_processed_count',
            'created_at', 'updated_at'
        ]


class PlatformEmailAddressSerializer(serializers.ModelSerializer):
    """Full serializer for platform email addresses."""
    email_address = serializers.ReadOnlyField()
    effective_sender_name = serializers.ReadOnlyField()
    assigned_user = AssignedUserSerializer(read_only=True)
    assigned_user_id = serializers.IntegerField(
        write_only=True,
        required=False,
        allow_null=True
    )
    imap_settings = serializers.SerializerMethodField()
    smtp_settings = serializers.SerializerMethodField()

    class Meta:
        model = PlatformEmailAddress
        fields = [
            'id', 'display_name', 'sender_name', 'effective_sender_name',
            'local_part', 'domain', 'email_address', 'color',
            'assigned_user', 'assigned_user_id',
            'password', 'is_active', 'is_default',
            'mail_server_synced', 'last_sync_error', 'last_synced_at',
            'last_check_at', 'emails_processed_count',
            'created_at', 'updated_at',
            'imap_settings', 'smtp_settings'
        ]
        read_only_fields = [
            'email_address', 'effective_sender_name',
            'mail_server_synced', 'last_sync_error', 'last_synced_at',
            'last_check_at', 'emails_processed_count',
            'created_at', 'updated_at',
            'imap_settings', 'smtp_settings'
        ]
        extra_kwargs = {
            'password': {'write_only': True},
        }

    def validate_assigned_user_id(self, value):
        """Validate and convert assigned_user_id to User instance."""
        if value is None:
            return None
        from smoothschedule.identity.users.models import User
        try:
            user = User.objects.get(
                pk=value,
                role__in=['superuser', 'platform_manager', 'platform_support'],
                is_active=True
            )
            return user
        except User.DoesNotExist:
            raise serializers.ValidationError("User not found or not a platform user.")

    def create(self, validated_data):
        assigned_user = validated_data.pop('assigned_user_id', None)
        instance = super().create(validated_data)
        if assigned_user is not None:
            instance.assigned_user = assigned_user
            instance.save(update_fields=['assigned_user'])
        return instance

    def update(self, instance, validated_data):
        if 'assigned_user_id' in validated_data:
            instance.assigned_user = validated_data.pop('assigned_user_id')
        return super().update(instance, validated_data)

    def get_imap_settings(self, obj):
        """Return IMAP settings without password."""
        settings = obj.get_imap_settings()
        settings.pop('password', None)
        return settings

    def get_smtp_settings(self, obj):
        """Return SMTP settings without password."""
        settings = obj.get_smtp_settings()
        settings.pop('password', None)
        return settings

    def validate_local_part(self, value):
        """Validate local part of email address."""
        import re
        value = value.lower().strip()

        # Check format
        if not re.match(r'^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$', value):
            raise serializers.ValidationError(
                "Local part must start and end with a letter or number, "
                "and can only contain letters, numbers, dots, underscores, and hyphens"
            )

        if len(value) > 64:
            raise serializers.ValidationError("Local part cannot exceed 64 characters")

        return value

    def validate_password(self, value):
        """Validate password strength."""
        if len(value) < 8:
            raise serializers.ValidationError("Password must be at least 8 characters")
        return value

    def validate(self, attrs):
        """Cross-field validation."""
        local_part = attrs.get('local_part', getattr(self.instance, 'local_part', None))
        domain = attrs.get('domain', getattr(self.instance, 'domain', None))

        if local_part and domain:
            # Check uniqueness
            qs = PlatformEmailAddress.objects.filter(
                local_part=local_part.lower(),
                domain=domain
            )
            if self.instance:
                qs = qs.exclude(pk=self.instance.pk)
            if qs.exists():
                raise serializers.ValidationError({
                    'local_part': f'Email address {local_part}@{domain} already exists'
                })

        return attrs


class PlatformEmailAddressCreateSerializer(PlatformEmailAddressSerializer):
    """Serializer for creating platform email addresses with mail server sync."""

    def create(self, validated_data):
        """Create the email address and sync to mail server."""
        from .mail_server import get_mail_server_service

        # Normalize local_part
        validated_data['local_part'] = validated_data['local_part'].lower()

        # Create the database record first
        instance = super().create(validated_data)

        # Sync to mail server
        service = get_mail_server_service()
        success, message = service.sync_account(instance)

        if not success:
            # Delete the database record if mail server sync failed
            instance.delete()
            raise serializers.ValidationError({
                'mail_server': f'Failed to create email account on mail server: {message}'
            })

        return instance


class PlatformEmailAddressUpdateSerializer(serializers.ModelSerializer):
    """Serializer for updating platform email addresses."""
    email_address = serializers.ReadOnlyField()
    assigned_user_id = serializers.IntegerField(
        write_only=True,
        required=False,
        allow_null=True
    )

    class Meta:
        model = PlatformEmailAddress
        fields = [
            'id', 'display_name', 'sender_name', 'email_address', 'color',
            'assigned_user_id',
            'password', 'is_active', 'is_default'
        ]
        read_only_fields = ['id', 'email_address']
        extra_kwargs = {
            'password': {'write_only': True, 'required': False},
            'sender_name': {'required': False},
        }

    def validate_assigned_user_id(self, value):
        """Validate and convert assigned_user_id to User instance."""
        if value is None:
            return None
        from smoothschedule.identity.users.models import User
        try:
            user = User.objects.get(
                pk=value,
                role__in=['superuser', 'platform_manager', 'platform_support'],
                is_active=True
            )
            return user
        except User.DoesNotExist:
            raise serializers.ValidationError("User not found or not a platform user.")

    def validate_password(self, value):
        """Validate password strength if provided."""
        if value and len(value) < 8:
            raise serializers.ValidationError("Password must be at least 8 characters")
        return value

    def update(self, instance, validated_data):
        """Update the email address and sync password to mail server if changed."""
        from .mail_server import get_mail_server_service

        password = validated_data.get('password')
        password_changed = password and password != instance.password

        # Handle assigned_user_id separately
        if 'assigned_user_id' in validated_data:
            instance.assigned_user = validated_data.pop('assigned_user_id')

        # Update the instance
        instance = super().update(instance, validated_data)

        # Sync to mail server if password changed
        if password_changed:
            service = get_mail_server_service()
            success, message = service.sync_account(instance)

            if not success:
                raise serializers.ValidationError({
                    'mail_server': f'Failed to update password on mail server: {message}'
                })

        return instance

