"""
Complaints forms
"""
import os

from django import forms
from django.db import models
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.utils.translation import gettext_lazy as _

from apps.complaints.models import (
    Complaint,
    ComplaintCategory,
    ComplaintSource,
    ComplaintStatus,
    Inquiry,
    ComplaintSLAConfig,
    EscalationRule,
    ComplaintThreshold,
)
from apps.core.models import PriorityChoices, SeverityChoices
from apps.organizations.models import Department, Hospital, Patient, Staff


class MultiFileInput(forms.FileInput):
    """
    Custom FileInput widget that supports multiple file uploads.

    Unlike standard FileInput which only supports single files,
    this widget allows users to upload multiple files at once.
    """
    def __init__(self, attrs=None):
        # Call parent's __init__ first to avoid Django's 'multiple' check
        super().__init__(attrs)
        # Add 'multiple' attribute after initialization
        self.attrs['multiple'] = 'multiple'

    def value_from_datadict(self, data, files, name):
        """
        Get all uploaded files for a given field name.

        Returns a list of uploaded files instead of a single file.
        """
        if name in files:
            return files.getlist(name)
        return []


class PublicComplaintForm(forms.ModelForm):
    """
    Simplified public complaint submission form.

    Key changes for AI-powered classification:
    - Fewer required fields (simplified for public users)
    - Severity and priority removed (AI will determine these automatically)
    - Only essential information collected
    """

    # Contact Information
    name = forms.CharField(
        label=_("Name"),
        max_length=200,
        required=True,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': _('Your full name')
            }
        )
    )

    email = forms.EmailField(
        label=_("Email Address"),
        required=True,
        widget=forms.EmailInput(
            attrs={
                'class': 'form-control',
                'placeholder': _('your@email.com')
            }
        )
    )

    phone = forms.CharField(
        label=_("Phone Number"),
        max_length=20,
        required=True,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': _('Your phone number')
            }
        )
    )

    # Hospital and Department
    hospital = forms.ModelChoiceField(
        label=_("Hospital"),
        queryset=Hospital.objects.filter(status='active').order_by('name'),
        empty_label=_("Select Hospital"),
        required=True,
        widget=forms.Select(
            attrs={
                'class': 'form-control',
                'id': 'hospital_select',
                'data-action': 'load-departments'
            }
        )
    )

    department = forms.ModelChoiceField(
        label=_("Department (Optional)"),
        queryset=Department.objects.none(),
        empty_label=_("Select Department"),
        required=False,
        widget=forms.Select(
            attrs={
                'class': 'form-control',
                'id': 'department_select'
            }
        )
    )

    # Complaint Details
    category = forms.ModelChoiceField(
        label=_("Complaint Category"),
        queryset=ComplaintCategory.objects.filter(is_active=True).order_by('name_en'),
        empty_label=_("Select Category"),
        required=True,
        widget=forms.Select(
            attrs={
                'class': 'form-control',
                'id': 'category_select'
            }
        )
    )

    title = forms.CharField(
        label=_("Complaint Title"),
        max_length=200,
        required=True,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': _('Brief title of your complaint')
            }
        )
    )

    description = forms.CharField(
        label=_("Complaint Description"),
        required=True,
        widget=forms.Textarea(
            attrs={
                'class': 'form-control',
                'rows': 6,
                'placeholder': _('Please describe your complaint in detail. Our AI system will analyze and prioritize your complaint accordingly.')
            }
        )
    )

    # Hidden fields - these will be set by view or AI
    severity = forms.ChoiceField(
        label=_("Severity"),
        choices=SeverityChoices.choices,
        initial=SeverityChoices.MEDIUM,
        required=False,
        widget=forms.HiddenInput()
    )

    priority = forms.ChoiceField(
        label=_("Priority"),
        choices=PriorityChoices.choices,
        initial=PriorityChoices.MEDIUM,
        required=False,
        widget=forms.HiddenInput()
    )

    # File uploads
    attachments = forms.FileField(
        label=_("Attach Documents (Optional)"),
        required=False,
        widget=MultiFileInput(
            attrs={
                'class': 'form-control',
                'accept': 'image/*,.pdf,.doc,.docx'
            }
        ),
        help_text=_('You can upload images, PDFs, or Word documents (max 10MB each)')
    )

    class Meta:
        model = Complaint
        fields = [
            'name', 'email', 'phone', 'hospital', 'department',
            'category', 'title', 'description', 'severity', 'priority'
        ]
        # Note: 'attachments' is not in fields because Complaint model doesn't have this field.
        # Attachments are handled separately via ComplaintAttachment model in the view.

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Check both initial data and POST data for hospital
        hospital_id = None
        if 'hospital' in self.initial:
            hospital_id = self.initial['hospital']
        elif 'hospital' in self.data:
            hospital_id = self.data['hospital']

        if hospital_id:
            # Filter departments
            self.fields['department'].queryset = Department.objects.filter(
                hospital_id=hospital_id,
                status='active'
            ).order_by('name')

            # Filter categories (show hospital-specific first, then system-wide)
            self.fields['category'].queryset = ComplaintCategory.objects.filter(
                models.Q(hospital_id=hospital_id) | models.Q(hospital__isnull=True),
                is_active=True
            ).order_by('hospital', 'order', 'name_en')


    def clean_attachments(self):
        """Validate file attachments"""
        files = self.files.getlist('attachments')

        # Check file count
        if len(files) > 5:
            raise ValidationError(_('Maximum 5 files allowed'))

        # Check each file
        for file in files:
            # Check file size (10MB limit)
            if file.size > 10 * 1024 * 1024:
                raise ValidationError(_('File size must be less than 10MB'))

            # Check file type
            allowed_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.pdf', '.doc', '.docx']
            ext = os.path.splitext(file.name)[1].lower()
            if ext not in allowed_extensions:
                raise ValidationError(_('Allowed file types: JPG, PNG, GIF, PDF, DOC, DOCX'))

        return files

    def clean(self):
        """Custom cross-field validation"""
        cleaned_data = super().clean()

        # Basic validation - all required fields are already validated by field definitions
        # This method is kept for future custom cross-field validation needs

        return cleaned_data


class ComplaintForm(forms.ModelForm):
    """
    Form for creating complaints by authenticated users.
    
    Uses Django form rendering with minimal JavaScript for dependent dropdowns.
    Category, subcategory, and source are omitted - AI will determine them.
    """

    patient = forms.ModelChoiceField(
        label=_("Patient"),
        queryset=Patient.objects.filter(status='active'),
        empty_label=_("Select Patient"),
        required=True,
        widget=forms.Select(attrs={'class': 'form-select', 'id': 'patientSelect'})
    )

    hospital = forms.ModelChoiceField(
        label=_("Hospital"),
        queryset=Hospital.objects.filter(status='active'),
        empty_label=_("Select Hospital"),
        required=True,
        widget=forms.Select(attrs={'class': 'form-select', 'id': 'hospitalSelect'})
    )

    department = forms.ModelChoiceField(
        label=_("Department"),
        queryset=Department.objects.none(),
        empty_label=_("Select Department"),
        required=False,
        widget=forms.Select(attrs={'class': 'form-select', 'id': 'departmentSelect'})
    )

    staff = forms.ModelChoiceField(
        label=_("Staff"),
        queryset=Staff.objects.none(),
        empty_label=_("Select Staff"),
        required=False,
        widget=forms.Select(attrs={'class': 'form-select', 'id': 'staffSelect'})
    )

    encounter_id = forms.CharField(
        label=_("Encounter ID"),
        required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 
                                     'placeholder': _('Optional encounter/visit ID')})
    )

    description = forms.CharField(
        label=_("Description"),
        required=True,
        widget=forms.Textarea(attrs={'class': 'form-control', 
                                       'rows': 6,
                                       'placeholder': _('Detailed description of complaint...')})
    )

    class Meta:
        model = Complaint
        fields = ['patient', 'hospital', 'department', 'staff', 
                   'encounter_id', 'description']

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)

        # Filter hospitals and patients based on user permissions
        if user and not user.is_px_admin() and user.hospital:
            self.fields['hospital'].queryset = Hospital.objects.filter(id=user.hospital.id)
            self.fields['hospital'].initial = user.hospital
            self.fields['patient'].queryset = Patient.objects.filter(
                primary_hospital=user.hospital,
                status='active'
            )
        
        # Check for hospital selection in both initial data and POST data
        hospital_id = None
        if 'hospital' in self.data:
            hospital_id = self.data.get('hospital')
        elif 'hospital' in self.initial:
            hospital_id = self.initial.get('hospital')
            
        if hospital_id:
            # Filter departments based on selected hospital
            self.fields['department'].queryset = Department.objects.filter(
                hospital_id=hospital_id,
                status='active'
            ).order_by('name')
            
            # Filter staff based on selected hospital
            self.fields['staff'].queryset = Staff.objects.filter(
                hospital_id=hospital_id,
                status='active'
            ).order_by('first_name', 'last_name')


class InquiryForm(forms.ModelForm):
    """
    Form for creating inquiries by authenticated users.
    
    Similar to ComplaintForm - supports patient search, department filtering, 
    and proper field validation with AJAX support.
    """

    patient = forms.ModelChoiceField(
        label=_("Patient (Optional)"),
        queryset=Patient.objects.filter(status='active'),
        empty_label=_("Select Patient"),
        required=False,
        widget=forms.Select(attrs={'class': 'form-select', 'id': 'patientSelect'})
    )

    hospital = forms.ModelChoiceField(
        label=_("Hospital"),
        queryset=Hospital.objects.filter(status='active'),
        empty_label=_("Select Hospital"),
        required=True,
        widget=forms.Select(attrs={'class': 'form-select', 'id': 'hospitalSelect'})
    )

    department = forms.ModelChoiceField(
        label=_("Department (Optional)"),
        queryset=Department.objects.none(),
        empty_label=_("Select Department"),
        required=False,
        widget=forms.Select(attrs={'class': 'form-select', 'id': 'departmentSelect'})
    )

    category = forms.ChoiceField(
        label=_("Inquiry Type"),
        choices=[
            ('general', 'General Inquiry'),
            ('appointment', 'Appointment Related'),
            ('billing', 'Billing & Insurance'),
            ('medical_records', 'Medical Records'),
            ('pharmacy', 'Pharmacy'),
            ('insurance', 'Insurance'),
            ('feedback', 'Feedback'),
            ('other', 'Other'),
        ],
        required=True,
        widget=forms.Select(attrs={'class': 'form-control'})
    )

    subject = forms.CharField(
        label=_("Subject"),
        max_length=200,
        required=True,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('Brief subject')})
    )

    message = forms.CharField(
        label=_("Message"),
        required=True,
        widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 5, 'placeholder': _('Describe your inquiry')})
    )

    # Contact info for inquiries without patient
    contact_name = forms.CharField(label=_("Contact Name"), max_length=200, required=False, widget=forms.TextInput(attrs={'class': 'form-control'}))
    contact_phone = forms.CharField(label=_("Contact Phone"), max_length=20, required=False, widget=forms.TextInput(attrs={'class': 'form-control'}))
    contact_email = forms.EmailField(label=_("Contact Email"), required=False, widget=forms.EmailInput(attrs={'class': 'form-control'}))

    class Meta:
        model = Inquiry
        fields = ['patient', 'hospital', 'department', 'subject', 'message', 
                   'contact_name', 'contact_phone', 'contact_email']

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)

        # Filter hospitals based on user role
        if user and not user.is_px_admin() and user.hospital:
            self.fields['hospital'].queryset = Hospital.objects.filter(id=user.hospital.id)
            self.fields['hospital'].initial = user.hospital
            self.fields['hospital'].widget.attrs['readonly'] = True
        
        # Check for hospital selection in both initial data and POST data
        hospital_id = None
        if 'hospital' in self.data:
            hospital_id = self.data.get('hospital')
        elif 'hospital' in self.initial:
            hospital_id = self.initial.get('hospital')
            
        if hospital_id:
            # Filter departments based on selected hospital
            self.fields['department'].queryset = Department.objects.filter(
                hospital_id=hospital_id,
                status='active'
            ).order_by('name')


class SLAConfigForm(forms.ModelForm):
    """Form for creating and editing SLA configurations"""

    class Meta:
        model = ComplaintSLAConfig
        fields = ['hospital', 'severity', 'priority', 'sla_hours', 'reminder_hours_before', 'is_active']
        widgets = {
            'hospital': forms.Select(attrs={'class': 'form-select'}),
            'severity': forms.Select(attrs={'class': 'form-select'}),
            'priority': forms.Select(attrs={'class': 'form-select'}),
            'sla_hours': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}),
            'reminder_hours_before': forms.NumberInput(attrs={'class': 'form-control', 'min': '0'}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        }

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)

        # Filter hospitals based on user role
        if user and not user.is_px_admin() and user.hospital:
            self.fields['hospital'].queryset = Hospital.objects.filter(id=user.hospital.id)
            self.fields['hospital'].initial = user.hospital
            self.fields['hospital'].widget.attrs['readonly'] = True

    def clean(self):
        cleaned_data = super().clean()
        hospital = cleaned_data.get('hospital')
        severity = cleaned_data.get('severity')
        priority = cleaned_data.get('priority')
        sla_hours = cleaned_data.get('sla_hours')
        reminder_hours = cleaned_data.get('reminder_hours_before')

        # Validate SLA hours is positive
        if sla_hours and sla_hours <= 0:
            raise ValidationError({'sla_hours': 'SLA hours must be greater than 0'})

        # Validate reminder hours < SLA hours
        if sla_hours and reminder_hours and reminder_hours >= sla_hours:
            raise ValidationError({'reminder_hours_before': 'Reminder hours must be less than SLA hours'})

        # Check for unique combination (excluding current instance when editing)
        if hospital and severity and priority:
            queryset = ComplaintSLAConfig.objects.filter(
                hospital=hospital,
                severity=severity,
                priority=priority
            )
            if self.instance.pk:
                queryset = queryset.exclude(pk=self.instance.pk)
            if queryset.exists():
                raise ValidationError(
                    'An SLA configuration for this hospital, severity, and priority already exists.'
                )

        return cleaned_data


class EscalationRuleForm(forms.ModelForm):
    """Form for creating and editing escalation rules"""

    class Meta:
        model = EscalationRule
        fields = [
            'hospital', 'name', 'description', 'escalation_level', 'max_escalation_level',
            'trigger_on_overdue', 'trigger_hours_overdue',
            'reminder_escalation_enabled', 'reminder_escalation_hours',
            'escalate_to_role', 'escalate_to_user',
            'severity_filter', 'priority_filter', 'is_active'
        ]
        widgets = {
            'hospital': forms.Select(attrs={'class': 'form-select'}),
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
            'escalation_level': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}),
            'max_escalation_level': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}),
            'trigger_on_overdue': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'trigger_hours_overdue': forms.NumberInput(attrs={'class': 'form-control', 'min': '0'}),
            'reminder_escalation_enabled': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'reminder_escalation_hours': forms.NumberInput(attrs={'class': 'form-control', 'min': '0'}),
            'escalate_to_role': forms.Select(attrs={'class': 'form-select', 'id': 'escalate_to_role'}),
            'escalate_to_user': forms.Select(attrs={'class': 'form-select'}),
            'severity_filter': forms.Select(attrs={'class': 'form-select'}),
            'priority_filter': forms.Select(attrs={'class': 'form-select'}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        }

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)

        # Filter hospitals based on user role
        if user and not user.is_px_admin() and user.hospital:
            self.fields['hospital'].queryset = Hospital.objects.filter(id=user.hospital.id)
            self.fields['hospital'].initial = user.hospital
            self.fields['hospital'].widget.attrs['readonly'] = True

        # Filter users for escalate_to_user field
        from apps.accounts.models import User
        if user and user.is_px_admin():
            self.fields['escalate_to_user'].queryset = User.objects.filter(is_active=True)
        elif user and user.hospital:
            self.fields['escalate_to_user'].queryset = User.objects.filter(
                is_active=True,
                hospital=user.hospital
            )
        else:
            self.fields['escalate_to_user'].queryset = User.objects.none()

    def clean(self):
        cleaned_data = super().clean()
        escalate_to_role = cleaned_data.get('escalate_to_role')
        escalate_to_user = cleaned_data.get('escalate_to_user')

        # If role is 'specific_user', user must be specified
        if escalate_to_role == 'specific_user' and not escalate_to_user:
            raise ValidationError({'escalate_to_user': 'Please select a user when role is set to Specific User'})

        return cleaned_data


class ComplaintThresholdForm(forms.ModelForm):
    """Form for creating and editing complaint thresholds"""

    class Meta:
        model = ComplaintThreshold
        fields = ['hospital', 'threshold_type', 'threshold_value', 'comparison_operator', 'action_type', 'is_active']
        widgets = {
            'hospital': forms.Select(attrs={'class': 'form-select'}),
            'threshold_type': forms.Select(attrs={'class': 'form-select'}),
            'threshold_value': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.1'}),
            'comparison_operator': forms.Select(attrs={'class': 'form-select'}),
            'action_type': forms.Select(attrs={'class': 'form-select'}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
        }

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)

        # Filter hospitals based on user role
        if user and not user.is_px_admin() and user.hospital:
            self.fields['hospital'].queryset = Hospital.objects.filter(id=user.hospital.id)
            self.fields['hospital'].initial = user.hospital
            self.fields['hospital'].widget.attrs['readonly'] = True


class PublicInquiryForm(forms.Form):
    """Public inquiry submission form (simpler, for general questions)"""

    # Contact Information
    name = forms.CharField(
        label=_("Name"),
        max_length=200,
        required=True,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': _('Your full name')
            }
        )
    )

    phone = forms.CharField(
        label=_("Phone Number"),
        max_length=20,
        required=True,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': _('Your phone number')
            }
        )
    )

    email = forms.EmailField(
        label=_("Email Address"),
        required=False,
        widget=forms.EmailInput(
            attrs={
                'class': 'form-control',
                'placeholder': _('your@email.com')
            }
        )
    )

    # Inquiry Details
    hospital = forms.ModelChoiceField(
        label=_("Hospital"),
        queryset=Hospital.objects.filter(status='active').order_by('name'),
        empty_label=_("Select Hospital"),
        required=True,
        widget=forms.Select(attrs={'class': 'form-control'})
    )

    category = forms.ChoiceField(
        label=_("Inquiry Type"),
        choices=[
            ('general', 'General Inquiry'),
            ('appointment', 'Appointment Related'),
            ('billing', 'Billing & Insurance'),
            ('medical_records', 'Medical Records'),
            ('other', 'Other'),
        ],
        required=True,
        widget=forms.Select(attrs={'class': 'form-control'})
    )

    subject = forms.CharField(
        label=_("Subject"),
        max_length=200,
        required=True,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': _('Brief subject')
            }
        )
    )

    message = forms.CharField(
        label=_("Message"),
        required=True,
        widget=forms.Textarea(
            attrs={
                'class': 'form-control',
                'rows': 5,
                'placeholder': _('Describe your inquiry')
            }
        )
    )
