"""
Management command to populate existing staff with random emails and phone numbers
"""
import random
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from django.db.models import Q

from apps.organizations.models import Staff


class Command(BaseCommand):
    help = 'Populate existing staff records with random emails and phone numbers'

    def add_arguments(self, parser):
        parser.add_argument(
            '--hospital-code',
            type=str,
            help='Target hospital code (default: all hospitals)'
        )
        parser.add_argument(
            '--email-only',
            action='store_true',
            help='Only populate email addresses'
        )
        parser.add_argument(
            '--phone-only',
            action='store_true',
            help='Only populate phone numbers'
        )
        parser.add_argument(
            '--overwrite',
            action='store_true',
            help='Overwrite existing email/phone (default: fill missing only)'
        )
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Preview changes without updating database'
        )

    def handle(self, *args, **options):
        hospital_code = options['hospital_code']
        email_only = options['email_only']
        phone_only = options['phone_only']
        overwrite = options['overwrite']
        dry_run = options['dry_run']

        self.stdout.write(f"\n{'='*60}")
        self.stdout.write("Staff Contact Information Populator")
        self.stdout.write(f"{'='*60}\n")

        # Base queryset
        queryset = Staff.objects.all()

        # Filter by hospital if specified
        if hospital_code:
            queryset = queryset.filter(hospital__code__iexact=hospital_code)
            self.stdout.write(f"Target hospital: {hospital_code}")
        else:
            self.stdout.write("Target: All hospitals")

        # Filter staff needing updates
        if not overwrite:
            if email_only:
                queryset = queryset.filter(Q(email__isnull=True) | Q(email=''))
            elif phone_only:
                queryset = queryset.filter(Q(phone__isnull=True) | Q(phone=''))
            else:
                # Both email and phone
                queryset = queryset.filter(
                    Q(email__isnull=True) | Q(email='') | 
                    Q(phone__isnull=True) | Q(phone='')
                )

        total_staff = queryset.count()

        if total_staff == 0:
            self.stdout.write(
                self.style.SUCCESS("✓ All staff already have contact information.")
            )
            return

        self.stdout.write(f"\nFound {total_staff} staff to update")
        self.stdout.write(f"  Email only: {email_only}")
        self.stdout.write(f"  Phone only: {phone_only}")
        self.stdout.write(f"  Overwrite existing: {overwrite}")
        self.stdout.write(f"  Dry run: {dry_run}\n")

        # Track statistics
        updated_emails = 0
        updated_phones = 0
        skipped = 0

        with transaction.atomic():
            for staff in queryset:
                update_email = False
                update_phone = False
                
                # Determine which fields to update
                should_update_email = email_only or (not email_only and not phone_only)
                should_update_phone = phone_only or (not email_only and not phone_only)
                
                # Determine if we should update email
                if should_update_email:
                    if overwrite or not staff.email or not staff.email.strip():
                        if not staff.first_name or not staff.last_name:
                            self.stdout.write(
                                self.style.WARNING(f"  ⚠ Skipping staff {staff.id}: Missing first/last name")
                            )
                            skipped += 1
                            continue
                        update_email = True
                
                # Determine if we should update phone
                if should_update_phone:
                    if overwrite or not staff.phone or not staff.phone.strip():
                        update_phone = True

                if not update_email and not update_phone:
                    skipped += 1
                    continue

                # Generate new values
                new_email = None
                new_phone = None
                
                if update_email:
                    new_email = self.generate_email(staff)
                    updated_emails += 1
                
                if update_phone:
                    new_phone = self.generate_phone_number()
                    updated_phones += 1

                # Display what will be updated
                if dry_run:
                    updates = []
                    if new_email:
                        old_email = staff.email if staff.email else 'None'
                        updates.append(f"email: {old_email} → {new_email}")
                    if new_phone:
                        old_phone = staff.phone if staff.phone else 'None'
                        updates.append(f"phone: {old_phone} → {new_phone}")
                    
                    name = staff.name if staff.name else f"{staff.first_name} {staff.last_name}"
                    self.stdout.write(f"  Would update: {name}")
                    for update in updates:
                        self.stdout.write(f"    - {update}")
                else:
                    # Apply updates
                    if new_email:
                        staff.email = new_email
                    if new_phone:
                        staff.phone = new_phone
                    
                    staff.save()

                    name = staff.name if staff.name else f"{staff.first_name} {staff.last_name}"
                    self.stdout.write(f"  ✓ Updated: {name}")
                    if new_email:
                        self.stdout.write(f"    Email: {new_email}")
                    if new_phone:
                        self.stdout.write(f"    Phone: {new_phone}")

        # Summary
        self.stdout.write("\n" + "="*60)
        self.stdout.write("Summary:")
        self.stdout.write(f"  Total staff processed: {total_staff}")
        self.stdout.write(f"  Emails populated: {updated_emails}")
        self.stdout.write(f"  Phone numbers populated: {updated_phones}")
        self.stdout.write(f"  Skipped: {skipped}")
        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("Contact information populated successfully!\n"))

    def generate_email(self, staff):
        """Generate unique email for staff"""
        # Use staff.name if available, otherwise use first_name + last_name
        if staff.name and staff.name.strip():
            # Try to split name into first and last
            name_parts = staff.name.strip().split()
            if len(name_parts) >= 2:
                first_name = name_parts[0]
                last_name = name_parts[-1]
            else:
                first_name = staff.name.strip()
                last_name = staff.last_name if staff.last_name else ''
        else:
            first_name = staff.first_name if staff.first_name else 'user'
            last_name = staff.last_name if staff.last_name else 'unknown'

        # 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 == ' ')
        
        # Get hospital code for domain
        hospital_code = staff.hospital.code if staff.hospital else 'hospital'
        hospital_code = hospital_code.lower().replace(' ', '')
        
        base = f"{clean_first.replace(' ', '.')}.{clean_last.replace(' ', '.')}"
        email = f"{base}@{hospital_code}.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}.sa"
            counter += 1
            if counter > 100:  # Safety limit
                break
        
        return email

    def generate_phone_number(self):
        """Generate random Saudi phone number (+966 5X XXX XXXX)"""
        # Saudi mobile format: +966 5X XXX XXXX
        # X is random digit
        
        second_digit = random.randint(0, 9)
        group1 = random.randint(100, 999)
        group2 = random.randint(100, 999)
        
        phone = f"+966 5{second_digit} {group1} {group2}"
        return phone
