"""
Serializers for Contract/E-Signature system.
"""
from rest_framework import serializers
from .models import ContractTemplate, ServiceContractRequirement, Contract, ContractSignature


class ContractTemplateSerializer(serializers.ModelSerializer):
    """Full serializer for template CRUD"""
    services = serializers.SerializerMethodField()
    created_by_name = serializers.SerializerMethodField()

    class Meta:
        model = ContractTemplate
        fields = [
            "id", "name", "description", "content", "scope", "status",
            "expires_after_days", "version", "version_notes", "services",
            "created_by", "created_by_name", "created_at", "updated_at"
        ]
        read_only_fields = ["version", "created_by", "created_at", "updated_at"]

    def get_services(self, obj):
        requirements = obj.service_requirements.select_related("service")
        return [{"id": r.service.id, "name": r.service.name} for r in requirements]

    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


class ContractTemplateListSerializer(serializers.ModelSerializer):
    """Lightweight serializer for dropdowns/lists"""
    class Meta:
        model = ContractTemplate
        fields = ["id", "name", "description", "content", "scope", "status", "version", "expires_after_days"]


class ServiceContractRequirementSerializer(serializers.ModelSerializer):
    template_name = serializers.CharField(source="template.name", read_only=True)
    template_scope = serializers.CharField(source="template.scope", read_only=True)
    service_name = serializers.CharField(source="service.name", read_only=True)

    class Meta:
        model = ServiceContractRequirement
        fields = [
            "id", "service", "service_name", "template", "template_name",
            "template_scope", "display_order", "is_required", "created_at"
        ]


class ContractSignatureSerializer(serializers.ModelSerializer):
    class Meta:
        model = ContractSignature
        fields = [
            "signed_at", "signer_name", "signer_email", "ip_address",
            "consent_checkbox_checked", "electronic_consent_given"
        ]


class ContractSerializer(serializers.ModelSerializer):
    customer_name = serializers.SerializerMethodField()
    customer_email = serializers.CharField(source="customer.email", read_only=True)
    template_name = serializers.SerializerMethodField()
    is_signed = serializers.SerializerMethodField()
    signature_details = ContractSignatureSerializer(source="signature", read_only=True)
    signing_url = serializers.SerializerMethodField()

    class Meta:
        model = Contract
        fields = [
            "id", "template", "template_name", "template_version", "title",
            "content_html", "customer", "customer_name", "customer_email",
            "event", "status", "expires_at", "is_signed", "signature_details",
            "signing_url", "pdf_path", "sent_at", "created_at", "updated_at"
        ]
        read_only_fields = [
            "template_version", "content_html", "content_hash",
            "signing_token", "sent_at", "created_at", "updated_at"
        ]

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

    def get_template_name(self, obj):
        return obj.template.name if obj.template else obj.title

    def get_is_signed(self, obj):
        return obj.status == Contract.Status.SIGNED

    def get_signing_url(self, obj):
        request = self.context.get("request")
        return obj.get_signing_url(request)


class ContractListSerializer(serializers.ModelSerializer):
    """Lightweight serializer for contract lists"""
    customer_name = serializers.SerializerMethodField()
    customer_email = serializers.CharField(source="customer.email", read_only=True)
    template_name = serializers.SerializerMethodField()
    is_signed = serializers.SerializerMethodField()
    signed_at = serializers.SerializerMethodField()

    class Meta:
        model = Contract
        fields = [
            "id", "template", "title", "content_html", "customer", "customer_name", "customer_email",
            "status", "is_signed", "template_name", "template_version", "expires_at",
            "sent_at", "signed_at", "created_at", "signing_token"
        ]

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

    def get_template_name(self, obj):
        return obj.template.name if obj.template else obj.title

    def get_is_signed(self, obj):
        return obj.status == Contract.Status.SIGNED

    def get_signed_at(self, obj):
        if hasattr(obj, 'signature') and obj.signature:
            return obj.signature.signed_at
        return None


class PublicContractSerializer(serializers.Serializer):
    """Serializer for public signing endpoint (no auth required)"""

    def to_representation(self, instance):
        from django.db import connection
        from django.utils import timezone
        from smoothschedule.identity.core.models import Tenant

        # Get business info
        try:
            tenant = Tenant.objects.get(schema_name=connection.schema_name)
            business_name = tenant.name
            business_logo = tenant.logo.url if tenant.logo else None
        except (Tenant.DoesNotExist, ValueError):
            business_name = "Business"
            business_logo = None

        # Check expiration
        is_expired = bool(instance.expires_at and timezone.now() > instance.expires_at)

        # Can sign if pending and not expired
        can_sign = instance.status == Contract.Status.PENDING and not is_expired

        # Get signature if exists
        signature_data = None
        if hasattr(instance, 'signature') and instance.signature:
            sig = instance.signature
            signature_data = {
                "signer_name": sig.signer_name,
                "signer_email": sig.signer_email,
                "signed_at": sig.signed_at.isoformat() if sig.signed_at else None,
            }

        return {
            "contract": {
                "id": str(instance.id),
                "title": instance.title,
                "content": instance.content_html,
                "status": instance.status,
                "expires_at": instance.expires_at.isoformat() if instance.expires_at else None,
            },
            "template": {
                "name": instance.template.name if instance.template else instance.title,
                "content": instance.content_html,
            },
            "business": {
                "name": business_name,
                "logo_url": business_logo,
            },
            "customer": {
                "name": instance.customer.get_full_name() or instance.customer.email,
                "email": instance.customer.email,
            } if instance.customer else None,
            "appointment": {
                "service_name": instance.event.service.name if instance.event and instance.event.service else None,
                "start_time": instance.event.start_time.isoformat() if instance.event else None,
            } if instance.event else None,
            "is_expired": is_expired,
            "can_sign": can_sign,
            "signature": signature_data,
        }


class ContractSignatureInputSerializer(serializers.Serializer):
    """Input for signing a contract"""
    consent_checkbox_checked = serializers.BooleanField()
    electronic_consent_given = serializers.BooleanField()
    signer_name = serializers.CharField(max_length=200)
    latitude = serializers.DecimalField(
        max_digits=9, decimal_places=6, required=False, allow_null=True
    )
    longitude = serializers.DecimalField(
        max_digits=9, decimal_places=6, required=False, allow_null=True
    )


class CreateContractSerializer(serializers.Serializer):
    """Input for creating a contract from template"""
    template = serializers.PrimaryKeyRelatedField(
        queryset=ContractTemplate.objects.filter(status=ContractTemplate.Status.ACTIVE)
    )
    customer_id = serializers.IntegerField()
    event_id = serializers.IntegerField(required=False, allow_null=True)
    send_email = serializers.BooleanField(default=True)

    def validate_customer_id(self, value):
        from smoothschedule.identity.users.models import User
        try:
            customer = User.objects.get(id=value, role=User.Role.CUSTOMER)
            return customer
        except User.DoesNotExist:
            raise serializers.ValidationError("Customer not found")

    def validate_event_id(self, value):
        if value is None:
            return None
        from smoothschedule.scheduling.schedule.models import Event
        try:
            return Event.objects.get(id=value)
        except Event.DoesNotExist:
            raise serializers.ValidationError("Event not found")

    def validate(self, attrs):
        # Transform the validated objects into proper fields
        attrs['customer'] = attrs.pop('customer_id')
        attrs['event'] = attrs.pop('event_id', None)
        return attrs
