"""
Surveys views and viewsets
"""

from django.shortcuts import get_object_or_404
from django.utils import timezone
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response

from apps.accounts.permissions import IsPXAdminOrHospitalAdmin
from apps.core.services import AuditService

from .models import (
    SurveyInstance,
    SurveyQuestion,
    SurveyResponse,
    SurveyTemplate,
)
from .serializers import (
    PublicSurveySerializer,
    SurveyInstanceSerializer,
    SurveyQuestionSerializer,
    SurveyResponseSerializer,
    SurveySubmissionSerializer,
    SurveyTemplateSerializer,
)


class SurveyTemplateViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Survey Templates.

    Permissions:
    - PX Admins and Hospital Admins can manage templates
    - Others can view templates
    """

    queryset = SurveyTemplate.objects.all()
    serializer_class = SurveyTemplateSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = ["survey_type", "hospital", "is_active", "hospital__organization"]
    search_fields = ["name", "name_ar", "description"]
    ordering_fields = ["name", "created_at"]
    ordering = ["hospital", "name"]

    def get_queryset(self):
        """Filter templates based on user role"""
        queryset = super().get_queryset().select_related("hospital").prefetch_related("questions")
        user = self.request.user

        if user.is_px_admin():
            if hasattr(self.request, "tenant_hospital") and self.request.tenant_hospital:
                return queryset.filter(hospital=self.request.tenant_hospital)
            return queryset

        if user.is_hospital_admin() and user.hospital:
            return queryset.filter(hospital=user.hospital)

        if user.hospital:
            return queryset.filter(hospital=user.hospital)

        return queryset.none()


class SurveyQuestionViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Survey Questions.

    Permissions:
    - PX Admins and Hospital Admins can manage questions
    """

    queryset = SurveyQuestion.objects.all()
    serializer_class = SurveyQuestionSerializer
    permission_classes = [IsAuthenticated, IsPXAdminOrHospitalAdmin]
    filterset_fields = ["survey_template", "question_type", "is_required"]
    search_fields = ["text", "text_ar"]
    ordering_fields = ["order", "created_at"]
    ordering = ["survey_template", "order"]

    def get_queryset(self):
        queryset = super().get_queryset().select_related("survey_template")
        user = self.request.user

        if user.is_px_admin():
            if hasattr(self.request, "tenant_hospital") and self.request.tenant_hospital:
                return queryset.filter(survey_template__hospital=self.request.tenant_hospital)
            return queryset

        # Hospital Admins see questions for their hospital
        if user.is_hospital_admin() and user.hospital:
            return queryset.filter(survey_template__hospital=user.hospital)

        return queryset.none()


class SurveyInstanceViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Survey Instances.

    Permissions:
    - All authenticated users can view survey instances
    - PX Admins and Hospital Admins can create/manage instances
    """

    queryset = SurveyInstance.objects.all()
    serializer_class = SurveyInstanceSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = [
        "survey_template",
        "patient",
        "status",
        "delivery_channel",
        "is_negative",
        "journey_instance",
        "survey_template__hospital__organization",
    ]
    search_fields = ["patient__mrn", "patient__first_name", "patient__last_name", "encounter_id"]
    ordering_fields = ["sent_at", "completed_at", "created_at"]
    ordering = ["-created_at"]

    def get_queryset(self):
        """Filter survey instances based on user role"""
        queryset = (
            super()
            .get_queryset()
            .select_related("survey_template", "patient", "journey_instance")
            .prefetch_related("responses")
        )

        user = self.request.user

        if user.is_px_admin():
            if hasattr(self.request, "tenant_hospital") and self.request.tenant_hospital:
                return queryset.filter(survey_template__hospital=self.request.tenant_hospital)
            return queryset

        # Hospital Admins see instances for their hospital
        if user.is_hospital_admin() and user.hospital:
            return queryset.filter(survey_template__hospital=user.hospital)

        # Others see instances for their hospital
        if user.hospital:
            return queryset.filter(survey_template__hospital=user.hospital)

        return queryset.none()

    @action(detail=True, methods=["post"])
    def resend(self, request, pk=None):
        """Resend survey invitation"""
        survey_instance = self.get_object()

        if survey_instance.status == "completed":
            return Response({"error": "Cannot resend completed survey"}, status=status.HTTP_400_BAD_REQUEST)

        from apps.surveys.services import SurveyDeliveryService

        try:
            SurveyDeliveryService.deliver_survey(survey_instance)
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response({"message": "Survey invitation resent successfully"})


class SurveyResponseViewSet(viewsets.ReadOnlyModelViewSet):
    """
    ViewSet for Survey Responses (read-only).

    Responses are created via the public survey submission endpoint.
    """

    queryset = SurveyResponse.objects.all()
    serializer_class = SurveyResponseSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = ["survey_instance", "question"]
    ordering = ["survey_instance", "question__order"]

    def get_queryset(self):
        queryset = super().get_queryset().select_related("survey_instance", "question")
        user = self.request.user

        if user.is_px_admin():
            if hasattr(self.request, "tenant_hospital") and self.request.tenant_hospital:
                return queryset.filter(survey_instance__hospital=self.request.tenant_hospital)
            return queryset

        # Hospital Admins see responses for their hospital
        if user.is_hospital_admin() and user.hospital:
            return queryset.filter(survey_instance__hospital=user.hospital)

        # Others see responses for their hospital
        if user.hospital:
            return queryset.filter(survey_instance__hospital=user.hospital)

        return queryset.none()


class PublicSurveyViewSet(viewsets.GenericViewSet):
    """
    Public survey viewset for patient-facing survey access.

    No authentication required - uses secure token.
    """

    permission_classes = [AllowAny]

    def retrieve(self, request, token=None):
        """
        Get survey by access token.

        GET /api/surveys/public/{token}/
        """
        survey_instance = get_object_or_404(
            SurveyInstance.objects.select_related("survey_template").prefetch_related("survey_template__questions"),
            access_token=token,
        )

        # Check if token expired
        if survey_instance.token_expires_at and survey_instance.token_expires_at < timezone.now():
            return Response({"error": "Survey link has expired"}, status=status.HTTP_410_GONE)

        # Check if already completed
        if survey_instance.status == "completed":
            return Response(
                {"error": "Survey already completed", "completed_at": survey_instance.completed_at},
                status=status.HTTP_410_GONE,
            )

        # Mark as opened if first time
        if not survey_instance.opened_at:
            survey_instance.opened_at = timezone.now()
            survey_instance.save(update_fields=["opened_at"])

        serializer = PublicSurveySerializer(survey_instance)
        return Response(serializer.data)

    @action(detail=False, methods=["post"], url_path="(?P<token>[^/.]+)/submit")
    def submit(self, request, token=None):
        """
        Submit survey responses.

        POST /api/surveys/public/{token}/submit/

        Body:
        {
            "responses": [
                {"question_id": "uuid", "numeric_value": 5},
                {"question_id": "uuid", "text_value": "Great service!"}
            ]
        }
        """
        survey_instance = get_object_or_404(SurveyInstance, access_token=token)

        # Check if token expired
        if survey_instance.token_expires_at and survey_instance.token_expires_at < timezone.now():
            return Response({"error": "Survey link has expired"}, status=status.HTTP_410_GONE)

        # Check if already completed
        if survey_instance.status == "completed":
            return Response({"error": "Survey already completed"}, status=status.HTTP_400_BAD_REQUEST)

        # Validate and create responses
        serializer = SurveySubmissionSerializer(data=request.data, context={"survey_instance": survey_instance})
        serializer.is_valid(raise_exception=True)
        serializer.save()

        return Response(
            {
                "message": "Survey submitted successfully",
                "score": float(survey_instance.total_score) if survey_instance.total_score else None,
            },
            status=status.HTTP_201_CREATED,
        )
