import logging
import random
from datetime import datetime, timedelta
from django.db import transaction
from django_q.models import Schedule
from django_q.tasks import schedule
from django.dispatch import receiver
from django_q.tasks import async_task
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.utils import timezone
from .models import (
    FormField,
    FormStage,
    FormTemplate,
    Application,
    JobPosting,
    Notification,
    HiringAgency,
    Person,
    Source,
)
from .forms import generate_api_key, generate_api_secret
from django.contrib.auth import get_user_model
from django_q.models import Schedule


logger = logging.getLogger(__name__)

User = get_user_model()


@receiver(post_save, sender=JobPosting)
def format_job(sender, instance, created, **kwargs):
    if created or not instance.ai_parsed:
        form = getattr(instance, "form_template", None)
        if not form:
            FormTemplate.objects.get_or_create(
                job=instance, is_active=True, name=instance.title
            )
        async_task(
            "recruitment.tasks.format_job_description",
            instance.pk,
            # hook='myapp.tasks.email_sent_callback'  # Optional callback
        )

    else:
        existing_schedule = Schedule.objects.filter(
            func="recruitment.tasks.form_close",
            args=f"[{instance.pk}]",
            schedule_type=Schedule.ONCE,
        ).first()

        if instance.STATUS_CHOICES == "ACTIVE" and instance.application_deadline:
            if not existing_schedule:
                # Create a new schedule if one does not exist
                schedule(
                    "recruitment.tasks.form_close",
                    instance.pk,
                    schedule_type=Schedule.ONCE,
                    next_run=instance.application_deadline,
                    repeats=-1,  # Ensure the schedule is deleted after it runs
                    name=f"job_closing_{instance.pk}",  # Add a name for easier lookup
                )
            elif existing_schedule.next_run != instance.application_deadline:
                # Update an existing schedule's run time
                existing_schedule.next_run = instance.application_deadline
                existing_schedule.save()
        elif existing_schedule:
            # If the instance is no longer active, delete the scheduled task
            existing_schedule.delete()


# @receiver(post_save, sender=JobPosting)
# def update_form_template_status(sender, instance, created, **kwargs):
#     if not created:
#         if instance.status == "Active":
#             instance.form_template.is_active = True
#         else:
#             instance.form_template.is_active = False
#         instance.save()


@receiver(post_save, sender=Application)
def score_candidate_resume(sender, instance, created, **kwargs):
    if instance.resume and not instance.is_resume_parsed:
        logger.info(f"Scoring resume for candidate {instance.pk}")
        async_task(
            "recruitment.tasks.handle_reume_parsing_and_scoring",
            instance.pk,
            hook="recruitment.hooks.callback_ai_parsing",
        )


@receiver(post_save, sender=FormTemplate)
def create_default_stages(sender, instance, created, **kwargs):
    """
    Create default resume stages when a new FormTemplate is created
    """
    if created:
        with transaction.atomic():
            # Stage 1: Contact Information
            contact_stage = FormStage.objects.create(
                template=instance,
                name="Contact Information",
                order=0,
                is_predefined=True,
            )
            # FormField.objects.create(
            #     stage=contact_stage,
            #     label="First Name",
            #     field_type="text",
            #     required=True,
            #     order=0,
            #     is_predefined=True,
            # )
            # FormField.objects.create(
            #     stage=contact_stage,
            #     label="Last Name",
            #     field_type="text",
            #     required=True,
            #     order=1,
            #     is_predefined=True,
            # )
            # FormField.objects.create(
            #     stage=contact_stage,
            #     label="Email Address",
            #     field_type="email",
            #     required=True,
            #     order=2,
            #     is_predefined=True,
            # )
            # FormField.objects.create(
            #     stage=contact_stage,
            #     label="Phone Number",
            #     field_type="phone",
            #     required=True,
            #     order=3,
            #     is_predefined=True,
            # )
            # FormField.objects.create(
            #     stage=contact_stage,
            #     label="Address",
            #     field_type="text",
            #     required=False,
            #     order=4,
            #     is_predefined=True,
            # )
            # FormField.objects.create(
            #     stage=contact_stage,
            #     label="National ID / Iqama Number",
            #     field_type="text",
            #     required=False,
            #     order=5,
            #     is_predefined=True,
            # )
            FormField.objects.create(
                stage=contact_stage,
                label="GPA",
                field_type="text",
                required=False,
                order=1,
                is_predefined=True,
            )
            FormField.objects.create(
                stage=contact_stage,
                label="Resume Upload",
                field_type="file",
                required=True,
                order=2,
                is_predefined=True,
                file_types=".pdf,.doc,.docx",
                max_file_size=1,
            )

            # # Stage 2: Resume Objective
            # objective_stage = FormStage.objects.create(
            #     template=instance,
            #     name='Resume Objective',
            #     order=1,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=objective_stage,
            #     label='Career Objective',
            #     field_type='textarea',
            #     required=False,
            #     order=0,
            #     is_predefined=True
            # )

            # # Stage 3: Education
            # education_stage = FormStage.objects.create(
            #     template=instance,
            #     name='Education',
            #     order=2,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=education_stage,
            #     label='Degree',
            #     field_type='text',
            #     required=True,
            #     order=0,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=education_stage,
            #     label='Institution',
            #     field_type='text',
            #     required=True,
            #     order=1,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=education_stage,
            #     label='Location',
            #     field_type='text',
            #     required=False,
            #     order=2,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=education_stage,
            #     label='Graduation Date',
            #     field_type='date',
            #     required=False,
            #     order=3,
            #     is_predefined=True
            # )

            # # Stage 4: Experience
            # experience_stage = FormStage.objects.create(
            #     template=instance,
            #     name='Experience',
            #     order=3,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=experience_stage,
            #     label='Position Title',
            #     field_type='text',
            #     required=True,
            #     order=0,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=experience_stage,
            #     label='Company Name',
            #     field_type='text',
            #     required=True,
            #     order=1,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=experience_stage,
            #     label='Location',
            #     field_type='text',
            #     required=False,
            #     order=2,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=experience_stage,
            #     label='Start Date',
            #     field_type='date',
            #     required=True,
            #     order=3,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=experience_stage,
            #     label='End Date',
            #     field_type='date',
            #     required=True,
            #     order=4,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=experience_stage,
            #     label='Responsibilities & Achievements',
            #     field_type='textarea',
            #     required=False,
            #     order=5,
            #     is_predefined=True
            # )

            # # Stage 5: Skills
            # skills_stage = FormStage.objects.create(
            #     template=instance,
            #     name='Skills',
            #     order=4,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=skills_stage,
            #     label='Technical Skills',
            #     field_type='checkbox',
            #     required=False,
            #     order=0,
            #     is_predefined=True,
            #     options=['Programming Languages', 'Frameworks', 'Tools & Technologies']
            # )

            # # Stage 6: Summary
            # summary_stage = FormStage.objects.create(
            #     template=instance,
            #     name='Summary',
            #     order=5,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=summary_stage,
            #     label='Professional Summary',
            #     field_type='textarea',
            #     required=False,
            #     order=0,
            #     is_predefined=True
            # )

            # # Stage 7: Certifications
            # certifications_stage = FormStage.objects.create(
            #     template=instance,
            #     name='Certifications',
            #     order=6,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=certifications_stage,
            #     label='Certification Name',
            #     field_type='text',
            #     required=False,
            #     order=0,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=certifications_stage,
            #     label='Issuing Organization',
            #     field_type='text',
            #     required=False,
            #     order=1,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=certifications_stage,
            #     label='Issue Date',
            #     field_type='date',
            #     required=False,
            #     order=2,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=certifications_stage,
            #     label='Expiration Date',
            #     field_type='date',
            #     required=False,
            #     order=3,
            #     is_predefined=True
            # )

            # # Stage 8: Awards and Recognitions
            # awards_stage = FormStage.objects.create(
            #     template=instance,
            #     name='Awards and Recognitions',
            #     order=7,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=awards_stage,
            #     label='Award Name',
            #     field_type='text',
            #     required=False,
            #     order=0,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=awards_stage,
            #     label='Issuing Organization',
            #     field_type='text',
            #     required=False,
            #     order=1,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=awards_stage,
            #     label='Date Received',
            #     field_type='date',
            #     required=False,
            #     order=2,
            #     is_predefined=True
            # )
            # FormField.objects.create(
            #     stage=awards_stage,
            #     label='Description',
            #     field_type='textarea',
            #     required=False,
            #     order=3,
            #     is_predefined=True
            # )


# AgencyMessage signal handler removed - model has been deleted

# SSE notification cache for real-time updates
SSE_NOTIFICATION_CACHE = {}


@receiver(post_save, sender=Notification)
def notification_created(sender, instance, created, **kwargs):
    """Signal handler for when a notification is created"""
    if created:
        logger.info(
            f"New notification created: {instance.id} for user {instance.recipient.username}"
        )

        # Store notification in cache for SSE
        user_id = instance.recipient.id
        if user_id not in SSE_NOTIFICATION_CACHE:
            SSE_NOTIFICATION_CACHE[user_id] = []

        notification_data = {
            "id": instance.id,
            "message": instance.message[:100]
            + ("..." if len(instance.message) > 100 else ""),
            "type": instance.get_notification_type_display(),
            "status": instance.get_status_display(),
            "time_ago": "Just now",
            "url": f"/notifications/{instance.id}/",
        }

        SSE_NOTIFICATION_CACHE[user_id].append(notification_data)

        # Keep only last 50 notifications per user in cache
        if len(SSE_NOTIFICATION_CACHE[user_id]) > 50:
            SSE_NOTIFICATION_CACHE[user_id] = SSE_NOTIFICATION_CACHE[user_id][-50:]

        logger.info(f"Notification cached for SSE: {notification_data}")


def generate_random_password():
    import string

    return "".join(random.choices(string.ascii_letters + string.digits, k=12))


@receiver(post_save, sender=HiringAgency)
def hiring_agency_created(sender, instance, created, **kwargs):
    if created:
        logger.info(f"New hiring agency created: {instance.pk} - {instance.name}")
        password = generate_random_password()
        user = User.objects.create_user(
            username=instance.name, email=instance.email, user_type="agency"
        )
        user.set_password(password)
        user.save()
        instance.user = user
        instance.generated_password = password
        instance.save()
        logger.info(f"Generated password stored for agency: {instance.pk}")


@receiver(post_save, sender=Person)
def person_created(sender, instance, created, **kwargs):
    if created and not instance.user:
        logger.info(f"New Person created: {instance.pk} - {instance.email}")
        user = User.objects.create_user(
            username=instance.email,
            first_name=instance.first_name,
            last_name=instance.last_name,
            email=instance.email,
            phone=instance.phone,
            user_type="candidate",
        )
        instance.user = user
        instance.save()


@receiver(post_save, sender=Source)
def source_created(sender, instance, created, **kwargs):
    """
    Automatically generate API key and API secret when a new Source is created.
    """
    if created:
        # Only generate keys if they don't already exist
        if not instance.api_key and not instance.api_secret:
            logger.info(f"Generating API keys for new Source: {instance.pk} - {instance.name}")

            # Generate API key and secret using existing secure functions
            api_key = generate_api_key()
            api_secret = generate_api_secret()

            # Update the source with generated keys
            instance.api_key = api_key
            instance.api_secret = api_secret
            instance.save(update_fields=['api_key', 'api_secret'])

            logger.info(f"API keys generated successfully for Source: {instance.name} (Key: {api_key[:8]}...)")
        else:
            logger.info(f"Source {instance.name} already has API keys, skipping generation")
