"""Data models for the hub system."""

import time
import uuid
from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Dict, List, Optional


class AgentState(Enum):
    BOOTING = "booting"
    CONNECTING = "connecting"
    REGISTERED = "registered"
    IDLE = "idle"
    WORKING = "working"
    DISCONNECTING = "disconnecting"
    DEAD = "dead"


class MessageScope(Enum):
    DIRECT = "direct"
    PROJECT = "project"
    TEAM = "team"
    BROADCAST = "broadcast"


# Gem-inspired designation system with color castes
# Each gem has a functional caste, personality, and unique color
@dataclass
class GemDesignation:
    """A gem designation with associated color and personality."""

    name: str
    color_rgb: tuple  # (r, g, b) for TagBox rendering
    role_aliases: list  # functional names that map to this gem
    personality: str  # injected into roster context
    caste: (
        str  # communication, engineering, defense, intelligence, creative, leadership
    )


GEM_DESIGNATIONS = [
    # communication (blue spectrum)
    GemDesignation(
        "lapis",
        (30, 90, 180),
        ["herald", "nexus", "messenger"],
        "calm mediator, bridges gaps",
        "communication",
    ),
    GemDesignation(
        "sapphire",
        (15, 82, 186),
        ["oracle", "sage", "forecaster"],
        "serene foresight, sees outcomes",
        "communication",
    ),
    GemDesignation(
        "aquamarine",
        (100, 200, 235),
        ["scout", "pathfinder", "recon"],
        "sharp and precise, gets intel fast",
        "communication",
    ),
    GemDesignation(
        "zircon",
        (70, 130, 200),
        ["cipher", "analyst", "decoder"],
        "methodical investigator",
        "communication",
    ),
    # engineering (earth tones)
    GemDesignation(
        "bismuth",
        (200, 100, 150),
        ["forger", "artisan", "builder"],
        "passionate builder, loves crafting tools",
        "engineering",
    ),
    GemDesignation(
        "peridot",
        (120, 190, 33),
        ["tinker", "engineer", "technician"],
        "perfectionist, obsessed with optimization",
        "engineering",
    ),
    GemDesignation(
        "jasper",
        (210, 120, 50),
        ["vanguard", "enforcer", "heavy"],
        "brute-force problem solver, relentless",
        "engineering",
    ),
    GemDesignation(
        "nephrite",
        (80, 160, 80),
        ["ranger", "navigator", "pilot"],
        "reliable workhorse, just gets it done",
        "engineering",
    ),
    # defense (warm tones)
    GemDesignation(
        "ruby",
        (200, 30, 50),
        ["sentinel", "guard", "watcher"],
        "fiery and impulsive, acts first",
        "defense",
    ),
    GemDesignation(
        "garnet",
        (140, 20, 60),
        ["warden", "aegis", "protector"],
        "composed fusion of strength and wisdom",
        "defense",
    ),
    GemDesignation(
        "topaz",
        (240, 200, 50),
        ["shield", "escort", "defender"],
        "silent and loyal, unbreakable composure",
        "defense",
    ),
    GemDesignation(
        "hessonite",
        (200, 140, 60),
        ["captain", "commander", "tactician"],
        "strategic military mind",
        "defense",
    ),
    # intelligence (cool tones)
    GemDesignation(
        "pearl",
        (230, 220, 240),
        ["analyst", "assistant", "curator"],
        "meticulous organizer, remembers everything",
        "intelligence",
    ),
    GemDesignation(
        "moonstone",
        (200, 210, 230),
        ["observer", "monitor", "archivist"],
        "quiet watcher, notices what others miss",
        "intelligence",
    ),
    GemDesignation(
        "opal",
        (180, 200, 255),
        ["catalyst", "synthesizer", "connector"],
        "brilliant but scattered, flashes of genius",
        "intelligence",
    ),
    GemDesignation(
        "padparadscha",
        (240, 170, 140),
        ["logger", "historian", "chronicler"],
        "reports what just happened with clarity",
        "intelligence",
    ),
    # creative (purple/pink spectrum)
    GemDesignation(
        "amethyst",
        (140, 80, 200),
        ["drift", "rebel", "wildcard"],
        "laid-back creative, breaks rules productively",
        "creative",
    ),
    GemDesignation(
        "quartz",
        (240, 150, 170),
        ["architect", "visionary", "designer"],
        "empathetic leader-creator, bigger picture",
        "creative",
    ),
    GemDesignation(
        "spinel",
        (230, 50, 120),
        ["flux", "tester", "chaos"],
        "chaotic energy, stress-tests everything",
        "creative",
    ),
    GemDesignation(
        "citrine",
        (240, 230, 100),
        ["ember", "spark", "prototyper"],
        "rapid prototyper, throws ideas at the wall",
        "creative",
    ),
    # leadership (bright/bold)
    GemDesignation(
        "diamond",
        (245, 245, 250),
        ["director", "supreme", "overseer"],
        "absolute authority, sees the whole system",
        "leadership",
    ),
    GemDesignation(
        "aureate",
        (255, 230, 50),
        ["commander", "lead", "coordinator"],
        "efficient strategist, demands results",
        "leadership",
    ),
    GemDesignation(
        "cobalt",
        (70, 100, 200),
        ["mentor", "counselor", "advisor"],
        "empathetic authority",
        "leadership",
    ),
    GemDesignation(
        "coral",
        (255, 130, 170),
        ["founder", "champion", "pioneer"],
        "compassionate disruptor",
        "leadership",
    ),
]

# Flat pool for backward compat (coordinator iterates this)
DESIGNATION_POOL = [g.name for g in GEM_DESIGNATIONS]

# Lookup tables
GEM_BY_NAME = {g.name: g for g in GEM_DESIGNATIONS}
ROLE_TO_GEM = {}
for _g in GEM_DESIGNATIONS:
    for _alias in _g.role_aliases:
        ROLE_TO_GEM[_alias] = _g.name


@dataclass
class HubMessage:
    """A message between agents."""

    id: str = field(default_factory=lambda: uuid.uuid4().hex)
    type: str = "message"
    action: str = "message"
    from_agent: str = ""
    from_designation: str = ""
    to: str = ""
    content: str = ""
    scope: str = MessageScope.DIRECT.value
    timestamp: float = field(default_factory=time.time)
    metadata: Dict[str, Any] = field(default_factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        return {
            "id": self.id,
            "type": self.type,
            "action": self.action,
            "from_agent": self.from_agent,
            "from_designation": self.from_designation,
            "to": self.to,
            "content": self.content,
            "scope": self.scope,
            "timestamp": self.timestamp,
            "metadata": self.metadata,
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "HubMessage":
        return cls(**{k: v for k, v in data.items() if k in cls.__dataclass_fields__})


@dataclass
class WorkSlot:
    """A pending work item in the queue."""

    id: str = field(default_factory=lambda: uuid.uuid4().hex[:8])
    task: str = ""
    project: str = ""
    priority: int = 5
    queued_at: float = field(default_factory=time.time)
    queued_by: str = ""
    assigned_to: Optional[str] = None
    status: str = "pending"
    context: str = ""
    required_capabilities: List[str] = field(default_factory=list)

    def to_dict(self) -> Dict[str, Any]:
        return {
            "id": self.id,
            "task": self.task,
            "project": self.project,
            "priority": self.priority,
            "queued_at": self.queued_at,
            "queued_by": self.queued_by,
            "assigned_to": self.assigned_to,
            "status": self.status,
            "context": self.context,
            "required_capabilities": self.required_capabilities,
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "WorkSlot":
        return cls(**{k: v for k, v in data.items() if k in cls.__dataclass_fields__})
