from django.db.models.signals import post_save
from django.dispatch import receiver

from jobs.models import JobApplication
from seekers.models import SeekerProfile

from .models import ApplicationEvent
from .services import log_event, process_application_scoring, reprocess_applications_for_user

_SCORING_ONLY_FIELDS = frozenset({
    'match_score', 'cv_parsed_text', 'cv_extracted_skills', 'cv_parsed_at', 'updated_at',
})
_SKIP_RESCORE_FIELDS = _SCORING_ONLY_FIELDS | {'status', 'rating'}
_PROFILE_CONTENT_FIELDS = frozenset({
    'skills', 'bio', 'education', 'experience_summary', 'qualification', 'headline', 'cv_file',
})


@receiver(post_save, sender=JobApplication)
def on_application_saved(sender, instance, created, **kwargs):
    update_fields = kwargs.get('update_fields')
    if update_fields and set(update_fields).issubset(_SKIP_RESCORE_FIELDS):
        if created:
            log_event(
                instance,
                instance.applicant,
                ApplicationEvent.EventType.CREATED,
                message='Application submitted',
            )
        return

    process_application_scoring(instance, parse_content=True)

    if created:
        message = 'Application submitted'
        if instance.cv_parsed_text:
            skill_count = len(instance.cv_skill_list)
            message = f'Application submitted - profile/CV analyzed ({skill_count} skill(s) detected)'
        log_event(
            instance,
            instance.applicant,
            ApplicationEvent.EventType.CREATED,
            message=message,
        )


@receiver(post_save, sender=SeekerProfile)
def on_seeker_profile_updated(sender, instance, **kwargs):
    if not instance.user_id:
        return

    update_fields = kwargs.get('update_fields')
    if update_fields and not set(update_fields) & _PROFILE_CONTENT_FIELDS:
        return

    reprocess_applications_for_user(instance.user)
