import re

from rest_framework import serializers

from .models import LeadSubmission


_MOBILE_RE = re.compile(r"^[0-9+()\-\s]{8,20}$")


class LeadSubmissionSerializer(serializers.Serializer):
    lead_type = serializers.ChoiceField(choices=LeadSubmission.LEAD_TYPE_CHOICES)
    full_name = serializers.CharField(required=False, allow_blank=True, max_length=160)
    email = serializers.EmailField(required=False, allow_blank=True)
    mobile_number = serializers.CharField(required=False, allow_blank=True, max_length=20)
    city = serializers.CharField(required=False, allow_blank=True, max_length=120)
    interested_category = serializers.CharField(required=False, allow_blank=True, max_length=160)
    subject = serializers.CharField(required=False, allow_blank=True, max_length=255)
    message = serializers.CharField(required=False, allow_blank=True)
    notes = serializers.CharField(required=False, allow_blank=True)

    source_page_url = serializers.CharField(required=False, allow_blank=True, max_length=500)
    source_page_name = serializers.CharField(required=False, allow_blank=True, max_length=255)
    source_page_type = serializers.CharField(required=False, allow_blank=True, max_length=100)
    campaign_source = serializers.CharField(required=False, allow_blank=True, max_length=120)
    referral_source = serializers.CharField(required=False, allow_blank=True, max_length=255)

    user_agent = serializers.CharField(required=False, allow_blank=True)
    honeypot = serializers.CharField(required=False, allow_blank=True, max_length=255)
    payload = serializers.JSONField(required=False)

    def validate_mobile_number(self, value: str) -> str:
        value = (value or "").strip()
        if value and not _MOBILE_RE.match(value):
            raise serializers.ValidationError("Enter a valid mobile number.")
        return value

    def validate(self, attrs):
        lead_type = attrs.get("lead_type")
        email = (attrs.get("email") or "").strip()
        mobile = (attrs.get("mobile_number") or "").strip()

        requires_contact = {
            LeadSubmission.LEAD_TYPE_NEWSLETTER,
            LeadSubmission.LEAD_TYPE_WAITLIST,
            LeadSubmission.LEAD_TYPE_CONTACT,
            LeadSubmission.LEAD_TYPE_EARLY_ACCESS,
            LeadSubmission.LEAD_TYPE_PRODUCT,
            LeadSubmission.LEAD_TYPE_SERVICE,
            LeadSubmission.LEAD_TYPE_PARTNER,
            LeadSubmission.LEAD_TYPE_VENDOR,
            LeadSubmission.LEAD_TYPE_VOLUNTEER,
        }

        if lead_type in requires_contact and not email and not mobile:
            raise serializers.ValidationError("Email or mobile number is required.")

        return attrs
