from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth import get_user_model
from .models import UserProfile
from bazi.models import Person
from iching.utils.utils import NameFormatter

User = get_user_model()

@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
    """Create or update a UserProfile instance when a User is created or updated."""
    if created:
        UserProfile.objects.create(user=instance)
    else:
        # Get or create the profile in case it doesn't exist
        UserProfile.objects.get_or_create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    """Save the UserProfile instance when the User is saved."""
    if hasattr(instance, 'profile'):
        instance.profile.save()

@receiver(post_save, sender=UserProfile)
def create_or_update_bazi_person(sender, instance, created, **kwargs):
    """Create or update a BaziPerson record when a UserProfile is created or updated."""
    # Skip auto-creation for temporary users - they should create records via API
    if hasattr(instance.user, 'is_temporary_user') and instance.user.is_temporary_user:
        return
    
    # Skip if this is triggered during a background relation calculation
    # to prevent overwriting recent API updates with stale UserProfile data
    import threading
    current_thread = threading.current_thread()
    if hasattr(current_thread, '_bazi_recalc_thread'):
        return
        
    if instance.birth_date:  # Only proceed if birth date is provided
        from bazi.models import Person
        
        # Format the name using the NameFormatter utility
        full_name = NameFormatter.format_name(instance.user.first_name, instance.user.last_name)

        # Try to get existing BaziPerson for this user
        bazi_person = Person.objects.filter(created_by=instance.user, owner=True).first()
        
        if bazi_person:
            # Update existing record
            # Only update name if we have actual first/last name data, otherwise preserve existing name
            if full_name.strip():  # Only update if we have a non-empty formatted name
                bazi_person.name = full_name
            # Only update gender if user has a non-default gender, otherwise preserve existing
            if instance.user.gender and instance.user.gender != 'N':
                bazi_person.gender = instance.user.gender
            
            # Update BaZi person record with UserProfile data
            bazi_person.birth_date = instance.birth_date
            bazi_person.birth_time = instance.birth_time
            bazi_person.twin_type = instance.twin_type
            bazi_person.father_dob = instance.father_dob
            bazi_person.mother_dob = instance.mother_dob
            bazi_person.created_by_temp_user = hasattr(instance.user, 'is_temporary_user') and instance.user.is_temporary_user
            # Calculate BaZi automatically for owner record
            bazi_person.calculate_bazi()
            bazi_person.save()
        else:
            # Create new record
            bazi_person = Person.objects.create(
                name=full_name,
                gender=instance.user.gender,
                birth_date=instance.birth_date,
                birth_time=instance.birth_time,
                twin_type=instance.twin_type,
                father_dob=instance.father_dob,
                mother_dob=instance.mother_dob,
                created_by=instance.user,
                created_by_temp_user=hasattr(instance.user, 'is_temporary_user') and instance.user.is_temporary_user,
                owner=True
            )
            # Calculate BaZi automatically for newly created owner record
            bazi_person.calculate_bazi()
            bazi_person.save() 