"""
Survey Console UI views - Server-rendered templates for survey management
"""

from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.db.models import Q, Prefetch, Avg, Count, F, Case, When, IntegerField
from django.db.models.functions import TruncDate, ExtractYear
from django.http import FileResponse, HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone
from django.views.decorators.http import require_http_methods, require_POST
from django.db.models import ExpressionWrapper, FloatField

from apps.accounts.services import StaffActivityService
from apps.core.services import AuditService
from apps.core.decorators import block_source_user
from apps.organizations.models import Department, Hospital

from .forms import (
    ManualSurveySendForm,
    SurveyQuestionFormSet,
    SurveyTemplateForm,
    ManualPhoneSurveySendForm,
    BulkCSVSurveySendForm,
    QuestionRoutingRuleFormSet,
)
from apps.integrations.models import HISEventType

from .services import SurveyDeliveryService
from .models import SurveyInstance, SurveyTemplate, SurveyQuestion
from .tasks import send_satisfaction_feedback
from datetime import datetime
import json


@block_source_user
@login_required
def survey_instance_list(request):
    """
    Survey instances list view with filters.

    Features:
    - Server-side pagination
    - Filters (status, journey type, hospital, date range)
    - Search by patient MRN
    - Score display
    """
    # Source Users don't have access to surveys
    if request.user.is_source_user():
        from django.core.exceptions import PermissionDenied

        raise PermissionDenied("Source users do not have access to surveys.")

    # Base queryset with optimizations
    queryset = SurveyInstance.objects.select_related(
        "survey_template", "patient", "journey_instance__journey_template"
    ).prefetch_related("responses__question")

    # Apply RBAC filters
    user = request.user
    if user.is_px_admin():
        if hasattr(request, "tenant_hospital") and request.tenant_hospital:
            queryset = queryset.filter(hospital=request.tenant_hospital)
    elif user.is_hospital_admin() and user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    elif user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    else:
        queryset = queryset.none()

    # Apply filters
    status_filter = request.GET.get("status")
    if status_filter:
        queryset = queryset.filter(status=status_filter)

    survey_type = request.GET.get("survey_type")
    if survey_type:
        queryset = queryset.filter(survey_template__survey_type=survey_type)

    is_negative = request.GET.get("is_negative")
    if is_negative == "true":
        queryset = queryset.filter(is_negative=True)

    hospital_filter = request.GET.get("hospital")
    if hospital_filter:
        queryset = queryset.filter(hospital_id=hospital_filter)

    # Search
    search_query = request.GET.get("search")
    if search_query:
        queryset = queryset.filter(
            Q(patient__mrn__icontains=search_query)
            | Q(patient__first_name__icontains=search_query)
            | Q(patient__last_name__icontains=search_query)
            | Q(encounter_id__icontains=search_query)
        )

    # Date range
    date_from = request.GET.get("date_from")
    if date_from:
        queryset = queryset.filter(sent_at__gte=date_from)

    date_to = request.GET.get("date_to")
    if date_to:
        queryset = queryset.filter(sent_at__lte=date_to)

    # Ordering
    order_by = request.GET.get("order_by", "-created_at")
    queryset = queryset.order_by(order_by)

    # Pagination
    page_size = int(request.GET.get("page_size", 25))
    paginator = Paginator(queryset, page_size)
    page_number = request.GET.get("page", 1)
    page_obj = paginator.get_page(page_number)

    context = {
        "surveys": page_obj,
        "filters": request.GET,
    }

    return render(request, "surveys/instance_list.html", context)


@block_source_user
@login_required
def survey_instance_detail(request, pk):
    """
    Survey instance detail view with responses.

    Features:
    - Full survey details
    - All responses
    - Score breakdown
    - Related journey/stage info
    - Score comparison with template average
    - Related surveys from same patient
    """
    survey = get_object_or_404(
        SurveyInstance.objects.select_related(
            "survey_template", "patient", "journey_instance__journey_template"
        ).prefetch_related("responses__question"),
        pk=pk,
    )

    # Get responses
    responses = survey.responses.all().order_by("question__order")

    # Calculate average score for this survey template
    template_average = (
        SurveyInstance.objects.filter(survey_template=survey.survey_template, status="completed").aggregate(
            avg_score=Avg("total_score")
        )["avg_score"]
        or 0
    )

    # Get related surveys from the same patient
    related_surveys = (
        SurveyInstance.objects.filter(patient=survey.patient, status="completed")
        .exclude(id=survey.id)
        .select_related("survey_template")
        .order_by("-completed_at")[:5]
    )

    # Get response statistics for each question (for choice questions)
    question_stats = {}
    for response in responses:
        if response.question.question_type in ["multiple_choice", "single_choice"]:
            choice_responses = (
                SurveyInstance.objects.filter(survey_template=survey.survey_template, status="completed")
                .values(f"responses__choice_value")
                .annotate(count=Count("id"))
                .filter(responses__question=response.question)
                .order_by("-count")
            )

            question_stats[response.question.id] = {
                "type": "choice",
                "options": [
                    {
                        "value": opt["responses__choice_value"],
                        "count": opt["count"],
                        "percentage": round(
                            (opt["count"] / choice_responses.count() * 100) if choice_responses.count() > 0 else 0, 1
                        ),
                    }
                    for opt in choice_responses
                    if opt["responses__choice_value"]
                ],
            }
        elif response.question.question_type == "rating":
            rating_stats = SurveyInstance.objects.filter(
                survey_template=survey.survey_template, status="completed"
            ).aggregate(avg_rating=Avg("responses__numeric_value"), total_responses=Count("responses"))
            question_stats[response.question.id] = {
                "type": "rating",
                "average": round(rating_stats["avg_rating"] or 0, 2),
                "total_responses": rating_stats["total_responses"] or 0,
            }

    context = {
        "survey": survey,
        "responses": responses,
        "template_average": round(template_average, 2),
        "related_surveys": related_surveys,
        "question_stats": question_stats,
        "visit_timeline": survey.metadata.get("visit_timeline", []),
        "survey_url": SurveyDeliveryService.generate_survey_url(survey),
    }

    return render(request, "surveys/instance_detail.html", context)


@block_source_user
@login_required
def survey_template_list(request):
    """Survey templates list view"""
    queryset = (
        SurveyTemplate.objects.select_related("hospital")
        .prefetch_related("questions")
        .annotate(questions_count=Count("questions"))
    )

    user = request.user
    if user.is_px_admin():
        tenant_hospital = getattr(request, "tenant_hospital", None)
        if tenant_hospital:
            queryset = queryset.filter(hospital=tenant_hospital)
        else:
            queryset = queryset.none()
    elif user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    else:
        queryset = queryset.none()

    survey_type = request.GET.get("survey_type")
    if survey_type:
        queryset = queryset.filter(survey_type=survey_type)

    hospital_filter = request.GET.get("hospital")
    if hospital_filter:
        queryset = queryset.filter(hospital_id=hospital_filter)

    is_active = request.GET.get("is_active")
    if is_active == "true":
        queryset = queryset.filter(is_active=True)
    elif is_active == "false":
        queryset = queryset.filter(is_active=False)

    queryset = queryset.order_by("hospital", "survey_type", "name")

    page_size = int(request.GET.get("page_size", 25))
    paginator = Paginator(queryset, page_size)
    page_number = request.GET.get("page", 1)
    page_obj = paginator.get_page(page_number)

    context = {
        "page_obj": page_obj,
        "templates": page_obj.object_list,
        "filters": request.GET,
    }

    return render(request, "surveys/template_list.html", context)


def _get_visit_timeline_events():
    """Build grouped HIS event types for survey question helper."""
    groups = {"IP": [], "OP": [], "ED": []}
    for event in HISEventType.objects.all().order_by("-event_count"):
        entry = {"event_type": event.event_type, "count": event.event_count}
        for pt in event.patient_types or []:
            if pt in groups:
                groups[pt].append(entry)
    return groups


@block_source_user
@login_required
def survey_template_create(request):
    """Create a new survey template with questions"""
    user = request.user
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to create survey templates.")
        return redirect("surveys:template_list")

    if request.method == "POST":
        form = SurveyTemplateForm(request.POST, request=request)
        formset = SurveyQuestionFormSet(request.POST)

        if form.is_valid() and formset.is_valid():
            template = form.save(commit=False)
            template.created_by = user
            template.save()

            questions = formset.save(commit=False)
            for question in questions:
                question.survey_template = template
                question.save()
            for deleted in formset.deleted_forms:
                if deleted.instance.pk:
                    deleted.instance.delete()

            routing_formset = QuestionRoutingRuleFormSet(request.POST, instance=template)
            if routing_formset.is_valid():
                routing_formset.save()

            StaffActivityService.log_from_request(
                request,
                activity_type="create",
                description=f"Created survey template {template.name}",
                content_object=template,
                module="surveys",
            )

            messages.success(request, "Survey template created successfully.")
            return redirect("surveys:template_detail", pk=template.pk)
        else:
            routing_formset = QuestionRoutingRuleFormSet(request.POST, instance=None)
    else:
        form = SurveyTemplateForm(request=request)
        formset = SurveyQuestionFormSet()
        routing_formset = QuestionRoutingRuleFormSet(instance=None)

    context = {
        "form": form,
        "formset": formset,
        "routing_formset": routing_formset,
        "visit_timeline_events": _get_visit_timeline_events(),
    }

    return render(request, "surveys/template_form.html", context)


@block_source_user
@login_required
def survey_template_detail(request, pk):
    """View survey template details"""
    template = get_object_or_404(SurveyTemplate.objects.select_related("hospital").prefetch_related("questions"), pk=pk)

    user = request.user
    if not user.is_px_admin() and not user.is_hospital_admin():
        if user.hospital and template.hospital != user.hospital:
            messages.error(request, "You don't have permission to view this template.")
            return redirect("surveys:template_list")

    # Year filter
    current_year = timezone.now().year
    selected_year = request.GET.get("year")
    try:
        selected_year = int(selected_year) if selected_year else current_year
    except (ValueError, TypeError):
        selected_year = current_year

    # Base queryset filtered by year
    instances_qs = template.instances.filter(created_at__year=selected_year)

    total_instances = instances_qs.count()
    completed_instances = instances_qs.filter(status="completed").count()
    negative_instances = instances_qs.filter(is_negative=True).count()
    positive_instances = instances_qs.filter(status="completed", is_negative=False).count()
    avg_score = instances_qs.filter(status="completed").aggregate(avg_score=Avg("total_score"))["avg_score"] or 0

    # Available years for filter dropdown
    available_years = (
        template.instances
        .annotate(year=ExtractYear("created_at"))
        .values_list("year", flat=True)
        .distinct()
        .order_by("-year")
    )
    available_years = list(available_years) if available_years else [current_year]
    if current_year not in available_years:
        available_years.insert(0, current_year)

    context = {
        "template": template,
        "questions": template.questions.all().order_by("order"),
        "stats": {
            "total_instances": total_instances,
            "completed_instances": completed_instances,
            "negative_instances": negative_instances,
            "positive_instances": positive_instances,
            "positive_rate": round((positive_instances / completed_instances * 100) if completed_instances > 0 else 0, 1),
            "completion_rate": round((completed_instances / total_instances * 100) if total_instances > 0 else 0, 1),
            "avg_score": round(avg_score, 2),
        },
        "selected_year": selected_year,
        "available_years": available_years,
    }

    return render(request, "surveys/template_detail.html", context)


@block_source_user
@login_required
def survey_template_edit(request, pk):
    """Edit an existing survey template with questions"""
    template = get_object_or_404(SurveyTemplate, pk=pk)

    user = request.user
    if not user.is_px_admin() and not user.is_hospital_admin():
        if user.hospital and template.hospital != user.hospital:
            messages.error(request, "You don't have permission to edit this template.")
            return redirect("surveys:template_list")

    if request.method == "POST":
        form = SurveyTemplateForm(request.POST, instance=template, request=request)
        formset = SurveyQuestionFormSet(request.POST, instance=template)

        if form.is_valid() and formset.is_valid():
            form.save()
            formset.save()

            routing_formset = QuestionRoutingRuleFormSet(request.POST, instance=template)
            if routing_formset.is_valid():
                routing_rules = routing_formset.save(commit=False)
                for rule in routing_rules:
                    rule.survey_template = template
                    rule.save()
                for deleted in routing_formset.deleted_forms:
                    if deleted.instance.pk:
                        deleted.instance.delete()

            StaffActivityService.log_from_request(
                request,
                activity_type="update",
                description=f"Updated survey template {template.name}",
                content_object=template,
                module="surveys",
            )

            messages.success(request, "Survey template updated successfully.")
            if request.POST.get("_save_continue"):
                return redirect("surveys:template_edit", pk=template.pk)
            return redirect("surveys:template_detail", pk=template.pk)
        else:
            routing_formset = QuestionRoutingRuleFormSet(request.POST, instance=template)
    else:
        form = SurveyTemplateForm(instance=template, request=request)
        formset = SurveyQuestionFormSet(instance=template)
        routing_formset = QuestionRoutingRuleFormSet(instance=template)

    context = {
        "form": form,
        "formset": formset,
        "template": template,
        "routing_formset": routing_formset,
        "questions_json": json.dumps(
            [
                {"id": str(q.id), "text": q.text, "order": q.order, "question_type": q.question_type}
                for q in template.questions.all().order_by("order")
            ]
        ),
        "visit_timeline_events": _get_visit_timeline_events(),
    }

    return render(request, "surveys/template_form.html", context)


@login_required
@require_POST
def template_question_reorder(request, pk):
    """Reorder questions in a survey template"""
    template = get_object_or_404(SurveyTemplate, pk=pk)
    try:
        order_data = json.loads(request.body) if request.body else json.loads(request.POST.get("order", "[]"))
    except json.JSONDecodeError:
        order_data = json.loads(request.POST.get("order", "[]"))

    for item in order_data:
        SurveyQuestion.objects.filter(
            pk=item.get("id"),
            survey_template=template,
        ).update(order=item.get("order", 0))

    return JsonResponse({"status": "ok"})


@block_source_user
@login_required
def survey_template_delete(request, pk):
    """Delete a survey template"""
    template = get_object_or_404(SurveyTemplate, pk=pk)

    user = request.user
    if not user.is_px_admin() and not user.is_hospital_admin():
        if user.hospital and template.hospital != user.hospital:
            messages.error(request, "You don't have permission to delete this template.")
            return redirect("surveys:template_list")

    if request.method == "POST":
        template_name = template.name
        template.delete()
        StaffActivityService.log_from_request(
            request,
            activity_type="delete",
            description=f"Deleted survey template {template_name}",
            module="surveys",
        )
        messages.success(request, f"Survey template '{template_name}' deleted successfully.")
        return redirect("surveys:template_list")

    context = {
        "template": template,
    }

    return render(request, "surveys/template_confirm_delete.html", context)


def survey_log_patient_contact(request, pk):
    """
    Log patient contact for negative survey.

    This records that the user contacted the patient to discuss
    the negative survey feedback.
    """
    survey = get_object_or_404(SurveyInstance, pk=pk)

    # Check permission
    user = request.user
    if not user.is_px_admin() and not user.is_hospital_admin():
        if user.hospital and survey.survey_template.hospital != user.hospital:
            messages.error(request, "You don't have permission to modify this survey.")
            return redirect("surveys:instance_detail", pk=pk)

    # Check if survey is negative
    if not survey.is_negative:
        messages.warning(request, "This survey is not marked as negative.")
        return redirect("surveys:instance_detail", pk=pk)

    # Get form data
    contact_notes = request.POST.get("contact_notes", "")
    issue_resolved = request.POST.get("issue_resolved") == "on"

    if not contact_notes:
        messages.error(request, "Please provide contact notes.")
        return redirect("surveys:instance_detail", pk=pk)

    try:
        # Update survey
        survey.patient_contacted = True
        survey.patient_contacted_at = timezone.now()
        survey.patient_contacted_by = user
        survey.contact_notes = contact_notes
        survey.issue_resolved = issue_resolved
        survey.save(
            update_fields=[
                "patient_contacted",
                "patient_contacted_at",
                "patient_contacted_by",
                "contact_notes",
                "issue_resolved",
            ]
        )

        # Log audit
        AuditService.log_event(
            event_type="survey_patient_contacted",
            description=f"Patient contacted for negative survey by {user.get_full_name()}",
            user=user,
            content_object=survey,
            metadata={
                "contact_notes": contact_notes,
                "issue_resolved": issue_resolved,
                "survey_score": float(survey.total_score) if survey.total_score else None,
            },
        )

        status = "resolved" if issue_resolved else "discussed"
        messages.success(request, f"Patient contact logged successfully. Issue marked as {status}.")

    except Exception as e:
        messages.error(request, f"Error logging patient contact: {str(e)}")

    return redirect("surveys:instance_detail", pk=pk)


@block_source_user
@login_required
def survey_comments_list(request):
    """
    Survey comments list view with AI analysis.

    Features:
    - Display all survey comments with AI analysis
    - Filters (sentiment, survey type, hospital, date range)
    - Search by patient MRN
    - Server-side pagination
    - PatientType display from journey
    """
    # Base queryset - only completed surveys with comments
    queryset = (
        SurveyInstance.objects.select_related("survey_template", "patient", "journey_instance__journey_template")
        .filter(status="completed", comment__isnull=False)
        .exclude(comment="")
    )

    # Apply RBAC filters
    user = request.user
    if user.is_px_admin():
        pass  # See all
    elif user.is_hospital_admin() and user.hospital:
        queryset = queryset.filter(survey_template__hospital=user.hospital)
    elif user.hospital:
        queryset = queryset.filter(survey_template__hospital=user.hospital)
    else:
        queryset = queryset.none()

    # Apply filters
    sentiment_filter = request.GET.get("sentiment")
    if sentiment_filter:
        queryset = queryset.filter(comment_analysis__sentiment=sentiment_filter)

    comment_category_filter = request.GET.get("comment_category")
    if comment_category_filter:
        queryset = queryset.filter(comment_analysis__comment_category=comment_category_filter)

    survey_type = request.GET.get("survey_type")
    if survey_type:
        queryset = queryset.filter(survey_template__survey_type=survey_type)

    hospital_filter = request.GET.get("hospital")
    if hospital_filter:
        queryset = queryset.filter(survey_template__hospital_id=hospital_filter)

    # Patient type filter
    patient_type_filter = request.GET.get("patient_type")
    if patient_type_filter:
        # Map filter values to HIS codes
        patient_type_map = {
            "outpatient": ["1"],
            "inpatient": ["2", "O"],
            "emergency": ["3", "E"],
        }
        if patient_type_filter in patient_type_map:
            codes = patient_type_map[patient_type_filter]
            queryset = queryset.filter(metadata__patient_type__in=codes)

    # Search
    search_query = request.GET.get("search")
    if search_query:
        queryset = queryset.filter(
            Q(patient__mrn__icontains=search_query)
            | Q(patient__first_name__icontains=search_query)
            | Q(patient__last_name__icontains=search_query)
            | Q(comment__icontains=search_query)
        )

    # Date range
    date_from = request.GET.get("date_from")
    if date_from:
        queryset = queryset.filter(completed_at__gte=date_from)

    date_to = request.GET.get("date_to")
    if date_to:
        queryset = queryset.filter(completed_at__lte=date_to)

    # Ordering
    order_by = request.GET.get("order_by", "-completed_at")
    queryset = queryset.order_by(order_by)

    # Pagination
    page_size = int(request.GET.get("page_size", 25))
    paginator = Paginator(queryset, page_size)
    page_number = request.GET.get("page", 1)
    page_obj = paginator.get_page(page_number)

    # Statistics
    stats_queryset = SurveyInstance.objects.filter(status="completed", comment__isnull=False).exclude(comment="")

    # Apply same RBAC filters to stats
    if user.is_px_admin():
        pass
    elif user.is_hospital_admin() and user.hospital:
        stats_queryset = stats_queryset.filter(survey_template__hospital=user.hospital)
    elif user.hospital:
        stats_queryset = stats_queryset.filter(survey_template__hospital=user.hospital)
    else:
        stats_queryset = stats_queryset.none()

    total_count = stats_queryset.count()
    positive_count = stats_queryset.filter(comment_analysis__sentiment="positive").count()
    negative_count = stats_queryset.filter(comment_analysis__sentiment="negative").count()
    neutral_count = stats_queryset.filter(comment_analysis__sentiment="neutral").count()
    analyzed_count = stats_queryset.filter(comment_analyzed=True).count()

    # Patient Type Distribution Chart Data
    patient_type_distribution = []
    patient_type_labels = []
    patient_type_mapping = {
        "1": "Outpatient",
        "2": "Inpatient",
        "O": "Inpatient",
        "3": "Emergency",
        "E": "Emergency",
    }

    # Count each patient type
    outpatient_count = stats_queryset.filter(metadata__patient_type__in=["1"]).count()
    inpatient_count = stats_queryset.filter(metadata__patient_type__in=["2", "O"]).count()
    emergency_count = stats_queryset.filter(metadata__patient_type__in=["3", "E"]).count()
    unknown_count = total_count - (outpatient_count + inpatient_count + emergency_count)

    patient_type_distribution = [
        {
            "type": "outpatient",
            "label": "Outpatient",
            "count": outpatient_count,
            "percentage": round((outpatient_count / total_count * 100) if total_count > 0 else 0, 1),
        },
        {
            "type": "inpatient",
            "label": "Inpatient",
            "count": inpatient_count,
            "percentage": round((inpatient_count / total_count * 100) if total_count > 0 else 0, 1),
        },
        {
            "type": "emergency",
            "label": "Emergency",
            "count": emergency_count,
            "percentage": round((emergency_count / total_count * 100) if total_count > 0 else 0, 1),
        },
        {
            "type": "unknown",
            "label": "N/A",
            "count": unknown_count,
            "percentage": round((unknown_count / total_count * 100) if total_count > 0 else 0, 1),
        },
    ]

    # Sentiment by Patient Type Chart Data
    sentiment_by_patient_type = {
        "types": ["Outpatient", "Inpatient", "Emergency", "N/A"],
        "positive": [],
        "negative": [],
        "neutral": [],
    }

    # Calculate sentiment for each patient type
    for pt_type, codes in [
        ("outpatient", ["1"]),
        ("inpatient", ["2", "O"]),
        ("emergency", ["3", "E"]),
        ("unknown", []),
    ]:
        if codes:
            pt_queryset = stats_queryset.filter(metadata__patient_type__in=codes)
        else:
            pt_queryset = stats_queryset.exclude(metadata__patient_type__in=["1", "2", "O", "3", "E"])

        pt_positive = pt_queryset.filter(comment_analysis__sentiment="positive").count()
        pt_negative = pt_queryset.filter(comment_analysis__sentiment="negative").count()
        pt_neutral = pt_queryset.filter(comment_analysis__sentiment="neutral").count()

        sentiment_by_patient_type["positive"].append(pt_positive)
        sentiment_by_patient_type["negative"].append(pt_negative)
        sentiment_by_patient_type["neutral"].append(pt_neutral)

    # PatientType mapping helper - maps HIS codes to display values
    # HIS codes: "1"=Inpatient, "2"/"O"=Outpatient, "3"/"E"=Emergency
    PATIENT_TYPE_MAPPING = {
        "1": {"label": "Outpatient", "icon": "bi-person-walking", "color": "bg-primary"},
        "2": {"label": "Inpatient", "icon": "bi-hospital", "color": "bg-warning"},
        "O": {"label": "Inpatient", "icon": "bi-hospital", "color": "bg-warning"},
        "3": {"label": "Emergency", "icon": "bi-ambulance", "color": "bg-danger"},
        "E": {"label": "Emergency", "icon": "bi-ambulance", "color": "bg-danger"},
    }

    def get_patient_type_display(survey):
        """Get patient type display for a survey from HIS metadata"""
        # Get patient_type from survey metadata (saved by HIS adapter)
        patient_type_code = survey.metadata.get("patient_type")

        if patient_type_code:
            type_info = PATIENT_TYPE_MAPPING.get(str(patient_type_code))
            if type_info:
                return {
                    "code": patient_type_code,
                    "label": type_info["label"],
                    "icon": type_info["icon"],
                    "color": type_info["color"],
                }

        # Fallback: try to get from journey if available
        if survey.journey_instance and survey.journey_instance.journey_template:
            journey_type = survey.journey_instance.journey_template.journey_type
            journey_mapping = {
                "opd": {"label": "Outpatient", "icon": "bi-person-walking", "color": "bg-primary"},
                "inpatient": {"label": "Inpatient", "icon": "bi-hospital", "color": "bg-warning"},
                "ems": {"label": "Emergency", "icon": "bi-ambulance", "color": "bg-danger"},
                "day_case": {"label": "Day Case", "icon": "bi-calendar-day", "color": "bg-info"},
            }
            return journey_mapping.get(
                journey_type, {"code": None, "label": "N/A", "icon": "bi-question-circle", "color": "bg-secondary"}
            )

        return {"code": None, "label": "N/A", "icon": "bi-question-circle", "color": "bg-secondary"}

    # Add patient type info to surveys
    for survey in page_obj.object_list:
        survey.patient_type = get_patient_type_display(survey)

    stats = {
        "total": total_count,
        "positive": positive_count,
        "negative": negative_count,
        "neutral": neutral_count,
        "analyzed": analyzed_count,
        "unanalyzed": total_count - analyzed_count,
    }

    # Serialize chart data to JSON
    import json

    patient_type_distribution_json = json.dumps(patient_type_distribution)
    sentiment_by_patient_type_json = json.dumps(sentiment_by_patient_type)

    context = {
        "page_obj": page_obj,
        "surveys": page_obj.object_list,
        "stats": stats,
        "filters": request.GET,
        "patient_type_distribution": patient_type_distribution,
        "sentiment_by_patient_type": sentiment_by_patient_type,
        "patient_type_distribution_json": patient_type_distribution_json,
        "sentiment_by_patient_type_json": sentiment_by_patient_type_json,
    }

    return render(request, "surveys/comment_list.html", context)


@block_source_user
@login_required
@require_http_methods(["POST"])
def survey_send_satisfaction_feedback(request, pk):
    """
    Send satisfaction feedback form to patient.

    This creates and sends a feedback form to assess patient satisfaction
    with how their negative survey concerns were addressed.
    """
    survey = get_object_or_404(SurveyInstance, pk=pk)

    # Check permission
    user = request.user
    if not user.is_px_admin() and not user.is_hospital_admin():
        if user.hospital and survey.survey_template.hospital != user.hospital:
            messages.error(request, "You don't have permission to modify this survey.")
            return redirect("surveys:instance_detail", pk=pk)

    # Check if survey is negative
    if not survey.is_negative:
        messages.warning(request, "This survey is not marked as negative.")
        return redirect("surveys:instance_detail", pk=pk)

    # Check if patient was contacted
    if not survey.patient_contacted:
        messages.error(request, "Please log patient contact before sending satisfaction feedback.")
        return redirect("surveys:instance_detail", pk=pk)

    # Check if already sent
    if survey.satisfaction_feedback_sent:
        messages.warning(request, "Satisfaction feedback has already been sent for this survey.")
        return redirect("surveys:instance_detail", pk=pk)

    try:
        # Trigger async task to send satisfaction feedback
        send_satisfaction_feedback.delay(str(survey.id), str(user.id))

        messages.success(
            request,
            "Satisfaction feedback form is being sent to the patient. "
            "They will receive a link to provide their feedback.",
        )

    except Exception as e:
        messages.error(request, f"Error sending satisfaction feedback: {str(e)}")

    return redirect("surveys:instance_detail", pk=pk)


@block_source_user
@login_required
def manual_survey_send(request):
    """
    Manually send a survey to a patient or staff member.

    Features:
    - Select survey template
    - Choose recipient type (patient/staff)
    - Search and select recipient
    - Choose delivery channel (email/SMS)
    - Add custom message (optional)
    - Send survey immediately
    """
    user = request.user

    # Check permission
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to send surveys manually.")
        return redirect("surveys:instance_list")

    if request.method == "POST":
        form = ManualSurveySendForm(request=request, data=request.POST)

        if form.is_valid():
            try:
                # Get form data
                survey_template = form.cleaned_data["survey_template"]
                recipient_type = form.cleaned_data["recipient_type"]
                recipient_id = form.cleaned_data["recipient"]
                delivery_channel = form.cleaned_data["delivery_channel"]
                custom_message = form.cleaned_data.get("custom_message", "")

                # Get recipient object
                from apps.organizations.models import Patient, Staff

                if recipient_type == "patient":
                    recipient = get_object_or_404(Patient, pk=recipient_id)
                    recipient_name = f"{recipient.first_name} {recipient.last_name}"
                else:
                    recipient = get_object_or_404(Staff, pk=recipient_id)
                    recipient_name = f"{recipient.first_name} {recipient.last_name}"

                # Check if recipient has contact info for selected channel
                if delivery_channel == "email":
                    contact_info = recipient.email
                    if not contact_info:
                        messages.error(request, f"{recipient_type.title()} does not have an email address.")
                        return render(request, "surveys/manual_send.html", {"form": form})
                elif delivery_channel == "sms":
                    contact_info = recipient.phone
                    if not contact_info:
                        messages.error(request, f"{recipient_type.title()} does not have a phone number.")
                        return render(request, "surveys/manual_send.html", {"form": form})

                # Create survey instance
                from .models import SurveyStatus

                survey_instance = SurveyInstance.objects.create(
                    survey_template=survey_template,
                    patient=recipient if recipient_type == "patient" else None,
                    staff=recipient if recipient_type == "staff" else None,
                    hospital=survey_template.hospital,
                    delivery_channel=delivery_channel,
                    recipient_email=contact_info if delivery_channel == "email" else None,
                    recipient_phone=contact_info if delivery_channel == "sms" else None,
                    status=SurveyStatus.SENT,
                    metadata={
                        "sent_manually": True,
                        "sent_by": str(user.id),
                        "custom_message": custom_message,
                        "recipient_type": recipient_type,
                    },
                )

                # Send survey
                success = SurveyDeliveryService.deliver_survey(survey_instance)

                if success:
                    # Log audit
                    AuditService.log_event(
                        event_type="survey_sent_manually",
                        description=f"Survey sent manually to {recipient_name} ({recipient_type}) by {user.get_full_name()}",
                        user=user,
                        content_object=survey_instance,
                        metadata={
                            "survey_template": survey_template.name,
                            "recipient_type": recipient_type,
                            "recipient_id": recipient_id,
                            "delivery_channel": delivery_channel,
                            "custom_message": custom_message,
                        },
                    )

                    messages.success(
                        request,
                        f"Survey sent successfully to {recipient_name} via {delivery_channel.upper()}. "
                        f"Survey ID: {survey_instance.id}",
                    )
                    return redirect("surveys:instance_detail", pk=survey_instance.pk)
                else:
                    messages.error(request, "Failed to send survey. Please try again.")
                    survey_instance.delete()
                    return render(request, "surveys/manual_send.html", {"form": form})

            except Exception as e:
                import logging

                logger = logging.getLogger(__name__)
                logger.error(f"Error sending survey manually: {str(e)}", exc_info=True)
                messages.error(request, f"Error sending survey: {str(e)}")
                return render(request, "surveys/manual_send.html", {"form": form})
    else:
        form = ManualSurveySendForm(request=request)

    context = {
        "form": form,
    }

    return render(request, "surveys/manual_send.html", context)


@block_source_user
@login_required
def manual_survey_send_phone(request):
    """
    Send survey to a manually entered phone number.

    Features:
    - Enter phone number directly
    - Optional recipient name
    - Send via SMS only
    """
    user = request.user

    # Check permission
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to send surveys manually.")
        return redirect("surveys:instance_list")

    if request.method == "POST":
        form = ManualPhoneSurveySendForm(request=request, data=request.POST)

        if form.is_valid():
            try:
                survey_template = form.cleaned_data["survey_template"]
                phone_number = form.cleaned_data["phone_number"]
                recipient_name = form.cleaned_data.get("recipient_name", "")
                custom_message = form.cleaned_data.get("custom_message", "")

                # Create survey instance
                from .models import SurveyStatus

                survey_instance = SurveyInstance.objects.create(
                    survey_template=survey_template,
                    hospital=survey_template.hospital,
                    delivery_channel="sms",
                    recipient_phone=phone_number,
                    status=SurveyStatus.SENT,
                    metadata={
                        "sent_manually": True,
                        "sent_by": str(user.id),
                        "custom_message": custom_message,
                        "recipient_name": recipient_name,
                        "recipient_type": "manual_phone",
                    },
                )

                # Send survey
                success = SurveyDeliveryService.deliver_survey(survey_instance)

                if success:
                    # Log audit
                    AuditService.log_event(
                        event_type="survey_sent_manually_phone",
                        description=f"Survey sent manually to phone {phone_number} by {user.get_full_name()}",
                        user=user,
                        content_object=survey_instance,
                        metadata={
                            "survey_template": survey_template.name,
                            "phone_number": phone_number,
                            "recipient_name": recipient_name,
                            "custom_message": custom_message,
                        },
                    )

                    display_name = recipient_name if recipient_name else phone_number
                    messages.success(
                        request, f"Survey sent successfully to {display_name} via SMS. Survey ID: {survey_instance.id}"
                    )
                    return redirect("surveys:instance_detail", pk=survey_instance.pk)
                else:
                    messages.error(request, "Failed to send survey. Please try again.")
                    survey_instance.delete()
                    return render(request, "surveys/manual_send_phone.html", {"form": form})

            except Exception as e:
                import logging

                logger = logging.getLogger(__name__)
                logger.error(f"Error sending survey to phone: {str(e)}", exc_info=True)
                messages.error(request, f"Error sending survey: {str(e)}")
                return render(request, "surveys/manual_send_phone.html", {"form": form})
    else:
        form = ManualPhoneSurveySendForm(request=request)

    context = {
        "form": form,
    }

    return render(request, "surveys/manual_send_phone.html", context)


@block_source_user
@login_required
def manual_survey_send_csv(request):
    """
    Bulk send surveys via CSV upload.

    CSV Format:
    phone_number,name(optional)
    +966501234567,John Doe
    +966501234568,Jane Smith

    Features:
    - Upload CSV with phone numbers
    - Optional names for each recipient
    - Bulk processing with success/failure reporting
    """
    import csv
    import io
    from django.utils.translation import gettext as _

    user = request.user

    # Check permission
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to send surveys manually.")
        return redirect("surveys:instance_list")

    if request.method == "POST":
        form = BulkCSVSurveySendForm(request=request, data=request.POST, files=request.FILES)

        if form.is_valid():
            try:
                survey_template = form.cleaned_data["survey_template"]
                csv_file = form.cleaned_data["csv_file"]
                custom_message = form.cleaned_data.get("custom_message", "")

                # Parse CSV
                decoded_file = csv_file.read().decode("utf-8-sig")  # Handle BOM
                io_string = io.StringIO(decoded_file)
                reader = csv.reader(io_string)

                # Skip header if present
                first_row = next(reader, None)
                if not first_row:
                    messages.error(request, "CSV file is empty.")
                    return render(request, "surveys/manual_send_csv.html", {"form": form})

                # Check if first row is header or data
                rows = []
                if first_row[0].strip().lower() in ["phone", "phone_number", "mobile", "number", "tel"]:
                    # First row is header, use remaining rows
                    pass
                else:
                    # First row is data
                    rows.append(first_row)

                # Read remaining rows
                for row in reader:
                    if row and row[0].strip():  # Skip empty rows
                        rows.append(row)

                if not rows:
                    messages.error(request, "No valid phone numbers found in CSV.")
                    return render(request, "surveys/manual_send_csv.html", {"form": form})

                # Process each row
                from .models import SurveyStatus

                success_count = 0
                failed_count = 0
                failed_numbers = []
                created_instances = []

                import logging

                logger = logging.getLogger(__name__)

                for row in rows:
                    try:
                        phone_number = row[0].strip() if len(row) > 0 else ""
                        recipient_name = row[1].strip() if len(row) > 1 else ""

                        # Clean phone number
                        phone_number = phone_number.replace(" ", "").replace("-", "").replace("(", "").replace(")", "")

                        logger.info(f"Processing row: phone={phone_number}, name={recipient_name}")

                        # Skip empty or invalid
                        if not phone_number or not phone_number.startswith("+"):
                            failed_count += 1
                            failed_numbers.append(f"{phone_number} (invalid format - must start with +)")
                            logger.warning(f"Invalid phone format: {phone_number}")
                            continue

                        # Create survey instance
                        survey_instance = SurveyInstance.objects.create(
                            survey_template=survey_template,
                            hospital=survey_template.hospital,
                            delivery_channel="sms",
                            recipient_phone=phone_number,
                            status=SurveyStatus.SENT,
                            metadata={
                                "sent_manually": True,
                                "sent_by": str(user.id),
                                "custom_message": custom_message,
                                "recipient_name": recipient_name,
                                "recipient_type": "csv_upload",
                                "csv_row": row,
                            },
                        )

                        logger.info(f"Created survey instance: {survey_instance.id}")

                        # Send survey
                        success = SurveyDeliveryService.deliver_survey(survey_instance)

                        logger.info(f"Survey delivery result for {phone_number}: success={success}")

                        if success:
                            success_count += 1
                            created_instances.append(survey_instance)
                        else:
                            failed_count += 1
                            failed_numbers.append(f"{phone_number} (delivery failed - check logs)")
                            survey_instance.delete()

                    except Exception as e:
                        failed_count += 1
                        phone_display = phone_number if "phone_number" in locals() else "unknown"
                        failed_numbers.append(f"{phone_display} (exception: {str(e)})")
                        logger.error(f"Exception processing row {row}: {str(e)}", exc_info=True)

                # Log audit for bulk operation
                AuditService.log_event(
                    event_type="survey_sent_manually_csv",
                    description=f"Bulk survey send via CSV: {success_count} successful, {failed_count} failed by {user.get_full_name()}",
                    user=user,
                    metadata={
                        "survey_template": survey_template.name,
                        "success_count": success_count,
                        "failed_count": failed_count,
                        "total_count": len(rows),
                        "custom_message": custom_message,
                    },
                )

                # Show results
                if success_count > 0 and failed_count == 0:
                    messages.success(request, f"Successfully sent {success_count} surveys from CSV.")
                elif success_count > 0 and failed_count > 0:
                    messages.warning(
                        request,
                        f"Sent {success_count} surveys successfully. {failed_count} failed. Check failed numbers: {', '.join(failed_numbers[:5])}{'...' if len(failed_numbers) > 5 else ''}",
                    )
                else:
                    messages.error(
                        request, f"All {failed_count} surveys failed to send. Check the phone numbers and try again."
                    )

                # Redirect to list view with filter for these surveys
                if created_instances:
                    return redirect("surveys:instance_list")
                else:
                    return render(request, "surveys/manual_send_csv.html", {"form": form})

            except Exception as e:
                import logging

                logger = logging.getLogger(__name__)
                logger.error(f"Error processing CSV upload: {str(e)}", exc_info=True)
                messages.error(request, f"Error processing CSV: {str(e)}")
                return render(request, "surveys/manual_send_csv.html", {"form": form})
    else:
        form = BulkCSVSurveySendForm(request=request)

    context = {
        "form": form,
    }

    return render(request, "surveys/manual_send_csv.html", context)


@block_source_user
@login_required
def survey_analytics_reports(request):
    """
    Survey analytics reports management page.

    Features:
    - List all available reports
    - View report details
    - Generate new reports
    - Download reports
    - Delete reports
    """
    import os
    from django.conf import settings

    user = request.user

    # Check permission - only admins and hospital admins can view reports
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to view analytics reports.")
        return redirect("surveys:instance_list")

    output_dir = getattr(settings, "SURVEY_REPORTS_DIR", "reports")

    # Get all reports
    reports = []
    if os.path.exists(output_dir):
        for filename in os.listdir(output_dir):
            filepath = os.path.join(output_dir, filename)
            if os.path.isfile(filepath):
                stat = os.stat(filepath)
                report_type = "unknown"
                if filename.endswith(".json"):
                    report_type = "json"
                elif filename.endswith(".html"):
                    report_type = "html"
                elif filename.endswith(".md"):
                    report_type = "markdown"

                reports.append(
                    {
                        "filename": filename,
                        "type": report_type,
                        "size": stat.st_size,
                        "size_human": _human_readable_size(stat.st_size),
                        "created": stat.st_ctime,
                        "created_date": datetime.fromtimestamp(stat.st_ctime),
                        "modified": stat.st_mtime,
                    }
                )

        # Sort by creation date (newest first)
        reports.sort(key=lambda x: x["created"], reverse=True)

    # Statistics
    total_reports = len(reports)
    json_reports = len([r for r in reports if r["type"] == "json"])
    html_reports = len([r for r in reports if r["type"] == "html"])
    markdown_reports = len([r for r in reports if r["type"] == "markdown"])

    context = {
        "reports": reports,
        "stats": {
            "total": total_reports,
            "json": json_reports,
            "html": html_reports,
            "markdown": markdown_reports,
        },
    }

    return render(request, "surveys/analytics_reports.html", context)


@block_source_user
@login_required
def survey_analytics_report_view(request, filename):
    """
    View a specific survey analytics report.

    Features:
    - Display HTML reports in browser
    - Provide download links for all formats
    - Show report metadata
    """
    import os
    from django.conf import settings

    user = request.user

    # Check permission
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to view analytics reports.")
        return redirect("surveys:analytics_reports")

    output_dir = getattr(settings, "SURVEY_REPORTS_DIR", "reports")
    filepath = os.path.join(output_dir, filename)

    # Security check - ensure file is in reports directory
    if not os.path.abspath(filepath).startswith(os.path.abspath(output_dir)):
        messages.error(request, "Invalid report file.")
        return redirect("surveys:analytics_reports")

    if not os.path.exists(filepath):
        messages.error(request, "Report file not found.")
        return redirect("surveys:analytics_reports")

    # Determine report type
    report_type = "unknown"
    if filename.endswith(".json"):
        report_type = "json"
    elif filename.endswith(".html"):
        report_type = "html"
    elif filename.endswith(".md"):
        report_type = "markdown"

    # Get file info
    stat = os.stat(filepath)

    # For HTML files, render them directly
    if report_type == "html":
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()

        context = {
            "filename": filename,
            "content": content,
            "report_type": report_type,
            "size": stat.st_size,
            "size_human": _human_readable_size(stat.st_size),
            "created_date": datetime.fromtimestamp(stat.st_ctime),
            "modified_date": datetime.fromtimestamp(stat.st_mtime),
        }

        return render(request, "surveys/analytics_report_view.html", context)

    # For JSON and Markdown files, show info and provide download
    context = {
        "filename": filename,
        "report_type": report_type,
        "size": stat.st_size,
        "size_human": _human_readable_size(stat.st_size),
        "created_date": datetime.fromtimestamp(stat.st_ctime),
        "modified_date": datetime.fromtimestamp(stat.st_mtime),
    }

    return render(request, "surveys/analytics_report_info.html", context)


@block_source_user
@login_required
def survey_analytics_report_download(request, filename):
    """
    Download a survey analytics report file.
    """
    import os
    from django.conf import settings
    from django.http import FileResponse

    user = request.user

    # Check permission
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to download analytics reports.")
        return redirect("surveys:analytics_reports")

    output_dir = getattr(settings, "SURVEY_REPORTS_DIR", "reports")
    filepath = os.path.join(output_dir, filename)

    # Security check
    if not os.path.abspath(filepath).startswith(os.path.abspath(output_dir)):
        messages.error(request, "Invalid report file.")
        return redirect("surveys:analytics_reports")

    if not os.path.exists(filepath):
        messages.error(request, "Report file not found.")
        return redirect("surveys:analytics_reports")

    # Determine content type
    content_type = "application/octet-stream"
    if filename.endswith(".html"):
        content_type = "text/html"
    elif filename.endswith(".json"):
        content_type = "application/json"
    elif filename.endswith(".md"):
        content_type = "text/markdown"

    # Send file
    return FileResponse(open(filepath, "rb"), content_type=content_type, as_attachment=True, filename=filename)


@block_source_user
@login_required
def survey_analytics_report_view_inline(request, filename):
    """
    View a survey analytics report inline in the browser.

    Unlike download, this displays the file content directly in the browser
    without forcing a download. Works for HTML, JSON, and Markdown files.
    """
    import os
    from django.conf import settings

    user = request.user

    # Check permission
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to view analytics reports.")
        return redirect("surveys:analytics_reports")

    output_dir = getattr(settings, "SURVEY_REPORTS_DIR", "reports")
    filepath = os.path.join(output_dir, filename)

    # Security check
    if not os.path.abspath(filepath).startswith(os.path.abspath(output_dir)):
        messages.error(request, "Invalid report file.")
        return redirect("surveys:analytics_reports")

    if not os.path.exists(filepath):
        messages.error(request, "Report file not found.")
        return redirect("surveys:analytics_reports")

    # Determine content type
    content_type = "application/octet-stream"
    if filename.endswith(".html"):
        content_type = "text/html"
    elif filename.endswith(".json"):
        content_type = "application/json"
    elif filename.endswith(".md"):
        content_type = "text/plain; charset=utf-8"  # Plain text for markdown

    # For HTML and JSON, serve inline with FileResponse
    if filename.endswith((".html", ".json")):
        response = FileResponse(
            open(filepath, "rb"),
            content_type=content_type,
            as_attachment=False,  # Display inline
        )
        # Add CSP header to allow inline scripts for HTML reports
        if filename.endswith(".html"):
            response["Content-Security-Policy"] = (
                "default-src 'self' 'unsafe-inline' 'unsafe-eval' cdn.jsdelivr.net cdnjs.cloudflare.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' cdn.jsdelivr.net cdnjs.cloudflare.com;"
            )
        return response

    # For Markdown, render it in a template with viewer
    elif filename.endswith(".md"):
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()

        stat = os.stat(filepath)
        context = {
            "filename": filename,
            "content": content,
            "report_type": "markdown",
            "size": stat.st_size,
            "size_human": _human_readable_size(stat.st_size),
            "created_date": datetime.fromtimestamp(stat.st_ctime),
            "modified_date": datetime.fromtimestamp(stat.st_mtime),
        }
        return render(request, "surveys/analytics_report_markdown_view.html", context)

    # For other files, fallback to download
    return FileResponse(open(filepath, "rb"), content_type=content_type, as_attachment=True, filename=filename)


@block_source_user
@login_required
@require_http_methods(["POST"])
def survey_analytics_report_delete(request, filename):
    """
    Delete a survey analytics report file.
    """
    import os
    from django.conf import settings

    user = request.user

    # Check permission - only PX admins can delete reports
    if not user.is_px_admin():
        messages.error(request, "You don't have permission to delete analytics reports.")
        return redirect("surveys:analytics_reports")

    output_dir = getattr(settings, "SURVEY_REPORTS_DIR", "reports")
    filepath = os.path.join(output_dir, filename)

    # Security check
    if not os.path.abspath(filepath).startswith(os.path.abspath(output_dir)):
        messages.error(request, "Invalid report file.")
        return redirect("surveys:analytics_reports")

    if not os.path.exists(filepath):
        messages.error(request, "Report file not found.")
        return redirect("surveys:analytics_reports")

    try:
        os.remove(filepath)
        messages.success(request, f"Report '{filename}' deleted successfully.")
    except Exception as e:
        messages.error(request, f"Error deleting report: {str(e)}")

    return redirect("surveys:analytics_reports")


def _human_readable_size(size_bytes):
    """Convert bytes to human readable format"""
    for unit in ["B", "KB", "MB", "GB"]:
        if size_bytes < 1024.0:
            return f"{size_bytes:.2f} {unit}"
        size_bytes /= 1024.0
    return f"{size_bytes:.2f} TB"


# ============================================================================
# ENHANCED SURVEY REPORTS - Separate reports per survey type
# ============================================================================


@block_source_user
@login_required
def enhanced_survey_reports_list(request):
    """
    List all enhanced survey report directories.
    """
    from django.conf import settings
    import os

    user = request.user

    # Check permission
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to view analytics reports.")
        return redirect("surveys:analytics_reports")

    output_dir = getattr(settings, "SURVEY_REPORTS_DIR", "reports")

    # Find all report directories (folders starting with "reports_")
    report_sets = []
    if os.path.exists(output_dir):
        for item in sorted(os.listdir(output_dir), reverse=True):
            item_path = os.path.join(output_dir, item)
            if os.path.isdir(item_path) and item.startswith("reports_"):
                # Check if it has an index.html
                index_path = os.path.join(item_path, "index.html")
                if os.path.exists(index_path):
                    stat = os.stat(item_path)
                    # Count individual reports
                    report_count = len([f for f in os.listdir(item_path) if f.endswith(".html") and f != "index.html"])

                    report_sets.append(
                        {
                            "dir_name": item,
                            "created": datetime.fromtimestamp(stat.st_ctime),
                            "modified": datetime.fromtimestamp(stat.st_mtime),
                            "report_count": report_count,
                            "size": sum(
                                os.path.getsize(os.path.join(item_path, f))
                                for f in os.listdir(item_path)
                                if os.path.isfile(os.path.join(item_path, f))
                            ),
                        }
                    )

    context = {
        "report_sets": report_sets,
    }

    return render(request, "surveys/enhanced_reports_list.html", context)


@block_source_user
@login_required
def enhanced_survey_report_view(request, dir_name):
    """
    View the index of an enhanced report set.
    """
    from django.conf import settings
    import os

    user = request.user

    # Check permission
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to view analytics reports.")
        return redirect("surveys:analytics_reports")

    output_dir = getattr(settings, "SURVEY_REPORTS_DIR", "reports")
    dir_path = os.path.join(output_dir, dir_name)

    # Security check
    if not os.path.abspath(dir_path).startswith(os.path.abspath(output_dir)):
        messages.error(request, "Invalid report directory.")
        return redirect("surveys:enhanced_reports_list")

    if not os.path.exists(dir_path):
        messages.error(request, "Report directory not found.")
        return redirect("surveys:enhanced_reports_list")

    # Serve the index.html file
    index_path = os.path.join(dir_path, "index.html")
    if os.path.exists(index_path):
        with open(index_path, "r", encoding="utf-8") as f:
            content = f.read()
        return HttpResponse(content, content_type="text/html")

    messages.error(request, "Index file not found.")
    return redirect("surveys:enhanced_reports_list")


@block_source_user
@login_required
def enhanced_survey_report_file(request, dir_name, filename):
    """
    View/serve an individual enhanced report file.
    """
    from django.conf import settings
    import os
    from django.http import FileResponse

    user = request.user

    # Check permission
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to view analytics reports.")
        return redirect("surveys:analytics_reports")

    output_dir = getattr(settings, "SURVEY_REPORTS_DIR", "reports")
    dir_path = os.path.join(output_dir, dir_name)
    filepath = os.path.join(dir_path, filename)

    # Security check
    if not os.path.abspath(filepath).startswith(os.path.abspath(dir_path)):
        messages.error(request, "Invalid file path.")
        return redirect("surveys:enhanced_reports_list")

    if not os.path.exists(filepath):
        messages.error(request, "File not found.")
        return redirect("surveys:enhanced_reports_list")

    # Serve file based on type
    if filename.endswith(".html"):
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()
        response = HttpResponse(content, content_type="text/html")
        # Allow inline scripts/CDN resources
        response["Content-Security-Policy"] = (
            "default-src 'self' 'unsafe-inline' 'unsafe-eval' cdn.jsdelivr.net cdnjs.cloudflare.com unpkg.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' cdn.jsdelivr.net unpkg.com; style-src 'self' 'unsafe-inline' cdn.jsdelivr.net cdnjs.cloudflare.com fonts.googleapis.com; font-src 'self' fonts.gstatic.com;"
        )
        return response
    elif filename.endswith(".json"):
        return FileResponse(open(filepath, "rb"), content_type="application/json")
    else:
        return FileResponse(open(filepath, "rb"), as_attachment=True)


@block_source_user
@login_required
def generate_enhanced_report_ui(request):
    """
    UI view to generate enhanced reports with form.
    """
    from apps.surveys.models import SurveyTemplate
    from django.conf import settings

    user = request.user

    # Check permission
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to generate analytics reports.")
        return redirect("surveys:analytics_reports")

    if request.method == "POST":
        template_id = request.POST.get("template")
        start_date = request.POST.get("start_date")
        end_date = request.POST.get("end_date")

        try:
            # Get template name if specified
            template_name = None
            if template_id:
                try:
                    template = SurveyTemplate.objects.get(id=template_id)
                    template_name = template.name
                except SurveyTemplate.DoesNotExist:
                    pass

            # Parse dates
            start_dt = None
            end_dt = None
            if start_date:
                start_dt = datetime.strptime(start_date, "%Y-%m-%d").date()
            if end_date:
                end_dt = datetime.strptime(end_date, "%Y-%m-%d").date()

            # Generate enhanced reports
            from .analytics_utils import generate_enhanced_survey_reports

            result = generate_enhanced_survey_reports(template_name=template_name, start_date=start_dt, end_date=end_dt)

            messages.success(request, f"Generated {len(result['individual_reports'])} reports successfully!")

            # Redirect to the report directory
            dir_name = os.path.basename(result["reports_dir"])
            return redirect("surveys:enhanced_report_view", dir_name=dir_name)

        except Exception as e:
            messages.error(request, f"Error generating reports: {str(e)}")
            return redirect("surveys:enhanced_reports_list")

    # GET request - show form
    templates = SurveyTemplate.objects.filter(is_active=True).order_by("name")

    context = {
        "templates": templates,
    }

    return render(request, "surveys/generate_enhanced_report.html", context)


@block_source_user
@login_required
def survey_analytics_dashboard(request):
    """
    Standalone survey analytics dashboard with real-time metrics.

    Features:
    - Template selection with live metrics
    - Completion rates and trends
    - Question-level analysis
    - Response distribution charts
    - Time-based analytics
    """
    from .analytics import get_survey_engagement_stats

    user = request.user

    # Check permission
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, "You don't have permission to view analytics.")
        return redirect("surveys:instance_list")

    # Get available templates
    templates = SurveyTemplate.objects.filter(is_active=True).order_by("name")

    # Get selected template from query param
    selected_template_id = request.GET.get("template")
    selected_template = None
    analytics_data = None

    if selected_template_id:
        selected_template = get_object_or_404(SurveyTemplate, id=selected_template_id)
        # Get 30-day engagement stats for selected template
        analytics_data = get_survey_engagement_stats(
            survey_template_id=str(selected_template.id),
            hospital_id=str(user.hospital.id) if user.hospital else None,
            days=30,
        )

    context = {
        "templates": templates,
        "selected_template": selected_template,
        "analytics_data": analytics_data,
    }

    return render(request, "surveys/analytics_dashboard.html", context)
