import pytz
from datetime import datetime, timedelta
from modules.database import query_db
from modules.config import ConfigManager
from modules.logger import logger

def parse_time_str(time_str: str):
    """Parses 'HH:MM' string into hour and minute ints."""
    parts = time_str.split(':')
    return int(parts[0]), int(parts[1])

def is_currently_off_time() -> bool:
    """Checks if the current time matches any enabled off-time schedule.
    
    Returns:
        bool: True if off-time is active (we should auto-reply), False otherwise.
    """
    config = ConfigManager()
    
    # Global check: if the system is disabled, we never auto-reply
    if not config.get('enabled'):
        return False
        
    try:
        # Load all enabled schedules
        schedules = query_db("SELECT * FROM schedules WHERE enabled = 1")
        if not schedules:
            # If no schedules are defined but system is enabled, let's look at the config.json default start/end times
            # to fall back if SQLite schedules is empty.
            fallback_start = config.get('start_time')
            fallback_end = config.get('end_time')
            fallback_tz = config.get('timezone', 'Asia/Dhaka')
            
            if fallback_start and fallback_end:
                # Fallback to single daily schedule on all days
                schedules = [{
                    'start_time': fallback_start,
                    'end_time': fallback_end,
                    'timezone': fallback_tz,
                    'days': "Saturday,Sunday,Monday,Tuesday,Wednesday,Thursday,Friday"
                }]
            else:
                return False

        utc_now = datetime.now(pytz.utc)

        for schedule in schedules:
            tz_name = schedule['timezone'] or config.get('timezone', 'Asia/Dhaka')
            try:
                tz = pytz.timezone(tz_name)
            except Exception:
                tz = pytz.timezone('Asia/Dhaka')
                
            local_now = utc_now.astimezone(tz)
            
            current_day = local_now.strftime('%A')
            prev_day = (local_now - timedelta(days=1)).strftime('%A')
            
            current_time = local_now.time()
            
            start_hour, start_min = parse_time_str(schedule['start_time'])
            end_hour, end_min = parse_time_str(schedule['end_time'])
            
            start_time = datetime.strptime(f"{start_hour:02d}:{start_min:02d}", "%H:%M").time()
            end_time = datetime.strptime(f"{end_hour:02d}:{end_min:02d}", "%H:%M").time()
            
            scheduled_days = [d.strip() for d in schedule['days'].split(',') if d.strip()]
            
            # Case 1: Start and end in the same day (e.g., 09:00 - 17:00)
            if start_time <= end_time:
                if current_day in scheduled_days:
                    if start_time <= current_time <= end_time:
                        return True
            # Case 2: Schedule crosses midnight (e.g., 23:00 - 08:00)
            else:
                # Active if we are on a scheduled day and past start_time (e.g. 23:30 Friday)
                if current_day in scheduled_days and current_time >= start_time:
                    return True
                # Active if we are on the day AFTER a scheduled day and before end_time (e.g. 02:00 Saturday, following Friday run)
                if prev_day in scheduled_days and current_time <= end_time:
                    return True
                    
        return False
    except Exception as e:
        logger.error(f"Error in is_currently_off_time: {e}")
        return False
