"""
Scheduler module for handling background tasks
"""
import logging
from apscheduler.schedulers.background import BackgroundScheduler
import config
from utils.backup import create_backup
from db import get_connection


def scheduled_backup():
    """Führt ein geplantes Backup aus"""
    logging.info("Starte geplantes Backup...")
    create_backup(backup_type="scheduled", created_by="scheduler")


def cleanup_expired_sessions():
    """Clean up expired license sessions"""
    try:
        conn = get_connection()
        cur = conn.cursor()
        
        # Get client config for timeout value
        cur.execute("""
            SELECT session_timeout 
            FROM client_configs 
            WHERE client_name = 'Account Forger'
        """)
        result = cur.fetchone()
        timeout_seconds = result[0] if result else 60
        
        # Find expired sessions
        cur.execute("""
            SELECT id, license_id, hardware_id, ip_address, client_version, started_at
            FROM license_sessions
            WHERE last_heartbeat < CURRENT_TIMESTAMP - INTERVAL '%s seconds'
        """, (timeout_seconds,))
        
        expired_sessions = cur.fetchall()
        
        if expired_sessions:
            logging.info(f"Found {len(expired_sessions)} expired sessions to clean up")
            
            for session in expired_sessions:
                # Log to history
                cur.execute("""
                    INSERT INTO session_history 
                    (license_id, hardware_id, ip_address, client_version, started_at, ended_at, end_reason)
                    VALUES (%s, %s, %s, %s, %s, CURRENT_TIMESTAMP, 'timeout')
                """, (session[1], session[2], session[3], session[4], session[5]))
                
                # Delete session
                cur.execute("DELETE FROM license_sessions WHERE id = %s", (session[0],))
            
            conn.commit()
            logging.info(f"Cleaned up {len(expired_sessions)} expired sessions")
        
        cur.close()
        conn.close()
        
    except Exception as e:
        logging.error(f"Error cleaning up sessions: {str(e)}")
        if 'conn' in locals():
            conn.rollback()


def deactivate_expired_licenses():
    """Deactivate licenses that have expired"""
    try:
        conn = get_connection()
        cur = conn.cursor()
        
        # Find active licenses that have expired
        # Check valid_until < today (at midnight)
        cur.execute("""
            SELECT id, license_key, customer_id, valid_until
            FROM licenses
            WHERE is_active = true 
            AND valid_until IS NOT NULL 
            AND valid_until < CURRENT_DATE
            AND is_fake = false
        """)
        
        expired_licenses = cur.fetchall()
        
        if expired_licenses:
            logging.info(f"Found {len(expired_licenses)} expired licenses to deactivate")
            
            for license in expired_licenses:
                license_id, license_key, customer_id, valid_until = license
                
                # Deactivate the license
                cur.execute("""
                    UPDATE licenses 
                    SET is_active = false,
                        updated_at = CURRENT_TIMESTAMP
                    WHERE id = %s
                """, (license_id,))
                
                # Log to audit trail
                cur.execute("""
                    INSERT INTO audit_log 
                    (timestamp, username, action, entity_type, entity_id, 
                     old_values, new_values, additional_info)
                    VALUES (CURRENT_TIMESTAMP, 'system', 'DEACTIVATE', 'license', %s,
                            jsonb_build_object('is_active', true),
                            jsonb_build_object('is_active', false),
                            %s)
                """, (license_id, f"License automatically deactivated due to expiration. Valid until: {valid_until}"))
                
                logging.info(f"Deactivated expired license: {license_key} (ID: {license_id})")
            
            conn.commit()
            logging.info(f"Successfully deactivated {len(expired_licenses)} expired licenses")
        else:
            logging.debug("No expired licenses found to deactivate")
        
        cur.close()
        conn.close()
        
    except Exception as e:
        logging.error(f"Error deactivating expired licenses: {str(e)}")
        if 'conn' in locals():
            conn.rollback()


def init_scheduler():
    """Initialize and configure the scheduler"""
    scheduler = BackgroundScheduler()
    
    # Configure daily backup job
    scheduler.add_job(
        scheduled_backup,
        'cron',
        hour=config.SCHEDULER_CONFIG['backup_hour'],
        minute=config.SCHEDULER_CONFIG['backup_minute'],
        id='daily_backup',
        replace_existing=True
    )
    
    # Configure session cleanup job - runs every 60 seconds
    scheduler.add_job(
        cleanup_expired_sessions,
        'interval',
        seconds=60,
        id='session_cleanup',
        replace_existing=True
    )
    
    # Configure license expiration job - runs daily at midnight
    scheduler.add_job(
        deactivate_expired_licenses,
        'cron',
        hour=0,
        minute=0,
        id='license_expiration_check',
        replace_existing=True
    )
    
    scheduler.start()
    logging.info(f"Scheduler started. Daily backup scheduled at {config.SCHEDULER_CONFIG['backup_hour']:02d}:{config.SCHEDULER_CONFIG['backup_minute']:02d}")
    logging.info("Session cleanup job scheduled to run every 60 seconds")
    logging.info("License expiration check scheduled to run daily at midnight")
    
    return scheduler