from rest_framework import permissions, status
from rest_framework.response import Response
from rest_framework.throttling import ScopedRateThrottle
from rest_framework.views import APIView

from .models import LeadSubmission
from .serializers import LeadSubmissionSerializer
from .services import (
    find_duplicate,
    get_client_ip,
    get_lead_settings,
    infer_device_type,
    send_lead_emails,
)


class LeadSubmitAPIView(APIView):
    permission_classes = [permissions.AllowAny]
    throttle_classes = [ScopedRateThrottle]
    throttle_scope = "lead_submit"

    forced_lead_type = None

    def post(self, request):
        payload = dict(request.data)
        if self.forced_lead_type:
            payload["lead_type"] = self.forced_lead_type

        serializer = LeadSubmissionSerializer(data=payload)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data

        settings_obj = get_lead_settings()
        if not settings_obj.enable_public_forms:
            return Response(
                {
                    "success": False,
                    "message": "Lead submissions are temporarily unavailable.",
                    "code": "forms_disabled",
                },
                status=status.HTTP_503_SERVICE_UNAVAILABLE,
            )

        honeypot_value = (data.get("honeypot") or "").strip()
        if honeypot_value:
            lead = LeadSubmission.objects.create(
                lead_type=data["lead_type"],
                status=LeadSubmission.STATUS_SPAM,
                is_spam=True,
                honeypot=honeypot_value,
                source_page_url=data.get("source_page_url", ""),
                source_page_name=data.get("source_page_name", ""),
                source_page_type=data.get("source_page_type", ""),
                campaign_source=data.get("campaign_source", ""),
                referral_source=data.get("referral_source", ""),
                user_agent=data.get("user_agent", "") or request.META.get("HTTP_USER_AGENT", ""),
                ip_address=get_client_ip(request),
            )
            return Response(
                {
                    "success": True,
                    "message": "Thank you. We received your interest.",
                    "data": {"id": str(lead.id), "status": lead.status, "duplicate": False},
                }
            )

        duplicate = find_duplicate(
            lead_type=data["lead_type"],
            email=(data.get("email") or "").strip(),
            mobile_number=(data.get("mobile_number") or "").strip(),
            source_page_url=(data.get("source_page_url") or "").strip(),
        )
        if duplicate.is_duplicate and duplicate.existing:
            return Response(
                {
                    "success": True,
                    "message": "We already received your request recently. Our team will contact you soon.",
                    "data": {
                        "id": str(duplicate.existing.id),
                        "status": duplicate.existing.status,
                        "duplicate": True,
                    },
                }
            )

        user_agent = data.get("user_agent", "") or request.META.get("HTTP_USER_AGENT", "")

        lead = LeadSubmission.objects.create(
            lead_type=data["lead_type"],
            full_name=(data.get("full_name") or "").strip(),
            email=(data.get("email") or "").strip(),
            mobile_number=(data.get("mobile_number") or "").strip(),
            city=(data.get("city") or "").strip(),
            interested_category=(data.get("interested_category") or "").strip(),
            subject=(data.get("subject") or "").strip(),
            message=(data.get("message") or "").strip(),
            notes=(data.get("notes") or "").strip(),
            source_page_url=(data.get("source_page_url") or "").strip(),
            source_page_name=(data.get("source_page_name") or "").strip(),
            source_page_type=(data.get("source_page_type") or "").strip(),
            campaign_source=(data.get("campaign_source") or "").strip(),
            referral_source=(data.get("referral_source") or "").strip(),
            payload=data.get("payload") or {},
            user_agent=user_agent,
            device_info=infer_device_type(user_agent),
            ip_address=get_client_ip(request),
        )

        send_lead_emails(lead, settings_obj)

        return Response(
            {
                "success": True,
                "message": "Thank you. We received your interest.",
                "data": {"id": str(lead.id), "status": lead.status, "duplicate": False},
            },
            status=status.HTTP_201_CREATED,
        )


class NewsletterLeadSubmitAPIView(LeadSubmitAPIView):
    forced_lead_type = LeadSubmission.LEAD_TYPE_NEWSLETTER


class WaitlistLeadSubmitAPIView(LeadSubmitAPIView):
    forced_lead_type = LeadSubmission.LEAD_TYPE_WAITLIST


class ContactLeadSubmitAPIView(LeadSubmitAPIView):
    forced_lead_type = LeadSubmission.LEAD_TYPE_CONTACT


class PartnerLeadSubmitAPIView(LeadSubmitAPIView):
    forced_lead_type = LeadSubmission.LEAD_TYPE_PARTNER
