import secrets
from django.conf import settings
from django.shortcuts import get_object_or_404
from django.utils import timezone
from rest_framework import viewsets, permissions, status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import BasePermission, AllowAny, IsAuthenticated
from django.db.models import Count, Q

from .models import MailSender, MailEmail, MailNotificationToken
from .serializers import (
    MailSenderSerializer,
    MailEmailCreateSerializer,
    MailEmailListSerializer,
    FeedbackDetailSerializer,
)


class MailAPIKeyPermission(BasePermission):
    """X-API-Key ヘッダーで認証（Windmill向け）"""

    def has_permission(self, request, view):
        key = request.headers.get('X-API-Key', '')
        expected = getattr(settings, 'MAIL_API_KEY', '')
        if not key or not expected:
            return False
        return secrets.compare_digest(key, expected)


# ---------------------------------------------------------------------------
# Windmill 向け API（APIキー認証）
# ---------------------------------------------------------------------------

class SenderRuleView(APIView):
    """
    GET /api/mail/sender-rule/?email=...&domain=...
    送信者ルールを確認する（アドレス優先 > ドメイン優先）
    """
    permission_classes = [MailAPIKeyPermission]
    authentication_classes = []

    def get(self, request):
        email = request.query_params.get('email', '')
        domain = request.query_params.get('domain', '')

        # アドレスルールを先に確認（具体的なほど優先）
        if email:
            sender = MailSender.objects.filter(email=email).first()
            if sender:
                return Response({
                    'matched': True,
                    'rule': sender.rule,
                    'match_type': 'address',
                })

        # ドメインルールを確認
        if domain:
            sender = MailSender.objects.filter(domain=domain).first()
            if sender:
                return Response({
                    'matched': True,
                    'rule': sender.rule,
                    'match_type': 'domain',
                })

        return Response({'matched': False})


class SenderContextView(APIView):
    """
    GET /api/mail/sender-context/?email=...&domain=...
    LLM用フィードバック集計を返す（トークン肥大化防止のため集計値のみ）
    """
    permission_classes = [MailAPIKeyPermission]
    authentication_classes = []

    def get(self, request):
        email = request.query_params.get('email', '')
        domain = request.query_params.get('domain', '')

        # アドレスで絞り込み（なければドメインで絞り込み）
        if email:
            qs = MailEmail.objects.filter(sender_email=email)
        elif domain:
            qs = MailEmail.objects.filter(sender_domain=domain)
        else:
            return Response({
                'total_notified': 0,
                'important': 0,
                'not_important': 0,
                'never_notify': 0,
                'no_feedback': 0,
            })

        total = qs.count()
        important = qs.filter(feedback='important').count()
        not_important = qs.filter(feedback='not_important').count()
        never_notify = qs.filter(feedback='never_notify').count()
        no_feedback = qs.filter(feedback__isnull=True).count()

        return Response({
            'total_notified': total,
            'important': important,
            'not_important': not_important,
            'never_notify': never_notify,
            'no_feedback': no_feedback,
        })


class MailEmailView(APIView):
    """
    GET  /api/mail/emails/  メール処理履歴を取得（JWT認証）
    POST /api/mail/emails/  メールを記録する（APIキー認証、Windmill向け）
    """

    def get_permissions(self):
        if self.request.method == 'POST':
            return [MailAPIKeyPermission()]
        return [IsAuthenticated()]

    def get(self, request):
        qs = MailEmail.objects.select_related('notification_token').order_by('-received_at')

        account = request.query_params.get('account')
        if account:
            qs = qs.filter(account=account)
        verdict = request.query_params.get('verdict')
        if verdict:
            qs = qs.filter(llm_verdict=verdict)

        serializer = MailEmailListSerializer(qs[:100], many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = MailEmailCreateSerializer(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        mail_email = serializer.save()
        response_data = {'id': mail_email.id}

        if mail_email.llm_verdict == 'important':
            token_obj = MailNotificationToken.objects.create(email=mail_email)
            mail_email.notified_at = timezone.now()
            mail_email.save(update_fields=['notified_at'])

            frontend_url = getattr(settings, 'FRONTEND_URL', 'http://localhost:3000')
            response_data['feedback_url'] = f"{frontend_url}/mail/feedback/{token_obj.token}"

        return Response(response_data, status=status.HTTP_201_CREATED)


class MailStatsView(APIView):
    """
    GET /api/mail/stats/  ダッシュボード用統計
    """
    permission_classes = [IsAuthenticated]

    def get(self, request):
        today = timezone.now().date()

        today_processed = MailEmail.objects.filter(received_at__date=today).count()
        today_notified = MailEmail.objects.filter(notified_at__date=today).count()
        feedback_pending = MailEmail.objects.filter(
            llm_verdict='important',
            feedback__isnull=True
        ).count()
        total_rules = MailSender.objects.count()

        return Response({
            'today_processed': today_processed,
            'today_notified': today_notified,
            'feedback_pending': feedback_pending,
            'total_rules': total_rules,
        })


# ---------------------------------------------------------------------------
# フィードバックビュー（認証不要）
# ---------------------------------------------------------------------------

class FeedbackView(APIView):
    """
    GET  /api/mail/feedback/<token>/  メール情報と現在のフィードバックを返す
    POST /api/mail/feedback/<token>/  フィードバックを保存する
    """
    permission_classes = [AllowAny]
    authentication_classes = []

    def _get_mail_email(self, token):
        token_obj = get_object_or_404(MailNotificationToken, token=token)
        return token_obj.email

    def get(self, request, token):
        mail_email = self._get_mail_email(token)
        serializer = FeedbackDetailSerializer(mail_email)
        return Response(serializer.data)

    def post(self, request, token):
        mail_email = self._get_mail_email(token)

        feedback = request.data.get('feedback')
        valid_feedbacks = ['important', 'not_important', 'never_notify', 'always_notify']
        if feedback not in valid_feedbacks:
            return Response(
                {'error': f'feedback は {valid_feedbacks} のいずれかを指定してください'},
                status=status.HTTP_400_BAD_REQUEST
            )

        # フィードバックを更新（再選択も可能）
        mail_email.feedback = feedback
        mail_email.feedback_at = timezone.now()
        mail_email.save(update_fields=['feedback', 'feedback_at'])

        # 送信者ルールを伴うフィードバックの処理
        if feedback in ('never_notify', 'always_notify'):
            scope = request.data.get('scope')  # 'address' or 'domain'
            if scope == 'address':
                MailSender.objects.update_or_create(
                    email=mail_email.sender_email,
                    defaults={'domain': None, 'rule': feedback}
                )
            elif scope == 'domain':
                MailSender.objects.update_or_create(
                    domain=mail_email.sender_domain,
                    defaults={'email': None, 'rule': feedback}
                )

        return Response({'status': 'ok'})


# ---------------------------------------------------------------------------
# 履歴画面からのフィードバック更新（JWT認証）
# ---------------------------------------------------------------------------

class MailEmailFeedbackView(APIView):
    """
    PATCH /api/mail/emails/<pk>/feedback/  履歴画面から直接フィードバックを更新（JWT認証）
    """
    permission_classes = [IsAuthenticated]

    def patch(self, request, pk):
        mail_email = get_object_or_404(MailEmail, pk=pk)

        feedback = request.data.get('feedback')
        valid_feedbacks = ['important', 'not_important', 'never_notify', 'always_notify']
        if feedback not in valid_feedbacks:
            return Response(
                {'error': f'feedback は {valid_feedbacks} のいずれかを指定してください'},
                status=status.HTTP_400_BAD_REQUEST
            )

        mail_email.feedback = feedback
        mail_email.feedback_at = timezone.now()
        mail_email.save(update_fields=['feedback', 'feedback_at'])

        if feedback in ('never_notify', 'always_notify'):
            scope = request.data.get('scope')
            if scope == 'address':
                MailSender.objects.update_or_create(
                    email=mail_email.sender_email,
                    defaults={'domain': None, 'rule': feedback}
                )
            elif scope == 'domain':
                MailSender.objects.update_or_create(
                    domain=mail_email.sender_domain,
                    defaults={'email': None, 'rule': feedback}
                )

        return Response({'status': 'ok', 'feedback': feedback})


# ---------------------------------------------------------------------------
# ルール管理（JWT認証）
# ---------------------------------------------------------------------------

class MailSenderViewSet(viewsets.ModelViewSet):
    """
    GET    /api/mail/senders/       ルール一覧
    POST   /api/mail/senders/       ルール追加
    DELETE /api/mail/senders/{id}/  ルール削除
    """
    queryset = MailSender.objects.all().order_by('-created_at')
    serializer_class = MailSenderSerializer
    permission_classes = [IsAuthenticated]
    http_method_names = ['get', 'post', 'delete', 'head', 'options']
