#!/usr/bin/env python
"""
Scenario 1: Successful Explanation Submission

Tests the happy path where a staff member submits their explanation
before the SLA deadline. No escalation should occur.

Time Compression: 1 second = 1 hour
SLA Deadline: 10 hours (10 seconds)
"""
import os
import sys
import django

# Setup Django
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.dev')
django.setup()

from scenario_test_base import ScenarioTestBase
from django.utils import timezone
from apps.complaints.models import Complaint, ComplaintCategory, ComplaintExplanation, ComplaintSLAConfig
from apps.organizations.models import Hospital, Department, Staff
from apps.accounts.models import User, UserManager


class Scenario1SuccessfulExplanation(ScenarioTestBase):
    """Test successful explanation submission before SLA deadline"""
    
    def run(self):
        """Run the complete scenario"""
        self.print_header("SCENARIO 1: SUCCESSFUL EXPLANATION SUBMISSION")
        
        successful_steps = 0
        total_steps = 7
        
        try:
            # Step 1: Setup
            self.print_step("Setting up test environment", 0)
            hospital, department, staff = self.setup_environment()
            successful_steps += 1
            
            # Step 2: Create complaint
            self.print_step("Creating complaint", 2)  # Wait 2s (simulates 2 hours)
            complaint = self.create_complaint(hospital, department, staff)
            successful_steps += 1
            
            # Step 3: Request explanation
            self.print_step("Requesting explanation from staff", 1)  # Wait 1s (simulates 1 hour)
            explanation = self.request_explanation(complaint, staff)
            successful_steps += 1
            
            # Step 4: Verify initial state (pending, no reminder, no overdue)
            self.print_step("Verifying initial explanation state", 0)
            if self.verify_explanation_state(explanation, 'pending'):
                successful_steps += 1
            else:
                self.print_error("Initial state verification failed")
            
            # Step 5: Staff submits explanation (before deadline)
            self.print_step("Staff submits explanation (before deadline)", 3)  # Wait 3s (simulates 3 hours)
            self.submit_explanation(explanation, "This is my explanation about the complaint.")
            successful_steps += 1
            
            # Step 6: Verify explanation submitted
            self.print_step("Verifying explanation submitted successfully", 0)
            if self.verify_explanation_state(explanation, 'submitted'):
                successful_steps += 1
            else:
                self.print_error("Submission verification failed")
            
            # Step 7: Verify no escalation occurred
            self.print_step("Verifying no escalation occurred", 0)
            explanation.refresh_from_db()
            if explanation.escalated_to_manager is None:
                self.print_success("No escalation occurred (as expected)")
                successful_steps += 1
            else:
                self.print_error("Unexpected escalation occurred")
            
        except Exception as e:
            self.print_error(f"Test failed with exception: {str(e)}")
            import traceback
            traceback.print_exc()
        
        self.print_summary(total_steps, successful_steps)
        return successful_steps == total_steps
    
    def setup_environment(self):
        """Setup hospital, department, and staff"""
        # Get or create hospital
        hospital = Hospital.objects.filter(name__icontains="Al Hammadi").first()
        if not hospital:
            hospital = Hospital.objects.create(
                name="Al Hammadi Hospital",
                name_ar="مستشفى الحمادي",
                code="ALH",
                phone="+966114444444",
                email="info@alhammadi.sa",
                status='active'
            )
            self.print_success(f"Created hospital: {hospital.name}")
        
        # Get or create department
        department = Department.objects.filter(
            hospital=hospital,
            name__icontains="Emergency"
        ).first()
        if not department:
            department = Department.objects.create(
                hospital=hospital,
                name="Emergency Department",
                name_ar="قسم الطوارئ",
                code="ED",
                status='active'
            )
            self.print_success(f"Created department: {department.name}")
        
        # Create or get staff member
        staff, created = Staff.objects.get_or_create(
            email=f"omar.harbi@{hospital.name.lower().replace(' ', '')}.test",
            defaults={
                'hospital': hospital,
                'department': department,
                'first_name': "Omar",
                'last_name': "Al-Harbi",
                'first_name_ar': "عمر",
                'last_name_ar': "الحربي",
                'job_title': "Nurse",
                'specialization': "Patient Care",
                'phone': "+966513333333",
                'status': 'active'
            }
        )
        if created:
            self.print_success(f"Created staff member: {staff.get_full_name()}")
        else:
            self.print_info(f"Using existing staff member: {staff.get_full_name()}")
        
        # Configure SLA
        self.create_explanation_sla_config(
            hospital=hospital,
            response_hours=10,  # 10 hours = 10 seconds in test
            reminder_hours_before=5,  # Reminder 5 hours before
            auto_escalate_enabled=True,
            escalation_hours_overdue=0
        )
        
        self.create_complaint_sla_config(
            hospital=hospital,
            severity='medium',
            priority='medium',
            sla_hours=72,
            reminder_hours_before=24
        )
        
        return hospital, department, staff
    
    def create_complaint(self, hospital, department, staff):
        """Create a test complaint"""
        # Get or create category
        category = ComplaintCategory.objects.filter(
            hospitals=hospital,
            name_en__icontains="Service"
        ).first()
        if not category:
            category = ComplaintCategory.objects.create(
                code="SRV",
                name_en="Service Quality",
                name_ar="جودة الخدمة",
                description_en="Complaints about service quality",
                description_ar="شكاوى حول جودة الخدمة"
            )
            category.hospitals.add(hospital)
        
        # Create complaint
        complaint = Complaint.objects.create(
            hospital=hospital,
            department=department,
            staff=staff,
            title="Poor response time in emergency",
            description="Nurse Omar Al-Harbi took too long to respond to my emergency situation. The delay was unacceptable and caused unnecessary distress.",
            severity='medium',
            priority='medium',
            source_id=None,
            status='open',
            contact_name="Test Patient",
            contact_phone="+966599999999",
            contact_email="patient@test.com"
        )
        
        self.print_success(
            f"Created complaint: {complaint.title[:50]}... "
            f"(ID: {complaint.id})"
        )
        self.print_info(f"  Severity: {complaint.severity}")
        self.print_info(f"  Priority: {complaint.priority}")
        self.print_info(f"  Status: {complaint.status}")
        self.print_info(f"  Staff: {staff.get_full_name()}")
        
        return complaint
    
    def request_explanation(self, complaint, staff):
        """Request explanation from staff"""
        # Get admin user
        admin = User.objects.filter(
            hospital=complaint.hospital,
            groups__name='Hospital Admin'
        ).first()
        if not admin:
            # Create admin user using User.objects.create_user
            admin = User.objects.create_user(
                email=f"admin@{complaint.hospital.name.lower().replace(' ', '')}.test",
                password="test123",
                first_name="Hospital",
                last_name="Admin",
                hospital=complaint.hospital,
                phone="+966500000000"
            )
            from django.contrib.auth.models import Group
            admin_group, _ = Group.objects.get_or_create(name='Hospital Admin')
            admin.groups.add(admin_group)
        
        # Create explanation request
        import secrets
        explanation = ComplaintExplanation.objects.create(
            complaint=complaint,
            staff=staff,
            explanation='',  # Will be filled by staff
            token=secrets.token_urlsafe(64),
            is_used=False,
            submitted_via='email_link',
            requested_by=admin,
            request_message="Please provide your explanation about this complaint.",
            email_sent_at=None,  # Will be set by email task
            sla_due_at=None  # Will be set by email task
        )
        
        self.print_success(f"Created explanation request for {staff.get_full_name()}")
        self.print_info(f"  Token: {explanation.token[:20]}...")
        
        # Send email (simulate by calling the task directly)
        from apps.complaints.tasks import send_explanation_request_email
        result = send_explanation_request_email(str(explanation.id))
        
        if result['status'] == 'sent':
            self.print_success(f"Explanation request email sent")
            explanation.refresh_from_db()
            self.print_info(f"  SLA Due At: {explanation.sla_due_at}")
            hours_until_due = (explanation.sla_due_at - timezone.now()).total_seconds() / 3600
            self.print_info(f"  Hours until deadline: {hours_until_due:.1f}")
        else:
            self.print_error(f"Failed to send email: {result.get('reason', 'Unknown')}")
        
        return explanation
    
    def submit_explanation(self, explanation, explanation_text):
        """Simulate staff submitting explanation"""
        # Update explanation
        explanation.explanation = explanation_text
        explanation.is_used = True
        explanation.responded_at = timezone.now()
        explanation.save(update_fields=['explanation', 'is_used', 'responded_at'])
        
        self.print_success("Staff submitted explanation")
        self.print_info(f"  Response time: {explanation.responded_at}")
        self.print_info(f"  SLA deadline: {explanation.sla_due_at}")
        
        # Check if submitted before deadline
        if explanation.responded_at < explanation.sla_due_at:
            hours_before_deadline = (explanation.sla_due_at - explanation.responded_at).total_seconds() / 3600
            self.print_success(f"Submitted {hours_before_deadline:.1f} hours BEFORE deadline ✓")
        else:
            hours_after_deadline = (explanation.responded_at - explanation.sla_due_at).total_seconds() / 3600
            self.print_warning(f"Submitted {hours_after_deadline:.1f} hours AFTER deadline")
        
        return explanation


def main():
    """Main entry point"""
    test = Scenario1SuccessfulExplanation(time_compression_ratio=1)  # 1s = 1 hour
    success = test.run()
    
    if success:
        print("\n✓ Scenario 1 completed successfully!")
        sys.exit(0)
    else:
        print("\n✗ Scenario 1 failed!")
        sys.exit(1)


if __name__ == '__main__':
    main()
