#!/usr/bin/env python3
"""
Timmy World Rooms
Issue #83 — Evennia World Shell

The five core rooms of Timmy's world:
- Workshop: Where work happens
- Library: Knowledge storage
- Observatory: Monitoring and status
- Forge: Capability building
- Dispatch: Task queue
"""

from evennia import DefaultRoom
from typing import List, Dict, Any
from datetime import datetime


class TimmyRoom(DefaultRoom):
    """Base room type for Timmy's world."""
    
    def at_object_creation(self):
        """Called when room is created."""
        super().at_object_creation()
        self.db.room_type = "generic"
        self.db.activity_log = []
    
    def log_activity(self, message: str):
        """Log activity in this room."""
        entry = {
            "timestamp": datetime.now().isoformat(),
            "message": message
        }
        self.db.activity_log.append(entry)
        # Keep last 100 entries
        if len(self.db.activity_log) > 100:
            self.db.activity_log = self.db.activity_log[-100:]
    
    def get_display_desc(self, looker, **kwargs):
        """Get room description with dynamic content."""
        desc = super().get_display_desc(looker, **kwargs)
        
        # Add room-specific content
        if hasattr(self, 'get_dynamic_content'):
            desc += self.get_dynamic_content(looker)
        
        return desc


class Workshop(TimmyRoom):
    """
    The Workshop — default room where Timmy executes tasks.
    
    This is where active development happens. Tools are available,
    files can be edited, and work gets done.
    """
    
    def at_object_creation(self):
        super().at_object_creation()
        self.db.room_type = "workshop"
        self.key = "The Workshop"
        self.db.desc = """
|wThe Workshop|n

A clean, organized workspace with multiple stations:
- A terminal array for system operations
- A drafting table for architecture and design
- Tool racks along the walls
- A central workspace with holographic displays

This is where things get built.
        """.strip()
        
        self.db.active_projects = []
        self.db.available_tools = []
    
    def get_dynamic_content(self, looker, **kwargs):
        """Add dynamic content for workshop."""
        content = "\n\n"
        
        # Show active projects
        if self.db.active_projects:
            content += "|yActive Projects:|n\n"
            for project in self.db.active_projects[-5:]:
                content += f"  • {project}\n"
        
        # Show available tools count
        if self.db.available_tools:
            content += f"\n|g{len(self.db.available_tools)} tools available|n\n"
        
        return content
    
    def add_project(self, project_name: str):
        """Add an active project."""
        if project_name not in self.db.active_projects:
            self.db.active_projects.append(project_name)
            self.log_activity(f"Project started: {project_name}")
    
    def complete_project(self, project_name: str):
        """Mark a project as complete."""
        if project_name in self.db.active_projects:
            self.db.active_projects.remove(project_name)
            self.log_activity(f"Project completed: {project_name}")


class Library(TimmyRoom):
    """
    The Library — knowledge storage and retrieval.
    
    Where Timmy stores what he's learned: papers, techniques,
    best practices, and actionable knowledge.
    """
    
    def at_object_creation(self):
        super().at_object_creation()
        self.db.room_type = "library"
        self.key = "The Library"
        self.db.desc = """
|bThe Library|n

Floor-to-ceiling shelves hold knowledge items as glowing orbs:
- Optimization techniques sparkle with green light
- Architecture patterns pulse with blue energy
- Research papers rest in crystalline cases
- Best practices form organized stacks

A search terminal stands ready for queries.
        """.strip()
        
        self.db.knowledge_items = []
        self.db.categories = ["inference", "training", "prompting", "architecture", "tools"]
    
    def get_dynamic_content(self, looker, **kwargs):
        """Add dynamic content for library."""
        content = "\n\n"
        
        # Show knowledge stats
        items = [obj for obj in self.contents if obj.db.summary]
        if items:
            content += f"|yKnowledge Items:|n {len(items)}\n"
            
            # Show by category
            by_category = {}
            for item in items:
                for tag in item.db.tags or []:
                    by_category[tag] = by_category.get(tag, 0) + 1
            
            if by_category:
                content += "\n|wBy Category:|n\n"
                for tag, count in sorted(by_category.items(), key=lambda x: -x[1])[:5]:
                    content += f"  {tag}: {count}\n"
        
        return content
    
    def add_knowledge_item(self, item):
        """Add a knowledge item to the library."""
        self.db.knowledge_items.append(item.id)
        self.log_activity(f"Knowledge ingested: {item.name}")
    
    def search_by_tag(self, tag: str) -> List[Any]:
        """Search knowledge items by tag."""
        items = [obj for obj in self.contents if tag in (obj.db.tags or [])]
        return items
    
    def search_by_keyword(self, keyword: str) -> List[Any]:
        """Search knowledge items by keyword."""
        items = []
        for obj in self.contents:
            if obj.db.summary and keyword.lower() in obj.db.summary.lower():
                items.append(obj)
        return items


class Observatory(TimmyRoom):
    """
    The Observatory — monitoring and status.
    
    Where Timmy watches systems, checks health, and maintains
    awareness of the infrastructure state.
    """
    
    def at_object_creation(self):
        super().at_object_creation()
        self.db.room_type = "observatory"
        self.key = "The Observatory"
        self.db.desc = """
|mThe Observatory|n

A panoramic view of the infrastructure:
- Holographic dashboards float in the center
- System status displays line the walls
- Alert panels glow with current health
- A command console provides control

Everything is monitored from here.
        """.strip()
        
        self.db.system_status = {}
        self.db.active_alerts = []
        self.db.metrics_history = []
    
    def get_dynamic_content(self, looker, **kwargs):
        """Add dynamic content for observatory."""
        content = "\n\n"
        
        # Show system status
        if self.db.system_status:
            content += "|ySystem Status:|n\n"
            for system, status in self.db.system_status.items():
                icon = "|g✓|n" if status == "healthy" else "|r✗|n"
                content += f"  {icon} {system}: {status}\n"
        
        # Show active alerts
        if self.db.active_alerts:
            content += "\n|rActive Alerts:|n\n"
            for alert in self.db.active_alerts[-3:]:
                content += f"  ! {alert}\n"
        else:
            content += "\n|gNo active alerts|n\n"
        
        return content
    
    def update_system_status(self, system: str, status: str):
        """Update status for a system."""
        old_status = self.db.system_status.get(system)
        self.db.system_status[system] = status
        
        if old_status != status:
            self.log_activity(f"System {system}: {old_status} -> {status}")
            
            if status != "healthy":
                self.add_alert(f"{system} is {status}")
    
    def add_alert(self, message: str, severity: str = "warning"):
        """Add an alert."""
        alert = {
            "message": message,
            "severity": severity,
            "timestamp": datetime.now().isoformat()
        }
        self.db.active_alerts.append(alert)
    
    def clear_alert(self, message: str):
        """Clear an alert."""
        self.db.active_alerts = [
            a for a in self.db.active_alerts 
            if a["message"] != message
        ]
    
    def record_metrics(self, metrics: Dict[str, Any]):
        """Record current metrics."""
        entry = {
            "timestamp": datetime.now().isoformat(),
            "metrics": metrics
        }
        self.db.metrics_history.append(entry)
        # Keep last 1000 entries
        if len(self.db.metrics_history) > 1000:
            self.db.metrics_history = self.db.metrics_history[-1000:]


class Forge(TimmyRoom):
    """
    The Forge — capability building and tool creation.
    
    Where Timmy builds new capabilities, creates tools,
    and improves his own infrastructure.
    """
    
    def at_object_creation(self):
        super().at_object_creation()
        self.db.room_type = "forge"
        self.key = "The Forge"
        self.db.desc = """
|rThe Forge|n

Heat and light emanate from working stations:
- A compiler array hums with activity
- Tool templates hang on the walls
- Test rigs verify each creation
- A deployment pipeline waits ready

Capabilities are forged here.
        """.strip()
        
        self.db.available_tools = []
        self.db.build_queue = []
        self.db.test_results = []
    
    def get_dynamic_content(self, looker, **kwargs):
        """Add dynamic content for forge."""
        content = "\n\n"
        
        # Show available tools
        tools = [obj for obj in self.contents if hasattr(obj, 'db') and obj.db.tool_type]
        if tools:
            content += f"|yAvailable Tools:|n {len(tools)}\n"
        
        # Show build queue
        if self.db.build_queue:
            content += f"\n|wBuild Queue:|n {len(self.db.build_queue)} items\n"
        
        return content
    
    def register_tool(self, tool):
        """Register a new tool."""
        self.db.available_tools.append(tool.id)
        self.log_activity(f"Tool registered: {tool.name}")
    
    def queue_build(self, description: str):
        """Queue a new capability build."""
        self.db.build_queue.append({
            "description": description,
            "queued_at": datetime.now().isoformat(),
            "status": "pending"
        })
        self.log_activity(f"Build queued: {description}")
    
    def record_test_result(self, test_name: str, passed: bool, output: str):
        """Record a test result."""
        self.db.test_results.append({
            "test": test_name,
            "passed": passed,
            "output": output,
            "timestamp": datetime.now().isoformat()
        })


class Dispatch(TimmyRoom):
    """
    The Dispatch — task queue and routing.
    
    Where incoming work arrives, gets prioritized,
    and is assigned to appropriate houses.
    """
    
    def at_object_creation(self):
        super().at_object_creation()
        self.db.room_type = "dispatch"
        self.key = "Dispatch"
        self.db.desc = """
|yDispatch|n

A command center for task management:
- Incoming task queue displays on the wall
- Routing assignments to different houses
- Priority indicators glow red/orange/green
- Status boards show current workload

Work flows through here.
        """.strip()
        
        self.db.pending_tasks = []
        self.db.routing_rules = {
            "timmy": ["sovereign", "final_decision", "critical"],
            "ezra": ["research", "documentation", "analysis"],
            "bezalel": ["implementation", "testing", "building"],
            "allegro": ["routing", "connectivity", "tempo"]
        }
    
    def get_dynamic_content(self, looker, **kwargs):
        """Add dynamic content for dispatch."""
        content = "\n\n"
        
        # Show pending tasks
        tasks = [obj for obj in self.contents if hasattr(obj, 'db') and obj.db.status == "pending"]
        if tasks:
            content += f"|yPending Tasks:|n {len(tasks)}\n"
            for task in tasks[:5]:
                priority = task.db.priority
                color = "|r" if priority == "high" else "|y" if priority == "medium" else "|g"
                content += f"  {color}[{priority}]|n {task.name}\n"
        else:
            content += "|gNo pending tasks|n\n"
        
        # Show routing rules
        content += "\n|wRouting:|n\n"
        for house, responsibilities in self.db.routing_rules.items():
            content += f"  {house}: {', '.join(responsibilities[:2])}\n"
        
        return content
    
    def receive_task(self, task):
        """Receive a new task."""
        self.db.pending_tasks.append(task.id)
        self.log_activity(f"Task received: {task.name}")
        
        # Auto-route based on task type
        if task.db.task_type in self.db.routing_rules["timmy"]:
            task.assign("timmy")
        elif task.db.task_type in self.db.routing_rules["ezra"]:
            task.assign("ezra")
        elif task.db.task_type in self.db.routing_rules["bezalel"]:
            task.assign("bezalel")
        else:
            task.assign("allegro")
    
    def get_task_stats(self) -> Dict[str, int]:
        """Get statistics on tasks."""
        tasks = [obj for obj in self.contents if hasattr(obj, 'db') and obj.db.status]
        stats = {"pending": 0, "active": 0, "completed": 0}
        for task in tasks:
            status = task.db.status
            if status in stats:
                stats[status] += 1
        return stats
