from rest_framework import serializers
from organization.models import Organization, SyncLog, SyncConfiguration


class OrganizationSerializer(serializers.ModelSerializer):
    """Serializer for Organization model."""

    class Meta:
        model = Organization
        fields = [
            "organization_id",
            "name",
            "code",
            "email",
            "phone",
            "website",
            "description",
            "address_line1",
            "address_line2",
            "city",
            "state",
            "postal_code",
            "country",
            "external_id",
            "external_source",
            "status",
            "is_active",
            "created_at",
            "updated_at",
            "last_synced"
        ]
        read_only_fields = [
            "organization_id",
            "external_id",
            "external_source",
            "external_metadata",
            "created_at",
            "updated_at",
            "last_synced"
        ]

    def validate_email(self, value):
        """Validate email uniqueness."""
        instance = self.instance
        if instance:
            # Update case: check if email changed
            if instance.email != value:
                if Organization.objects.filter(email=value).exists():
                    raise serializers.ValidationError("This email is already in use.")
        else:
            # Create case
            if Organization.objects.filter(email=value).exists():
                raise serializers.ValidationError("This email is already in use.")
        return value

    def validate_code(self, value):
        """Validate code uniqueness."""
        instance = self.instance
        if instance:
            if instance.code != value:
                if Organization.objects.filter(code=value).exists():
                    raise serializers.ValidationError("This code is already in use.")
        else:
            if Organization.objects.filter(code=value).exists():
                raise serializers.ValidationError("This code is already in use.")
        return value


class SyncLogSerializer(serializers.ModelSerializer):
    """Serializer for SyncLog model."""

    success_rate = serializers.FloatField(read_only=True)
    is_successful = serializers.BooleanField(read_only=True)

    class Meta:
        model = SyncLog
        fields = [
            "sync_id",
            "external_source",
            "status",
            "started_at",
            "completed_at",
            "duration_seconds",
            "total_fetched",
            "created_count",
            "updated_count",
            "skipped_count",
            "error_count",
            "error_message",
            "triggered_by",
            "sync_type",
            "is_successful",
            "success_rate",
            "notes"
        ]
        read_only_fields = [
            "sync_id",
            "started_at",
            "completed_at",
            "duration_seconds"
        ]


class SyncConfigurationSerializer(serializers.ModelSerializer):
    """Serializer for SyncConfiguration model."""

    full_endpoint_url = serializers.CharField(read_only=True)

    class Meta:
        model = SyncConfiguration
        fields = [
            "config_id",
            "source_name",
            "base_url",
            "api_endpoint",
            "full_endpoint_url",
            "auth_type",
            "timeout_seconds",
            "max_retries",
            "retry_delay_seconds",
            "auto_sync_enabled",
            "auto_sync_interval_hours",
            "batch_size",
            "cache_enabled",
            "cache_ttl_seconds",
            "webhook_enabled",
            "is_active",
            "created_at",
            "updated_at",
            "last_tested_at",
            "last_test_successful"
        ]
        read_only_fields = [
            "config_id",
            "created_at",
            "updated_at",
            "last_tested_at",
            "last_test_successful"
        ]
        extra_kwargs = {
            "auth_key": {"write_only": True}  # Never expose auth key in response
        }

    def validate_base_url(self, value):
        """Validate base URL format."""
        if not value.startswith("http"):
            raise serializers.ValidationError(
                "Base URL must start with 'http://' or 'https://'"
            )
        return value

    def validate_timeout_seconds(self, value):
        """Validate timeout value."""
        if value < 1:
            raise serializers.ValidationError("Timeout must be at least 1 second")
        if value > 300:
            raise serializers.ValidationError("Timeout cannot exceed 300 seconds")
        return value

    def validate_max_retries(self, value):
        """Validate max retries."""
        if value < 0:
            raise serializers.ValidationError("Max retries cannot be negative")
        if value > 10:
            raise serializers.ValidationError("Max retries cannot exceed 10")
        return value


class SyncOrganizationRequestSerializer(serializers.Serializer):
    """Serializer for sync request validation."""

    source_name = serializers.CharField(
        required=False,
        help_text="Source configuration name (uses default if not specified)"
    )
    max_records = serializers.IntegerField(
        required=False,
        allow_null=True,
        min_value=1,
        help_text="Maximum organizations to sync (None = all)"
    )
    triggered_by = serializers.CharField(
        required=False,
        max_length=100,
        help_text="User/system triggering the sync"
    )

    def validate_source_name(self, value):
        """Validate source name exists and is active."""
        if value:
            try:
                config = SyncConfiguration.objects.get(
                    source_name=value,
                    is_active=True
                )
            except SyncConfiguration.DoesNotExist:
                raise serializers.ValidationError(
                    f"Sync configuration '{value}' not found or disabled"
                )
        return value


class SyncOrganizationResponseSerializer(serializers.Serializer):
    """Serializer for sync response."""

    sync_id = serializers.IntegerField()
    status = serializers.CharField()
    message = serializers.CharField()
    external_source = serializers.CharField()
    started_at = serializers.DateTimeField()
    completed_at = serializers.DateTimeField(allow_null=True)
    total_fetched = serializers.IntegerField()
    created_count = serializers.IntegerField()
    updated_count = serializers.IntegerField()
    error_count = serializers.IntegerField()
    duration_seconds = serializers.FloatField(allow_null=True)
    error_message = serializers.CharField(allow_blank=True)


class TestConnectionSerializer(serializers.Serializer):
    """Serializer for test connection response."""

    success = serializers.BooleanField()
    message = serializers.CharField()
    source_name = serializers.CharField()
    last_tested_at = serializers.DateTimeField()
