"""
线索提交接口。挂载在 /api/v1/custom/leads/（详见 apps/forms/urls.py 与
documents/设计方案分析与完善版.md §2.7 自定义业务接口设计）。
公开表单提交接口，限流走 DRF ScopedRateThrottle 的 "forms" scope（5/min，防刷）。

LeadDeletionRequestView/LeadDeletionConfirmView 支持 PIPL 数据主体删除权（§2.15）。
"""
import json
import logging

from django.conf import settings
from django.core.mail import send_mail
from django.utils import timezone
from rest_framework.response import Response
from rest_framework.throttling import ScopedRateThrottle
from rest_framework.views import APIView

from .models import FormDefinition, Lead, LeadDeletionRequest
from .serializers import (
    LeadDeletionConfirmSerializer,
    LeadDeletionRequestSerializer,
    LeadSubmitSerializer,
)

logger = logging.getLogger(__name__)


class LeadSubmitView(APIView):
    throttle_classes = [ScopedRateThrottle]
    throttle_scope = "forms"

    def post(self, request, *args, **kwargs):
        serializer = LeadSubmitSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        form_id = serializer.validated_data["form_id"]

        try:
            form_def = FormDefinition.objects.get(pk=form_id)
        except FormDefinition.DoesNotExist:
            return Response(
                {"error": {"code": "NOT_FOUND", "message": "表单不存在"}}, status=404
            )

        # 蜜罐反垃圾：honeypot 字段非空说明是自动化脚本提交，直接返回“成功”假象，
        # 不落库、不发通知邮件，避免打草惊蛇（详见设计文档 §2.15 验证码/反垃圾方案）。
        if serializer.validated_data.get("website"):
            return Response(
                {"success": True, "message": form_def.success_message}, status=201
            )

        lead = Lead.objects.create(
            form=form_def,
            data=serializer.validated_data["data"],
            source_url=serializer.validated_data.get("source_url", ""),
        )

        if form_def.notification_email:
            send_mail(
                subject=f"【新线索】{form_def.name}",
                message=json.dumps(lead.data, ensure_ascii=False, indent=2),
                from_email=getattr(settings, "DEFAULT_FROM_EMAIL", None),
                recipient_list=[form_def.notification_email],
                fail_silently=True,
            )

        return Response(
            {"success": True, "message": form_def.success_message}, status=201
        )


# PIPL 数据删除权：出于隐私考虑，无论邮箱是否存在关联数据，均返回相同的通用提示，
# 避免被用来探测某个邮箱是否曾提交过表单。
GENERIC_DELETION_REQUEST_MESSAGE = (
    "如果我们持有与该邮箱关联的信息，确认邮件将发送至该邮箱，请查收并点击链接完成删除确认。"
)


class LeadDeletionRequestView(APIView):
    """发起 PIPL 数据删除申请：POST {"contact": "user@example.com"}。"""

    throttle_classes = [ScopedRateThrottle]
    throttle_scope = "forms"

    def post(self, request, *args, **kwargs):
        serializer = LeadDeletionRequestSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        contact = serializer.validated_data["contact"]

        deletion_request = LeadDeletionRequest.objects.create(contact=contact)
        confirm_url = (
            f"{settings.FRONTEND_BASE_URL.rstrip('/')}/privacy-policy/delete-confirm"
            f"?token={deletion_request.token}"
        )
        try:
            send_mail(
                subject="确认删除您的个人信息",
                message=(
                    "我们收到了删除您个人信息的申请。如果这不是您本人操作，请忽略此邮件。\n\n"
                    f"请在 {LeadDeletionRequest.TOKEN_VALID_HOURS} 小时内点击以下链接确认删除：\n"
                    f"{confirm_url}"
                ),
                from_email=getattr(settings, "DEFAULT_FROM_EMAIL", None),
                recipient_list=[contact],
                fail_silently=False,
            )
        except Exception:
            logger.exception("发送删除确认邮件失败：%s", contact)

        return Response({"message": GENERIC_DELETION_REQUEST_MESSAGE}, status=202)


class LeadDeletionConfirmView(APIView):
    """确认 PIPL 数据删除申请：POST {"token": "..."}，校验通过后删除匹配的 Lead 记录。"""

    throttle_classes = [ScopedRateThrottle]
    throttle_scope = "forms"

    def post(self, request, *args, **kwargs):
        serializer = LeadDeletionConfirmSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        token = serializer.validated_data["token"]

        try:
            deletion_request = LeadDeletionRequest.objects.get(token=token)
        except LeadDeletionRequest.DoesNotExist:
            return Response(
                {"error": {"code": "INVALID_TOKEN", "message": "删除链接无效。"}},
                status=404,
            )

        if deletion_request.status != LeadDeletionRequest.STATUS_PENDING:
            return Response(
                {
                    "error": {
                        "code": "ALREADY_PROCESSED",
                        "message": "该删除申请已处理或已过期。",
                    }
                },
                status=400,
            )

        if deletion_request.is_expired:
            deletion_request.status = LeadDeletionRequest.STATUS_EXPIRED
            deletion_request.save(update_fields=["status"])
            return Response(
                {"error": {"code": "TOKEN_EXPIRED", "message": "删除链接已过期，请重新申请。"}},
                status=400,
            )

        contact = deletion_request.contact.strip().lower()
        matched_ids = [
            lead.pk
            for lead in Lead.objects.all()
            if any(
                isinstance(value, str) and value.strip().lower() == contact
                for value in lead.data.values()
            )
        ]
        deleted_count = len(matched_ids)
        if matched_ids:
            Lead.objects.filter(pk__in=matched_ids).delete()

        now = timezone.now()
        deletion_request.status = LeadDeletionRequest.STATUS_COMPLETED
        deletion_request.confirmed_at = now
        deletion_request.completed_at = now
        deletion_request.deleted_count = deleted_count
        deletion_request.save(
            update_fields=["status", "confirmed_at", "completed_at", "deleted_count"]
        )

        return Response(
            {
                "success": True,
                "deleted_count": deleted_count,
                "message": "已成功删除与该邮箱关联的个人信息。",
            }
        )
