# utils/scheduled.py

import random
import json
import os
import time
import asyncio
from datetime import datetime, timedelta
from apscheduler.triggers.date import DateTrigger
from discord import Status, ActivityType

import globals
from server_manager import server_manager
from utils.llm import query_llama
from utils.dm_interaction_analyzer import dm_analyzer
from utils.logger import get_logger

logger = get_logger('scheduled')

BEDTIME_TRACKING_FILE = "last_bedtime_targets.json"

async def send_monday_video_for_server(guild_id: int):
    """Send Monday video for a specific server"""
    server_config = server_manager.get_server_config(guild_id)
    if not server_config:
        logger.warning(f"No config found for server {guild_id}")
        return
    
    # No need to switch model - llama-swap handles this automatically

    # Generate a motivational message
    prompt = "It's Miku Monday! Give me an energetic and heartfelt Miku Monday morning message to inspire someone for the week ahead."
    response = await query_llama(prompt, user_id=f"weekly-motivation-{guild_id}", guild_id=guild_id)

    video_url = "http://zip.koko210cloud.xyz/u/zEgU7Z.mp4"

    # Use server-specific bedtime channels
    target_channel_ids = server_config.bedtime_channel_ids
    
    for channel_id in target_channel_ids:
        channel = globals.client.get_channel(channel_id)
        if channel is None:
            logger.error(f"Could not find channel with ID {channel_id} in server {server_config.guild_name}")
            continue

        try:
            await channel.send(content=response)
            # Send video link
            await channel.send(f"[Happy Miku Monday!]({video_url})")

            logger.info(f"Sent Monday video to channel ID {channel_id} in server {server_config.guild_name}")
        except Exception as e:
            logger.error(f"Failed to send video to channel ID {channel_id} in server {server_config.guild_name}: {e}")

async def send_monday_video():
    """Legacy function - now sends to all servers"""
    for guild_id in server_manager.servers:
        await send_monday_video_for_server(guild_id)

def load_last_bedtime_targets():
    if not os.path.exists(BEDTIME_TRACKING_FILE):
        return {}
    try:
        with open(BEDTIME_TRACKING_FILE, "r") as f:
            return json.load(f)
    except Exception as e:
        logger.error(f"Failed to load bedtime tracking file: {e}")
        return {}

_last_bedtime_targets = load_last_bedtime_targets()

def save_last_bedtime_targets(data):
    try:
        with open(BEDTIME_TRACKING_FILE, "w") as f:
            json.dump(data, f)
    except Exception as e:
        logger.error(f"Failed to save bedtime tracking file: {e}")

async def send_bedtime_reminder_for_server(guild_id: int, client=None):
    """Send bedtime reminder for a specific server"""
    server_config = server_manager.get_server_config(guild_id)
    if not server_config:
        logger.warning(f"No config found for server {guild_id}")
        return
    
    # Use provided client or fall back to globals.client
    if client is None:
        client = globals.client
    
    if client is None:
        logger.error(f"No Discord client available for bedtime reminder in server {guild_id}")
        return
    
    # No need to switch model - llama-swap handles this automatically

    # Use server-specific bedtime channels
    for channel_id in server_config.bedtime_channel_ids:
        channel = client.get_channel(channel_id)
        if not channel:
            logger.warning(f"Channel ID {channel_id} not found in server {server_config.guild_name}")
            continue

        guild = channel.guild

        # Filter online members (excluding bots)
        online_members = [
            member for member in guild.members
            if member.status in {Status.online, Status.idle, Status.dnd}
            and not member.bot
        ]

        specific_user_id = 214857593045254151 # target user ID
        specific_user = guild.get_member(specific_user_id)
        if specific_user and specific_user not in online_members:
            online_members.append(specific_user)

        if not online_members:
            # TODO: Handle this in a different way in the future
            logger.debug(f"No online members to ping in {guild.name}")
            continue

        # Avoid repeating the same person unless they're the only one
        last_target_id = _last_bedtime_targets.get(str(guild.id))
        eligible_members = [m for m in online_members if m.id != last_target_id]

        if not eligible_members:
            eligible_members = online_members  # fallback if only one user

        chosen_one = random.choice(eligible_members)
        _last_bedtime_targets[str(guild.id)] = chosen_one.id
        save_last_bedtime_targets(_last_bedtime_targets)

        # 🎯 Status-aware phrasing
        status_map = {
            Status.online: "",
            Status.idle: "Be sure to include the following information on their status too: Their profile status is currently idle. This implies they're not on their computer now, but are still awake.",
            Status.dnd: "Be sure to include the following information on their status too: Their current profile status is 'Do Not Disturb.' This implies they are very absorbed in what they're doing. But it's still important for them to know when to stop for the day and get some sleep, right?",
            Status.offline: "Be sure to include the following information on their status too: Their profile status is currently offline, but is it really? It's very likely they've just set it to invisible to avoid being seen that they're staying up so late!"
        }
        status_note = status_map.get(chosen_one.status, "")

        # 🎮 Activity-aware phrasing
        activity_note = ""
        if chosen_one.activities:
            for activity in chosen_one.activities:
                if activity.type == ActivityType.playing:
                    activity_note = f"You should also include the following information on their current activity on their profile too: They are playing **{activity.name}** right now. It's getting late, though. Maybe it's time to pause, leave the rest of the game for tomorrow and rest..."
                    break
                elif activity.type == ActivityType.streaming:
                    activity_note = f"You should also include the following information on their current activity on their profile too: They are streaming **{activity.name}** at this hour? They should know it's getting way too late for streams."
                    break
                elif activity.type == ActivityType.watching:
                    activity_note = f"You should also include the following information on their current activity on their profile too: They are watching **{activity.name}** right now. That's cozy, but it's not good to binge so late."
                    break
                elif activity.type == ActivityType.listening:
                    activity_note = f"You should also include the following information on their current activity on their profile too: They are listening to **{activity.name}** right now. Sounds like they're better off putting appropriate music to fall asleep to."
                    break

        # Generate intelligent bedtime message
        prompt = (
            f"Write a sweet, funny, or encouraging bedtime message to remind someone it's getting late and they should sleep. "
            f"Miku is currently feeling: {server_config.current_mood_description or 'neutral'}\nPlease word in a way that reflects this emotional tone."
        )
        
        bedtime_message = await query_llama(prompt, user_id=f"bedtime-{guild_id}", guild_id=guild_id)

        try:
            await channel.send(f"{chosen_one.mention} {bedtime_message}")
            logger.info(f"Sent bedtime reminder to {chosen_one.display_name} in server {server_config.guild_name}")
        except Exception as e:
            logger.error(f"Failed to send bedtime reminder in server {server_config.guild_name}: {e}")

async def send_bedtime_reminder():
    """Legacy function - now sends to all servers"""
    for guild_id in server_manager.servers:
        await send_bedtime_reminder_for_server(guild_id, globals.client)

def schedule_random_bedtime():
    """Legacy function - now schedules for all servers"""
    for guild_id in server_manager.servers:
        # Schedule bedtime for each server using the async function
        # This will be called from the server manager's event loop
        logger.info(f"Scheduling bedtime for server {guild_id}")
        # Note: This function is now called from the server manager's context
        # which properly handles the async operations

async def send_bedtime_now():
    """Send bedtime reminder immediately to all servers"""
    for guild_id in server_manager.servers:
        await send_bedtime_reminder_for_server(guild_id, globals.client)

async def run_daily_dm_analysis():
    """Run daily DM interaction analysis - reports one user per day"""
    if dm_analyzer is None:
        logger.warning("DM Analyzer not initialized, skipping daily analysis")
        return
    
    logger.info("Running daily DM interaction analysis...")
    await dm_analyzer.run_daily_analysis()
