
import os
import shutil
import subprocess
import winsound
import json
import time as time_lib
from datetime import datetime, timedelta
from livekit.agents import function_tool, RunContext

# ==============================
# PRODUCTIVITY (FOCUS MODE)
# ==============================

HOSTS_PATH = r"C:\Windows\System32\drivers\etc\hosts"
BACKUP_PATH = r"C:\Windows\System32\drivers\etc\hosts.bak"

@function_tool()
async def enable_focus_mode(context: RunContext, websites: list[str]) -> str:
    """
    Blocks the specified websites by modifying the hosts file.
    Requires Administrator privileges.
    """
    try:
        # Backup hosts file if not exists
        if not os.path.exists(BACKUP_PATH):
            shutil.copy(HOSTS_PATH, BACKUP_PATH)

        with open(HOSTS_PATH, "r") as f:
            content = f.read()

        new_entries = "\n# FOCUS MODE START\n"
        for site in websites:
            # Clean domain
            domain = site.replace("https://", "").replace("http://", "").replace("www.", "").strip()
            if domain not in content:
                new_entries += f"127.0.0.1 {domain}\n"
                new_entries += f"127.0.0.1 www.{domain}\n"
        new_entries += "# FOCUS MODE END\n"

        with open(HOSTS_PATH, "a") as f:
            f.write(new_entries)

        # Flush DNS
        subprocess.run("ipconfig /flushdns", shell=True)
        return f"✅ Focus Mode ENABLED. Blocked: {', '.join(websites)}"

    except PermissionError:
        return "❌ Permission Denied: Run Friday as Administrator."
    except Exception as e:
        return f"❌ Failed to enable Focus Mode: {e}"

@function_tool()
async def disable_focus_mode(context: RunContext) -> str:
    """
    Restores the original hosts file to unblock websites.
    """
    try:
        if os.path.exists(BACKUP_PATH):
            shutil.copy(BACKUP_PATH, HOSTS_PATH)
            subprocess.run("ipconfig /flushdns", shell=True)
            return "✅ Focus Mode DISABLED. Websites unblocked."
        else:
            return "❌ No backup found. Cannot restore hosts file."
    except PermissionError:
        return "❌ Permission Denied: Run Friday as Administrator."
    except Exception as e:
        return f"❌ Failed to disable Focus Mode: {e}"

@function_tool()
async def add_smart_reminder(context: RunContext, task: str, time_at: str) -> str:
    """Sets a reminder for a specific time (HH:MM)."""
    reminder_file = "reminders.json"
    reminders = []
    if os.path.exists(reminder_file):
        with open(reminder_file, "r") as f:
            try: reminders = json.load(f)
            except: reminders = []
    
    reminders.append({
        "type": "reminder",
        "task": task,
        "time": time_at,
        "notified": False,
        "date": datetime.now().strftime("%Y-%m-%d")
    })
    
    with open(reminder_file, "w") as f:
        json.dump(reminders, f, indent=2)
        
    return f"Reminder set for {task} at {time_at}"

@function_tool()
async def set_timer(context: RunContext, duration_seconds: int, task: str = "Timer") -> str:
    """Sets a countdown timer for a number of seconds."""
    reminder_file = "reminders.json"
    reminders = []
    if os.path.exists(reminder_file):
        with open(reminder_file, "r") as f:
            try: reminders = json.load(f)
            except: reminders = []
    
    expiry = datetime.now() + timedelta(seconds=duration_seconds)
    reminders.append({
        "type": "timer",
        "task": task,
        "expiry": expiry.timestamp(),
        "notified": False
    })
    
    with open(reminder_file, "w") as f:
        json.dump(reminders, f, indent=2)
        
    return f"Timer set for {duration_seconds} seconds for: {task}"

@function_tool()
async def set_alarm(context: RunContext, time_at: str, task: str = "Alarm") -> str:
    """Sets an alarm for a specific time (HH:MM)."""
    reminder_file = "reminders.json"
    reminders = []
    if os.path.exists(reminder_file):
        with open(reminder_file, "r") as f:
            try: reminders = json.load(f)
            except: reminders = []
    
    reminders.append({
        "type": "alarm",
        "task": task,
        "time": time_at,
        "notified": False,
        "date": datetime.now().strftime("%Y-%m-%d")
    })
    
    with open(reminder_file, "w") as f:
        json.dump(reminders, f, indent=2)
        
    return f"Alarm set for {time_at} for: {task}"

async def check_and_notify_reminders(session):
    reminder_file = "reminders.json"
    if not os.path.exists(reminder_file):
        return

    try:
        with open(reminder_file, "r") as f:
            reminders = json.load(f)
    except:
        return

    now = datetime.now()
    current_time_str = now.strftime("%H:%M")
    current_date_str = now.strftime("%Y-%m-%d")
    current_ts = now.timestamp()
    
    changed = False
    for r in reminders:
        if r.get("notified"):
            continue
            
        trigger = False
        r_type = r.get("type", "reminder")
        
        if r_type == "timer":
            if current_ts >= r.get("expiry", 0):
                trigger = True
        else: # reminder or alarm
            if r.get("time") == current_time_str and r.get("date") == current_date_str:
                trigger = True

        if trigger:
            # Notify visually/verbally if session active
            print(f"🔔 TRIGGER: {r['task']} ({r_type})")
            
            # Audible alert (Works even if session is 'off' but process is running)
            try:
                # Play system exclamation sound or beep
                winsound.Beep(1000, 2000) # 1000Hz for 2 seconds
            except: pass

            if session:
                try:
                    await session.generate_reply(instructions=f"PROACTIVE NOTIFICATION: The {r_type} for '{r['task']}' is finished. Inform the user in a natural way.")
                except Exception as e:
                    print(f"Failed to send verbal notification: {e}")
            
            r["notified"] = True
            changed = True

    if changed:
        # Keep only last 10 notified items or just unnotified ones
        active_reminders = [r for r in reminders if not r.get("notified")]
        # (Optional: keep history if needed, but for now just cleanup)
        with open(reminder_file, "w") as f:
            json.dump(reminders, f, indent=2)

