"""
Management command to seed staff data with bilingual support (English and Arabic)
"""
import random
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction

from apps.accounts.models import User
from apps.organizations.models import Hospital, Department, Staff
from apps.organizations.services import StaffService


# Saudi names data - Paired to ensure English and Arabic correspond
NAMES_MALE = [
    {'en': 'Mohammed', 'ar': 'محمد'},
    {'en': 'Ahmed', 'ar': 'أحمد'},
    {'en': 'Abdullah', 'ar': 'عبدالله'},
    {'en': 'Khalid', 'ar': 'خالد'},
    {'en': 'Saud', 'ar': 'سعود'},
    {'en': 'Fahd', 'ar': 'فهد'},
    {'en': 'Abdulaziz', 'ar': 'عبدالعزيز'},
    {'en': 'Sultan', 'ar': 'سلطان'},
    {'en': 'Faisal', 'ar': 'فيصل'},
    {'en': 'Omar', 'ar': 'عمر'},
    {'en': 'Turki', 'ar': 'تركي'},
    {'en': 'Nasser', 'ar': 'ناصر'},
    {'en': 'Mishari', 'ar': 'مشاري'},
    {'en': 'Abdulrahman', 'ar': 'عبدالرحمن'},
    {'en': 'Yousef', 'ar': 'يوسف'},
    {'en': 'Ali', 'ar': 'علي'}
]

NAMES_FEMALE = [
    {'en': 'Fatimah', 'ar': 'فاطمة'},
    {'en': 'Aisha', 'ar': 'عائشة'},
    {'en': 'Maryam', 'ar': 'مريم'},
    {'en': 'Noura', 'ar': 'نورة'},
    {'en': 'Sarah', 'ar': 'سارة'},
    {'en': 'Hind', 'ar': 'هند'},
    {'en': 'Latifa', 'ar': 'لطيفة'},
    {'en': 'Mona', 'ar': 'منى'},
    {'en': 'Reem', 'ar': 'ريم'},
    {'en': 'Jawaher', 'ar': 'جواهر'},
    {'en': 'Lina', 'ar': 'لينا'},
    {'en': 'Dua', 'ar': 'دعاء'},
    {'en': 'Maha', 'ar': 'مها'},
    {'en': 'Jumanah', 'ar': 'جمانة'},
    {'en': 'Rahaf', 'ar': 'رحاب'},
    {'en': 'Samar', 'ar': 'سمر'}
]

LAST_NAMES = [
    {'en': 'Al-Otaibi', 'ar': 'العتيبي'},
    {'en': 'Al-Dosari', 'ar': 'الدوسري'},
    {'en': 'Al-Qahtani', 'ar': 'القحطاني'},
    {'en': 'Al-Shammari', 'ar': 'الشمري'},
    {'en': 'Al-Harbi', 'ar': 'الحربي'},
    {'en': 'Al-Mutairi', 'ar': 'المطيري'},
    {'en': 'Al-Anazi', 'ar': 'العنزي'},
    {'en': 'Al-Zahrani', 'ar': 'الزهراني'},
    {'en': 'Al-Ghamdi', 'ar': 'الغامدي'},
    {'en': 'Al-Shehri', 'ar': 'الشهري'},
    {'en': 'Al-Salem', 'ar': 'السالم'},
    {'en': 'Al-Fahad', 'ar': 'الفالح'}
]

# Specializations for physicians
PHYSICIAN_SPECIALIZATIONS = [
    'Internal Medicine', 'General Surgery', 'Pediatrics', 'Obstetrics & Gynecology',
    'Cardiology', 'Orthopedics', 'Neurology', 'Dermatology', 'Ophthalmology',
    'ENT', 'Urology', 'Nephrology', 'Gastroenterology', 'Pulmonology',
    'Endocrinology', 'Rheumatology', 'Hematology', 'Oncology', 'Psychiatry'
]

# Job titles for nurses
NURSE_JOB_TITLES = [
    'Registered Nurse', 'Senior Nurse', 'Nurse Practitioner', 'ICU Nurse',
    'Emergency Nurse', 'Pediatric Nurse', 'Operating Room Nurse', 'Head Nurse'
]

# Job titles for admin staff
ADMIN_JOB_TITLES = [
    'Medical Receptionist', 'Administrative Assistant', 'Medical Records Clerk',
    'Hospital Administrator', 'Department Secretary', 'Patient Services Representative',
    'Front Desk Officer', 'Billing Specialist'
]


class Command(BaseCommand):
    help = 'Seed staff data with bilingual support (English and Arabic)'

    def add_arguments(self, parser):
        parser.add_argument(
            '--hospital-code',
            type=str,
            help='Target hospital code (default: all hospitals)'
        )
        parser.add_argument(
            '--count',
            type=int,
            default=10,
            help='Number of staff to create per type (default: 10)'
        )
        parser.add_argument(
            '--physicians',
            type=int,
            default=10,
            help='Number of physicians to create (default: 10)'
        )
        parser.add_argument(
            '--nurses',
            type=int,
            default=15,
            help='Number of nurses to create (default: 15)'
        )
        parser.add_argument(
            '--admin-staff',
            type=int,
            default=5,
            help='Number of admin staff to create (default: 5)'
        )
        parser.add_argument(
            '--create-users',
            action='store_true',
            help='Create user accounts for staff'
        )
        parser.add_argument(
            '--send-emails',
            action='store_true',
            help='Send credential emails to newly created users'
        )
        parser.add_argument(
            '--clear',
            action='store_true',
            help='Clear existing staff first'
        )
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Preview without making changes'
        )

    def handle(self, *args, **options):
        hospital_code = options['hospital_code']
        count = options['count']
        physicians_count = options['physicians']
        nurses_count = options['nurses']
        admin_staff_count = options['admin_staff']
        create_users = options['create_users']
        send_emails = options['send_emails']
        clear_existing = options['clear']
        dry_run = options['dry_run']

        self.stdout.write(f"\n{'='*60}")
        self.stdout.write("Staff Data Seeding Command")
        self.stdout.write(f"{'='*60}\n")

        with transaction.atomic():
            # Get hospitals
            if hospital_code:
                hospitals = Hospital.objects.filter(code=hospital_code)
                if not hospitals.exists():
                    self.stdout.write(
                        self.style.ERROR(f"Hospital with code '{hospital_code}' not found")
                    )
                    return
            else:
                hospitals = Hospital.objects.filter(status='active')

            if not hospitals.exists():
                self.stdout.write(
                    self.style.ERROR("No hospitals found. Please create hospitals first.")
                )
                return

            self.stdout.write(
                self.style.SUCCESS(f"Found {hospitals.count()} hospital(s) to seed staff")
            )

            # Display configuration
            self.stdout.write("\nConfiguration:")
            self.stdout.write(f"  Physicians per hospital: {physicians_count}")
            self.stdout.write(f"  Nurses per hospital: {nurses_count}")
            self.stdout.write(f"  Admin staff per hospital: {admin_staff_count}")
            self.stdout.write(f"  Total staff per hospital: {physicians_count + nurses_count + admin_staff_count}")
            self.stdout.write(f"  Create user accounts: {create_users}")
            self.stdout.write(f"  Send credential emails: {send_emails}")
            self.stdout.write(f"  Clear existing: {clear_existing}")
            self.stdout.write(f"  Dry run: {dry_run}")

            # Get all departments for assignment
            all_departments = Department.objects.filter(status='active')
            if not all_departments.exists():
                self.stdout.write(
                    self.style.WARNING("\nNo departments found. Staff will be created without departments.")
                )

            # Clear existing staff if requested
            if clear_existing:
                if dry_run:
                    self.stdout.write(
                        self.style.WARNING(f"\nWould delete {Staff.objects.count()} existing staff")
                    )
                else:
                    deleted_count = Staff.objects.count()
                    Staff.objects.all().delete()
                    self.stdout.write(
                        self.style.SUCCESS(f"\n✓ Deleted {deleted_count} existing staff")
                    )

            # Track created staff
            created_staff = []

            # Seed physicians
            physicians = self.create_staff_type(
                hospitals=hospitals,
                departments=all_departments,
                staff_type=Staff.StaffType.PHYSICIAN,
                count=physicians_count,
                job_titles=PHYSICIAN_SPECIALIZATIONS,
                create_users=create_users,
                send_emails=send_emails,
                dry_run=dry_run
            )
            created_staff.extend(physicians)

            # Seed nurses
            nurses = self.create_staff_type(
                hospitals=hospitals,
                departments=all_departments,
                staff_type=Staff.StaffType.NURSE,
                count=nurses_count,
                job_titles=NURSE_JOB_TITLES,
                create_users=create_users,
                send_emails=send_emails,
                dry_run=dry_run
            )
            created_staff.extend(nurses)

            # Seed admin staff
            admins = self.create_staff_type(
                hospitals=hospitals,
                departments=all_departments,
                staff_type=Staff.StaffType.ADMIN,
                count=admin_staff_count,
                job_titles=ADMIN_JOB_TITLES,
                create_users=create_users,
                send_emails=send_emails,
                dry_run=dry_run
            )
            created_staff.extend(admins)

            # Summary
            self.stdout.write("\n" + "="*60)
            self.stdout.write("Summary:")
            self.stdout.write(f"  Physicians created: {len(physicians)}")
            self.stdout.write(f"  Nurses created: {len(nurses)}")
            self.stdout.write(f"  Admin staff created: {len(admins)}")
            self.stdout.write(f"  Total staff created: {len(created_staff)}")
            self.stdout.write("="*60 + "\n")

            if dry_run:
                self.stdout.write(self.style.WARNING("DRY RUN: No changes were made\n"))
            else:
                self.stdout.write(self.style.SUCCESS("Staff seeding completed successfully!\n"))

    def create_staff_type(self, hospitals, departments, staff_type, count, job_titles,
                        create_users, send_emails, dry_run):
        """Create staff of a specific type"""
        created = []
        staff_type_display = dict(Staff.StaffType.choices).get(staff_type, staff_type)

        self.stdout.write(f"\nSeeding {staff_type_display}...")

        for hospital in hospitals:
            # Get departments for this hospital
            hospital_depts = [d for d in departments if d.hospital == hospital]

            for i in range(count):
                # Generate names (paired to ensure English and Arabic correspond)
                if staff_type == Staff.StaffType.NURSE:
                    # More female nurses (70%)
                    if random.random() < 0.7:
                        first_name = random.choice(NAMES_FEMALE)
                    else:
                        first_name = random.choice(NAMES_MALE)
                else:
                    # Physicians and admin staff are mostly male (60%)
                    if random.random() < 0.6:
                        first_name = random.choice(NAMES_MALE)
                    else:
                        first_name = random.choice(NAMES_FEMALE)

                last_name = random.choice(LAST_NAMES)

                job_title = random.choice(job_titles)

                # Generate employee ID
                employee_id = self.generate_employee_id(hospital.code, staff_type)

                # Generate random email
                email = self.generate_staff_email(first_name['en'], last_name['en'], hospital.code)

                # Generate license number for physicians
                license_number = None
                if staff_type == Staff.StaffType.PHYSICIAN:
                    license_number = self.generate_license_number()

                # Select department (optional)
                department = random.choice(hospital_depts) if hospital_depts and random.random() > 0.1 else None

                # Specialization for all staff types (required field)
                if staff_type == Staff.StaffType.PHYSICIAN:
                    specialization = job_title
                elif staff_type == Staff.StaffType.NURSE:
                    specialization = random.choice(['General Nursing', 'Patient Care', 'Clinical Nursing', 'Nursing'])
                elif staff_type == Staff.StaffType.ADMIN:
                    specialization = random.choice(['Administration', 'Hospital Operations', 'Medical Administration', 'Healthcare Admin'])
                else:
                    specialization = 'General Staff'

                if dry_run:
                    self.stdout.write(
                        f"  Would create: {first_name['en']} {last_name['en']} ({first_name['ar']} {last_name['ar']}) - {job_title}"
                    )
                    created.append({'type': staff_type_display, 'name': f"{first_name['en']} {last_name['en']}"})
                else:
                    # Create staff
                    staff = Staff.objects.create(
                        first_name=first_name['en'],
                        last_name=last_name['en'],
                        first_name_ar=first_name['ar'],
                        last_name_ar=last_name['ar'],
                        email=email,
                        staff_type=staff_type,
                        job_title=job_title,
                        license_number=license_number,
                        specialization=specialization,
                        employee_id=employee_id,
                        hospital=hospital,
                        department=department,
                        status='active'
                    )

                    # Create user account if requested
                    if create_users:
                        self.create_user_for_staff(staff, send_emails)

                    created.append(staff)

        self.stdout.write(
            self.style.SUCCESS(f"  ✓ Created {len([s for s in created if isinstance(s, Staff)])} {staff_type_display}")
        )
        return created

    def generate_employee_id(self, hospital_code, staff_type):
        """Generate unique employee ID"""
        prefix = {
            Staff.StaffType.PHYSICIAN: 'DR',
            Staff.StaffType.NURSE: 'RN',
            Staff.StaffType.ADMIN: 'ADM',
            Staff.StaffType.OTHER: 'STF'
        }.get(staff_type, 'STF')

        random_num = random.randint(10000, 99999)
        return f"{prefix}-{hospital_code}-{random_num}"

    def generate_license_number(self):
        """Generate unique license number"""
        random_num = random.randint(1000000, 9999999)
        return f"MOH-LIC-{random_num}"

    def generate_staff_email(self, first_name, last_name, hospital_code):
        """Generate unique random email for staff"""
        # Clean up names for email (remove spaces and special characters)
        clean_first = ''.join(c.lower() for c in first_name if c.isalnum() or c == ' ')
        clean_last = ''.join(c.lower() for c in last_name if c.isalnum() or c == ' ')
        
        base = f"{clean_first.replace(' ', '.')}.{clean_last.replace(' ', '.')}"
        email = f"{base}@{hospital_code.lower()}.sa"
        
        # Add random suffix if email already exists
        counter = 1
        while Staff.objects.filter(email=email).exists():
            random_num = random.randint(1, 999)
            email = f"{base}{random_num}@{hospital_code.lower()}.sa"
            counter += 1
            if counter > 100:  # Safety limit
                break
        
        return email

    def create_user_for_staff(self, staff, send_email=False):
        """Create a user account for staff using StaffService"""
        try:
            # Use email that was already set on staff during creation
            email = staff.email
            
            # Get role for this staff type
            role = StaffService.get_staff_type_role(staff.staff_type)
            
            # Create mock request object for StaffService
            class MockRequest:
                def build_absolute_uri(self, location=''):
                    from django.conf import settings
                    return f"{settings.SITE_URL if hasattr(settings, 'SITE_URL') else 'http://localhost:8000'}{location}"
            
            request = MockRequest()
            
            # Create user account using StaffService
            user, was_created, password = StaffService.create_user_for_staff(staff, role, request)
            
            if was_created:
                self.stdout.write(
                    self.style.SUCCESS(f"    ✓ Created user: {user.email} (role: {role})")
                )
                
                # Send password reset email if requested
                if send_email:
                    try:
                        StaffService.send_password_reset_email(staff, request)
                        self.stdout.write(
                            self.style.SUCCESS(f"    ✓ Sent password reset email to: {email}")
                        )
                    except Exception as email_error:
                        self.stdout.write(
                            self.style.WARNING(f"    ⚠ Failed to send email: {str(email_error)}")
                        )
            else:
                self.stdout.write(
                    self.style.SUCCESS(f"    ✓ Linked existing user: {user.email} (role: {role})")
                )
            
        except Exception as e:
            self.stdout.write(
                self.style.ERROR(f"    ✗ Failed to create user for {staff.first_name} {staff.last_name}: {str(e)}")
            )

    def generate_username(self, staff):
        """Generate unique username"""
        base = f"{staff.first_name.lower()}.{staff.last_name.lower()}"
        username = base

        # Add suffix if username exists
        counter = 1
        while User.objects.filter(username=username).exists():
            username = f"{base}{counter}"
            counter += 1

        return username
