import asyncio
import json
import logging
import os
import uuid
import time
import base64
from pathlib import Path
from typing import Any, Dict, List, Optional

logger = logging.getLogger("brynq.executor.commands")

def get_active_project_store(room_manager: Any) -> Any:
    """Get the ProjectStore from the active room host or client."""
    if room_manager.is_host and room_manager.host_service:
        return getattr(room_manager.host_service, 'project_store', None)
    elif room_manager.client_service:
        return getattr(room_manager.client_service, 'project_store', None)
    return None

async def handle_room_command(action: str, arg: str, room_manager: Any) -> Dict[str, Any]:
    """Shared logic for /room commands."""
    try:
        if action == "create":
            room_name = arg or "Untitled Room"
            room = await room_manager.create_room(room_name)
            return {"status": "success", "message": f"Room created: \"{room_name}\"", "room": room}
        elif action == "join":
            if not arg:
                return {"status": "error", "message": "Usage: /room join <BRYNQ-XXXX>"}
            room = await room_manager.join_room(arg)
            return {"status": "success", "message": f"Joined room: \"{room.get('name')}\"", "room": room}
        elif action == "leave":
            await room_manager.leave_room()
            return {"status": "success", "message": "Left the room."}
        elif action == "status":
            if not room_manager.active_room:
                return {"status": "info", "message": "Not in a room."}
            r = room_manager.active_room
            msg = f"Room: \"{r.get('name')}\" ({r.get('room_code')})\n"
            msg += f"Host: {'You' if room_manager.is_host else 'Remote'}\n"
            msg += f"Members: {len(r.get('members', []))}"
            return {"status": "info", "message": msg}
        elif action == "agents":
            if not room_manager.active_room:
                return {"status": "error", "message": "Not in a room."}
            agents = room_manager.a2a.remote_agents
            if not agents:
                return {"status": "info", "message": "No remote agents discovered yet."}
            
            msg = f"Remote Agents ({len(agents)}):\n"
            for aid, identity in agents.items():
                msg += f"  - {identity.name} (ID: {aid[:8]}...)\n"
                msg += f"    Capabilities: {', '.join(identity.capabilities)}\n"
            return {"status": "info", "message": msg}
        else:
            return {"status": "error", "message": f"Unknown room action: {action}"}
    except Exception as e:
        return {"status": "error", "message": f"Room error: {e}"}

async def handle_project_command(action: str, arg: str, room_manager: Any, user_id: str, username: str) -> Dict[str, Any]:
    """Shared logic for /project commands."""
    from runtime.rooms.project_store import ProjectStore
    
    try:
        if action == "create":
            if not room_manager.active_room:
                return {"status": "error", "message": "You must be in a room first."}
            project_name = arg or "Untitled Project"
            project_id = f"proj_{uuid.uuid4().hex[:12]}"
            store = ProjectStore(project_id)
            meta = {
                "project_id": project_id,
                "name": project_name,
                "room_id": room_manager.active_room.get("room_id", ""),
                "created_by": user_id,
                "created_at": time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),
                "description": ""
            }
            store.save_metadata(meta)
            
            # Attach to host/client
            if room_manager.is_host and room_manager.host_service:
                room_manager.host_service.project_store = store
                room_manager.host_service.active_project_id = project_id
            elif room_manager.client_service:
                room_manager.client_service.project_store = store
                room_manager.client_service.active_project_id = project_id
                
            announce = {
                "type": "project_created",
                "project_id": project_id,
                "name": project_name,
                "created_by": user_id,
                "created_by_name": username,
                "timestamp": meta["created_at"]
            }
            room_manager.send_message_raw(announce)
            return {"status": "success", "message": f"Project created: \"{project_name}\"", "project_id": project_id}

        elif action == "files":
            store = get_active_project_store(room_manager)
            if not store:
                return {"status": "error", "message": "No active project."}
            files = store.list_files()
            return {"status": "success", "files": files}

        elif action == "save":
            store = get_active_project_store(room_manager)
            if not store:
                return {"status": "error", "message": "No active project."}
            
            source = Path(arg).expanduser().resolve()
            if not source.exists() or not source.is_file():
                return {"status": "error", "message": f"File not found: {arg}"}
            
            content = source.read_bytes()
            rel_path = source.name
            result = store.add_file(rel_path, content, user_id=user_id, user_name=username)
            
            push_msg = {
                "type": "project_file_push",
                "project_id": store.project_id,
                "relative_path": rel_path,
                "content_b64": base64.b64encode(content).decode("ascii"),
                "content_hash": result["content_hash"],
                "size_bytes": result["size_bytes"],
                "action": result["action"],
                "user_id": user_id,
                "user_name": username,
                "timestamp": result["timestamp"]
            }
            room_manager.send_message_raw(push_msg)
            return {"status": "success", "message": f"Saved {rel_path}"}

        elif action == "delete":
            store = get_active_project_store(room_manager)
            if not store:
                return {"status": "error", "message": "No active project."}
            
            if store.delete_file(arg, user_id=user_id, user_name=username):
                del_msg = {
                    "type": "project_file_deleted",
                    "project_id": store.project_id,
                    "relative_path": arg,
                    "user_id": user_id,
                    "user_name": username,
                    "timestamp": time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
                }
                room_manager.send_message_raw(del_msg)
                return {"status": "success", "message": f"Deleted {arg}"}
            return {"status": "error", "message": f"File not found: {arg}"}

        else:
            return {"status": "error", "message": f"Unknown project action: {action}"}
    except Exception as e:
        return {"status": "error", "message": f"Project error: {e}"}
