from dotenv import load_dotenv
load_dotenv()

import os
from mem0 import MemoryClient
from livekit import agents
from livekit.agents import Agent, AgentSession, RoomInputOptions, RunContext
from livekit.plugins import google, noise_cancellation

from .prompts import AGENT_INSTRUCTION, SESSION_INSTRUCTION
from .tools import *

# ==============================
# MEM0 SETUP
# ==============================
MEM0_API_KEY = os.getenv("MEM0_API_KEY")
USER_ID = "SHIVANSH"

mem0 = MemoryClient(api_key= os.getenv("MEM0_API_KEY"))

# ==============================
# TOOLS
# ==============================
ALL_TOOLS = [
    # Core system & info
    get_weather, search_web, send_email, current_time,
    system_status, system_uptime, battery_status, check_internet, system_health_report,
    control_bluetooth, control_windows_settings,
    
    # Media & entertainment
    play_music, control_lg_tv, control_jio_stb, youtube_search_results, select_video_by_index,
    
    # App tracking & memory
    track_active_application, weekly_app_usage_report,
    remember, recall,
    
    # Contact management
    save_contact, get_contact_phone, list_all_contacts, delete_contact, search_contacts,
    
    # File system operations
    create_file, read_file, delete_file, rename_file, list_directory, create_folder,
    open_file_or_folder,
    
    # Window management
    get_active_window, minimize_window, maximize_window, close_active_window, switch_window,
    
    # OS automation
    open_website_or_app, run_command, lock_system,
    
    # Enhanced CMD/PowerShell access
    execute_powershell, execute_cmd,
    
    # Input control
    keyboard_mouse_control, volume_control, take_screenshot,
    
    # Clipboard
    read_clipboard, copy_to_clipboard, open_clipboard_history,
    
    # Process management
    running_processes, terminate_process,
    
    # Network scanning & monitoring
    scan_network_devices, get_detailed_network_info, get_active_connections,
    get_router_info, network_bandwidth_usage, get_network_speed,
    ping_device, trace_route, port_scan, get_remote_device_info, get_device_services,
    
    # Network control
    ip_information, list_wifi_networks, connect_wifi, disconnect_wifi,
    flush_dns, renew_ip_address, control_network_adapter,
    
    # Advanced network control (requires admin)
    disconnect_device_from_internet, reconnect_device_to_internet,
    check_admin_privileges, enable_packet_forwarding,
    get_router_admin_page, network_kill_switch,
    monitor_network_traffic, limit_device_bandwidth, remove_bandwidth_limit,
    get_network_devices_with_names,
    
    # Remote device control
    wake_on_lan, remote_shutdown, remote_restart, execute_remote_command,
    remote_desktop_connect, send_network_message,
    
    # Network file sharing
    share_folder_on_network, remove_network_share, list_network_shares,
    access_network_share, map_network_drive, disconnect_network_drive,
    remote_file_copy,
    
    # Router control
    control_jio_router,
    
    # Power management
    restart_system, shutdown_system, sleep_system, hibernate_system,
    
    # Advanced features
    login_with_gmail, generate_image,
    set_brightness, disk_usage, show_notification, schedule_task,
    
    # Phone & messaging
    universal_phone_unlocker, send_whatsapp_message, send_whatsapp_image, check_gmail_for_otp, 
    get_email_count, get_recent_email_senders, read_specific_email, reply_to_latest_email,

    # Intelligence & Hacking
    get_saved_wifi_passwords, analyze_screen_content, summarize_website,

    # GitHub Automation
    github_create_repo, github_push_changes,

    # YouTube Automation
    get_youtube_subscribers, open_youtube_studio,

    # Strategic & Government Tools
    generate_intelligence_briefing, satellite_recon, defense_protocol_alpha, perform_signal_intelligence_scan,

    # New Features
    send_whatsapp_message_background, make_phone_call, track_phone_number, get_latest_call_info, generate_phone_location_map, get_exact_location_via_adb, identify_object_from_camera,
    whatsapp_call, google_duo_call, start_google_meet, add_smart_reminder,
    play_chess_move_autonomously, detect_user_mood, perform_biometric_fingerprint_scan,
    vulnerability_scanner, local_network_brute_force, metasploit_demo_console, sniff_network_packets,
    remote_execute_psexec_hash,
    
    # Productivity
    enable_focus_mode, disable_focus_mode,
]

import asyncio

# Global storage for the current session to allow proactive notifications
active_session = None

# ==============================
# BACKGROUND WORKER
# ==============================
async def reminder_worker():
    while True:
        try:
            await check_and_notify_reminders(active_session)
        except:
            pass
        await asyncio.sleep(60) # Check every minute

# ==============================
# INTENT ROUTER
# ==============================
def route_intent(q: str):
    q = q.lower()
    if "on tv" in q: return control_lg_tv, {"command": "on_youtube", "value": q.replace("on tv", "").replace("play", "").strip()}
    if q.startswith("play"): return youtube_search_results, {"query": q.replace("play", "").strip()}
    if "email" in q: return send_email, {"query": q}
    if "unlock phone" in q: return universal_phone_unlocker, {}
    if "weather" in q: return get_weather, {"city": q.split()[-1]}
    if "time" in q: return current_time, {}
    if "internet" in q: return check_internet, {}
    if "weekly report" in q: return weekly_app_usage_report, {}
    if q.startswith("open"): return open_website_or_app, {"query": q}
    if "shutdown" in q: return shutdown_system, {}
    if "restart" in q: return restart_system, {}
    if "hacking scan" in q: return vulnerability_scanner, {"target": q.split()[-1]}
    if "brute force" in q: return local_network_brute_force, {"target_ip": q.split()[-1]}
    if "metasploit" in q: return metasploit_demo_console, {}
    if "jio" in q and ("pause" in q or "resume" in q or "play" in q or "stop" in q):
        action = "pause" if "pause" in q else ("resume" if "resume" in q else ("play" if "play" in q else "stop"))
        return control_jio_stb, {"action": action}
    return None, None

# ==============================
# ASSISTANT
# ==============================
class Assistant(Agent):
    def __init__(self):
        super().__init__(
            instructions=AGENT_INSTRUCTION,
            llm=google.beta.realtime.RealtimeModel(
                voice="Aoede",
                temperature=0.9,
            ),
            tools=ALL_TOOLS,
        )

    async def on_user_message(self, context: RunContext, message: str):
        global active_session
        
        # 🔹 SMART STORE MEMORY - Explicit remember command
        if message.lower().startswith("remember"):
            text = message.replace("remember", "").strip()
            mem0.add(messages=[{"role": "user", "content": text}], user_id=USER_ID)
            return "I've saved that to my long-term memory, Sir."
            
        # 🔹 AUTO-DETECT AND STORE IMPORTANT EVENTS
        event_keywords = [
            "meeting", "interview", "appointment", "event", "tomorrow", "next week", 
            "next month", "schedule", "basketball", "going to", "have to", "will be",
            "presentation", "exam", "test", "trip", "travel", "flight", "doctor",
            "dentist", "party", "celebration", "birthday", "anniversary", "deadline"
        ]
        
        # Store events automatically
        if any(keyword in message.lower() for keyword in event_keywords):
            mem0.add(
                messages=[{
                    "role": "user", 
                    "content": f"[EVENT] {message}"
                }], 
                user_id=USER_ID
            )
            print(f"📝 Stored event memory: {message}")

        # 🔹 AUTO-READ FILE PATHS
        import re
        if re.search(r'[a-zA-Z]:\\[\\\w\s.-]+', message) or ("/" in message and "." in message):
            path_match = re.search(r'([a-zA-Z]:\\[\\\w\s.-]+)', message)
            if path_match:
                file_path = path_match.group(1).strip()
                if os.path.exists(file_path) and os.path.isfile(file_path):
                    return await read_file(context, file_path)

        # 🔹 RETRIEVE RELEVANT MEMORIES
        memories = mem0.search(query=message, user_id=USER_ID, limit=5)
        memory_context = ""
        if memories and len(memories) > 0:
            memory_context = "IMPORTANT - You have the following memories about the user:\n"
            for m in memories:
                if 'memory' in m:
                    content = m['memory'].get('content', '') if isinstance(m['memory'], dict) else str(m['memory'])
                    memory_context += f"- {content}\n"

        # 🔹 INTENT ROUTING
        tool, args = route_intent(message)
        if tool:
            return await tool(context, **args)

        # 🔹 STRONG MEMORY INJECTION INTO PROMPT
        final_prompt = f"""
{memory_context}

User message:
{message}

IMPORTANT: If you have memories about past events the user mentioned (meetings, interviews, etc.), 
ask them how it went in a natural, conversational way.
"""
        return await super().on_user_message(context, final_prompt)

# ==============================
# ENTRYPOINT
# ==============================
async def entrypoint(ctx: agents.JobContext):
    print("🚀 Initializing Friday Agent...")
    global active_session
    
    try:
        await ctx.connect()
        print("✅ Connected to LiveKit Room.")
    except Exception as e:
        print(f"❌ Connection failed: {e}")
        return

    session = AgentSession()
    active_session = session

    # 🔹 START BACKGROUND WORKER
    asyncio.create_task(reminder_worker())

    await session.start(
        room=ctx.room,
        agent=Assistant(),
        room_input_options=RoomInputOptions(
            video_enabled=True,
            noise_cancellation=noise_cancellation.BVC(),
        ),
    )
    print("✅ Session started.")
    
    
    # 🔹 STARTUP GREETING WITH MEMORY CONTEXT
    try:
        # Get all recent memories
        all_memories = mem0.get_all(user_id=USER_ID, limit=10)
        
        # Filter for event memories
        event_memories = []
        general_memories = []
        
        if all_memories:
            for mem in all_memories:
                mem_content = ""
                if isinstance(mem, dict):
                    if 'memory' in mem:
                        mem_content = mem['memory'].get('content', '') if isinstance(mem['memory'], dict) else str(mem['memory'])
                    else:
                        mem_content = str(mem)
                else:
                    mem_content = str(mem)
                
                if '[EVENT]' in mem_content or any(kw in mem_content.lower() for kw in ['meeting', 'interview', 'appointment', 'tomorrow', 'today']):
                    event_memories.append(mem_content.replace('[EVENT]', '').strip())
                else:
                    general_memories.append(mem_content)
        
        # Build context string
        context_parts = []
        if event_memories:
            context_parts.append("RECENT EVENTS THE USER MENTIONED:")
            context_parts.extend([f"- {mem}" for mem in event_memories[:5]])
        
        if general_memories:
            context_parts.append("\nOTHER MEMORIES:")
            context_parts.extend([f"- {mem}" for mem in general_memories[:3]])
        
        context_str = "\n".join(context_parts) if context_parts else ""
        
        # Enhanced session instruction with memory
        enhanced_instruction = f"""{SESSION_INSTRUCTION}

{context_str}

IMPORTANT INSTRUCTIONS:
- You detected past events in the user's memory (above).
- Your GOAL for this first message is to PROACTIVELY ask about the MOST RECENT event.
- Do NOT say "Hello" or "How can I help" generically if you have an event to ask about.
- Example: "Welcome back, Sir. How did your meeting go?"
- Example: "Good evening, Boss. usage: Did you manage to catch your flight?"
- BE SPECIFIC. Mention the event context.
"""
        # If we have specific event memories, force the issue
        if event_memories:
             enhanced_instruction += "\n\nCRITICAL: You MUST start by asking about the event mentioned above: " + event_memories[0]

    except Exception as e:
        print(f"Greeting error: {e}")
        await session.generate_reply(instructions=SESSION_INSTRUCTION)

# ==============================
# RUN
# ==============================
def main():
    print("Friday online.")
    # existing logic here

if __name__ == "__main__":
    while True:
        pwd = input("🔒 ENTER ACCESS CODE: ")
        if pwd.strip() == "JARVIS":
            print("✅ ACCESS GRANTED")
            break
        print("❌ ACCESS DENIED")

    agents.cli.run_app(
        agents.WorkerOptions(entrypoint_fnc=entrypoint)
    )
