"""
Core App Signals

Handles automatic setup tasks when tenants are created.
"""
import logging
from django.db import transaction
from django.db.models.signals import post_save
from django.dispatch import receiver

logger = logging.getLogger(__name__)


def _create_site_for_tenant(tenant_id):
    """
    Create a Site and default home page for a tenant.
    Called after transaction commits to ensure tenant is fully saved.
    """
    from smoothschedule.identity.core.models import Tenant
    from smoothschedule.platform.tenant_sites.models import Site

    try:
        tenant = Tenant.objects.get(id=tenant_id)
        # Check if site already exists
        if not Site.objects.filter(tenant=tenant).exists():
            site = Site.objects.create(tenant=tenant, is_enabled=True)
            logger.info(f"Created Site for tenant: {tenant.schema_name}")
            # Default page is auto-created by Site's post_save signal
    except Tenant.DoesNotExist:
        logger.error(f"Tenant {tenant_id} not found when creating Site")
    except Exception as e:
        logger.error(f"Failed to create Site for tenant {tenant_id}: {e}")


def _seed_plugins_for_tenant(tenant_schema_name):
    """
    Internal function to seed platform plugins for a tenant.
    Called after transaction commits to ensure schema tables exist.
    """
    from django_tenants.utils import schema_context
    from smoothschedule.scheduling.schedule.models import PluginTemplate
    from django.utils import timezone

    logger.info(f"Seeding platform plugins for new tenant: {tenant_schema_name}")

    try:
        with schema_context(tenant_schema_name):
            # Import the plugin definitions from the seed command
            from smoothschedule.scheduling.schedule.management.commands.seed_platform_plugins import get_platform_plugins

            plugins_data = get_platform_plugins()
            created_count = 0

            for plugin_data in plugins_data:
                # Check if plugin already exists by slug
                if PluginTemplate.objects.filter(slug=plugin_data['slug']).exists():
                    continue

                # Create the plugin
                PluginTemplate.objects.create(
                    name=plugin_data['name'],
                    slug=plugin_data['slug'],
                    category=plugin_data['category'],
                    short_description=plugin_data['short_description'],
                    description=plugin_data['description'],
                    plugin_code=plugin_data['plugin_code'],
                    logo_url=plugin_data.get('logo_url', ''),
                    visibility=PluginTemplate.Visibility.PLATFORM,
                    is_approved=True,
                    approved_at=timezone.now(),
                    author_name='Smooth Schedule',
                    license_type='PLATFORM',
                )
                created_count += 1

            logger.info(f"Created {created_count} platform plugins for tenant: {tenant_schema_name}")
    except Exception as e:
        logger.error(f"Failed to seed plugins for tenant {tenant_schema_name}: {e}")


@receiver(post_save, sender='core.Tenant')
def seed_platform_plugins_on_tenant_create(sender, instance, created, **kwargs):
    """
    Seed platform plugins when a new tenant is created.

    This ensures new tenants have access to all marketplace plugins immediately.
    Uses transaction.on_commit() to defer seeding until after the schema is
    fully created and migrations have run.
    """
    if not created:
        return

    # Skip public schema
    if instance.schema_name == 'public':
        return

    # Defer the seeding until after the transaction commits
    # This ensures the schema and all tables exist before we try to use them
    schema_name = instance.schema_name
    transaction.on_commit(lambda: _seed_plugins_for_tenant(schema_name))


@receiver(post_save, sender='core.Tenant')
def create_site_on_tenant_create(sender, instance, created, **kwargs):
    """
    Create a Site with default home page when a new tenant is created.

    This ensures every tenant has a booking site ready to use immediately.
    Uses transaction.on_commit() to defer creation until after the tenant
    is fully saved.
    """
    if not created:
        return

    # Skip public schema
    if instance.schema_name == 'public':
        return

    tenant_id = instance.id
    transaction.on_commit(lambda: _create_site_for_tenant(tenant_id))


def _seed_email_templates_for_tenant(tenant_schema_name):
    """
    Create default email templates for a tenant.
    Called after transaction commits to ensure schema tables exist.
    """
    from django_tenants.utils import schema_context
    from smoothschedule.communication.messaging.models import PuckEmailTemplate
    from smoothschedule.communication.messaging.email_types import EmailType
    from smoothschedule.communication.messaging.default_templates import DEFAULT_TEMPLATES

    logger.info(f"Seeding email templates for new tenant: {tenant_schema_name}")

    try:
        with schema_context(tenant_schema_name):
            created_count = 0

            for email_type in EmailType:
                # Check if template already exists
                if PuckEmailTemplate.objects.filter(email_type=email_type.value).exists():
                    continue

                # Get default template data
                default_data = DEFAULT_TEMPLATES.get(email_type.value, {})
                if not default_data:
                    logger.warning(f"No default template found for {email_type.value}")
                    continue

                # Create the template
                PuckEmailTemplate.objects.create(
                    email_type=email_type.value,
                    subject_template=default_data.get('subject_template', ''),
                    puck_data=default_data.get('puck_data', {'content': [], 'root': {}}),
                    is_active=True,
                    is_customized=False,
                )
                created_count += 1

            logger.info(f"Created {created_count} email templates for tenant: {tenant_schema_name}")
    except Exception as e:
        logger.error(f"Failed to seed email templates for tenant {tenant_schema_name}: {e}")


@receiver(post_save, sender='core.Tenant')
def seed_email_templates_on_tenant_create(sender, instance, created, **kwargs):
    """
    Seed default email templates when a new tenant is created.

    This ensures new tenants have all system email templates ready to use.
    Uses transaction.on_commit() to defer seeding until after the schema is
    fully created and migrations have run.
    """
    if not created:
        return

    # Skip public schema
    if instance.schema_name == 'public':
        return

    schema_name = instance.schema_name
    transaction.on_commit(lambda: _seed_email_templates_for_tenant(schema_name))
