"""
Organizations views and viewsets
"""
from django.db import models
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated

from apps.accounts.permissions import CanAccessDepartmentData, CanAccessHospitalData, IsPXAdminOrHospitalAdmin

from .models import Department, Hospital, Organization, Patient, Staff
from .models import Staff as StaffModel
from .serializers import (
    DepartmentSerializer,
    HospitalSerializer,
    OrganizationSerializer,
    PatientListSerializer,
    PatientSerializer,
    StaffSerializer,
)


class OrganizationViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Organization model.

    Permissions:
    - PX Admins can manage organizations
    - Others can view organizations
    """
    queryset = Organization.objects.all()
    serializer_class = OrganizationSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = ['status', 'city']
    search_fields = ['name', 'name_ar', 'code', 'license_number']
    ordering_fields = ['name', 'created_at']
    ordering = ['name']

    def get_queryset(self):
        """Filter organizations based on user role"""
        queryset = super().get_queryset().prefetch_related('hospitals')
        user = self.request.user

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

        # Hospital Admins and others see their organization
        if user.is_hospital_admin() and user.hospital and user.hospital.organization:
            return queryset.filter(id=user.hospital.organization.id)

        # Others with hospital see their organization
        if user.hospital and user.hospital.organization:
            return queryset.filter(id=user.hospital.organization.id)

        return queryset.none()


class HospitalViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Hospital model.

    Permissions:
    - PX Admins and Hospital Admins can manage hospitals
    - Others can view hospitals they belong to
    """
    queryset = Hospital.objects.all()
    serializer_class = HospitalSerializer
    permission_classes = [IsAuthenticated, CanAccessHospitalData]
    filterset_fields = ['status', 'city', 'organization']
    search_fields = ['name', 'name_ar', 'code', 'city']
    ordering_fields = ['name', 'created_at']
    ordering = ['name']

    def get_queryset(self):
        """Filter hospitals based on user role"""
        queryset = super().get_queryset()
        user = self.request.user

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

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

        # Department Managers see their hospital
        if user.is_department_manager() and user.hospital:
            return queryset.filter(id=user.hospital.id)

        # Others see hospitals they're associated with
        if user.hospital:
            return queryset.filter(id=user.hospital.id)

        return queryset.none()


class DepartmentViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Department model.

    Permissions:
    - PX Admins and Hospital Admins can manage departments
    - Department Managers can view their department
    """
    queryset = Department.objects.all()
    serializer_class = DepartmentSerializer
    permission_classes = [IsAuthenticated, CanAccessDepartmentData]
    filterset_fields = ['status', 'hospital', 'parent', 'hospital__organization']
    search_fields = ['name', 'name_ar', 'code']
    ordering_fields = ['name', 'created_at']
    ordering = ['hospital', 'name']

    def get_queryset(self):
        """Filter departments based on user role"""
        queryset = super().get_queryset().select_related('hospital', 'parent', 'manager')
        user = self.request.user

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

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

        # Department Managers see their department and sub-departments
        if user.is_department_manager() and user.department:
            return queryset.filter(
                hospital=user.hospital
            ).filter(
                models.Q(id=user.department.id) | models.Q(parent=user.department)
            )

        # Others see departments in their hospital
        if user.hospital:
            return queryset.filter(hospital=user.hospital)

        return queryset.none()


class StaffViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Staff model.

    Permissions:
    - PX Admins and Hospital Admins can manage staff
    - Others can view staff
    """
    queryset = StaffModel.objects.all()
    serializer_class = StaffSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = ['status', 'hospital', 'department', 'staff_type', 'specialization', 'job_title', 'hospital__organization']
    search_fields = ['first_name', 'last_name', 'first_name_ar', 'last_name_ar', 'employee_id', 'license_number', 'job_title']
    ordering_fields = ['last_name', 'created_at']
    ordering = ['last_name', 'first_name']

    def get_queryset(self):
        """Filter staff based on user role"""
        queryset = super().get_queryset().select_related('hospital', 'department', 'user')
        user = self.request.user

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

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

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

        # Others see staff in their hospital
        if user.hospital:
            return queryset.filter(hospital=user.hospital)

        return queryset.none()


class PatientViewSet(viewsets.ModelViewSet):
    """
    ViewSet for Patient model.

    Permissions:
    - All authenticated users can view patients
    - PX Admins and Hospital Admins can manage patients
    """
    queryset = Patient.objects.all()
    permission_classes = [IsAuthenticated]
    filterset_fields = ['status', 'gender', 'primary_hospital', 'city', 'primary_hospital__organization']
    search_fields = ['mrn', 'national_id', 'first_name', 'last_name', 'phone', 'email']
    ordering_fields = ['last_name', 'created_at']
    ordering = ['last_name', 'first_name']

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

    def get_queryset(self):
        """Filter patients based on user role"""
        queryset = super().get_queryset().select_related('primary_hospital')
        user = self.request.user

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

        # Hospital Admins see patients in their hospital
        if user.is_hospital_admin() and user.hospital:
            return queryset.filter(primary_hospital=user.hospital)

        # Others see patients in their hospital
        if user.hospital:
            return queryset.filter(primary_hospital=user.hospital)

        return queryset
