"""
Journeys views and viewsets
"""
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

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

from .models import (
    PatientJourneyInstance,
    PatientJourneyStageInstance,
    PatientJourneyStageTemplate,
    PatientJourneyTemplate,
)
from .serializers import (
    PatientJourneyInstanceListSerializer,
    PatientJourneyInstanceSerializer,
    PatientJourneyStageInstanceSerializer,
    PatientJourneyStageTemplateSerializer,
    PatientJourneyTemplateSerializer,
)


class PatientJourneyTemplateViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Journey Templates.

    Permissions:
    - PX Admins and Hospital Admins can manage templates
    - Others can view templates
    """
    queryset = PatientJourneyTemplate.objects.all()
    serializer_class = PatientJourneyTemplateSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = ['journey_type', 'hospital', 'is_active', 'is_default', 'hospital__organization']
    search_fields = ['name', 'name_ar', 'description']
    ordering_fields = ['name', 'created_at']
    ordering = ['hospital', 'journey_type', 'name']

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

        # PX Admins see all templates
        if user.is_px_admin():
            return queryset

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

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

        return queryset.none()


class PatientJourneyStageTemplateViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Journey Stage Templates.

    Permissions:
    - PX Admins and Hospital Admins can manage stage templates
    """
    queryset = PatientJourneyStageTemplate.objects.all()
    serializer_class = PatientJourneyStageTemplateSerializer
    permission_classes = [IsAuthenticated, IsPXAdminOrHospitalAdmin]
    filterset_fields = ['journey_template', 'is_active', 'auto_send_survey']
    search_fields = ['name', 'name_ar', 'code', 'trigger_event_code']
    ordering_fields = ['order', 'name']
    ordering = ['journey_template', 'order']

    def get_queryset(self):
        queryset = super().get_queryset().select_related('journey_template', 'survey_template')
        user = self.request.user

        # PX Admins see all stage templates
        if user.is_px_admin():
            return queryset

        # Hospital Admins see stage templates for their hospital
        if user.is_hospital_admin() and user.hospital:
            return queryset.filter(journey_template__hospital=user.hospital)

        return queryset.none()


class PatientJourneyInstanceViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Journey Instances.

    Permissions:
    - All authenticated users can view journey instances
    - PX Admins and Hospital Admins can create/manage instances
    """
    queryset = PatientJourneyInstance.objects.all()
    permission_classes = [IsAuthenticated]
    filterset_fields = [
        'journey_template', 'journey_template__journey_type',
        'patient', 'hospital', 'department', 'status',
        'hospital__organization'
    ]
    search_fields = ['encounter_id', 'patient__mrn', 'patient__first_name', 'patient__last_name']
    ordering_fields = ['started_at', 'completed_at']
    ordering = ['-started_at']

    def get_serializer_class(self):
        """Use simplified serializer for list view"""
        if self.action == 'list':
            return PatientJourneyInstanceListSerializer
        return PatientJourneyInstanceSerializer

    def get_queryset(self):
        """Filter journey instances based on user role"""
        queryset = super().get_queryset().select_related(
            'journey_template', 'patient', 'hospital', 'department'
        ).prefetch_related('stage_instances__stage_template')

        user = self.request.user

        # PX Admins see all journey instances
        if user.is_px_admin():
            return queryset

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

        # Department Managers see instances for their department
        if user.is_department_manager() and user.department:
            return queryset.filter(department=user.department)

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

        return queryset.none()

    def perform_create(self, serializer):
        """
        Create journey instance and initialize stage instances.

        When a journey instance is created, automatically create
        stage instances for all stages in the template.
        """
        journey_instance = serializer.save()

        # Create stage instances for all stages in the template
        for stage_template in journey_instance.journey_template.stages.filter(is_active=True):
            PatientJourneyStageInstance.objects.create(
                journey_instance=journey_instance,
                stage_template=stage_template
            )

        # Log journey creation
        AuditService.log_from_request(
            event_type='journey_started',
            description=f"Journey started for encounter {journey_instance.encounter_id}",
            request=self.request,
            content_object=journey_instance,
            metadata={
                'journey_type': journey_instance.journey_template.journey_type,
                'patient_mrn': journey_instance.patient.mrn
            }
        )

    @action(detail=True, methods=['get'])
    def progress(self, request, pk=None):
        """Get journey progress summary"""
        journey = self.get_object()

        stages = journey.stage_instances.select_related('stage_template').order_by('stage_template__order')

        progress_data = {
            'journey_id': str(journey.id),
            'encounter_id': journey.encounter_id,
            'patient': journey.patient.get_full_name(),
            'journey_type': journey.journey_template.journey_type,
            'status': journey.status,
            'completion_percentage': journey.get_completion_percentage(),
            'is_complete': journey.is_complete(),
            'started_at': journey.started_at,
            'completed_at': journey.completed_at,
            'stages': [
                {
                    'name': stage.stage_template.name,
                    'order': stage.stage_template.order,
                    'status': stage.status,
                    'completed_at': stage.completed_at,
                    'survey_sent': stage.survey_sent_at is not None,
                }
                for stage in stages
            ]
        }

        return Response(progress_data)


class PatientJourneyStageInstanceViewSet(viewsets.ReadOnlyModelViewSet):
    """
    ViewSet for Journey Stage Instances (read-only).

    Stage instances are created automatically and updated via event processing.
    Manual updates should be done through the admin interface.
    """
    queryset = PatientJourneyStageInstance.objects.all()
    serializer_class = PatientJourneyStageInstanceSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = ['journey_instance', 'stage_template', 'status']
    search_fields = ['journey_instance__encounter_id', 'stage_template__name']
    ordering_fields = ['completed_at', 'created_at']
    ordering = ['journey_instance', 'stage_template__order']

    def get_queryset(self):
        """Filter stage instances based on user role"""
        queryset = super().get_queryset().select_related(
            'journey_instance',
            'stage_template',
            'physician',
            'department',
            'survey_instance'
        )

        user = self.request.user

        # PX Admins see all stage instances
        if user.is_px_admin():
            return queryset

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

        # Department Managers see instances for their department
        if user.is_department_manager() and user.department:
            return queryset.filter(journey_instance__department=user.department)

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

        return queryset.none()
