"""
Phase 3A: Global Workspace Specialists

7 Competing Specialists:
1. Memory Retrieval (brain_search results)
2. Prediction Oracle (prediction_alerts.json)
3. DMN Ideation (recent proposals)
4. Reflex Arc (mistake detections)
5. Neural State (session context + recommendations)
6. Working Memory (session buffer)
7. Governance (always-admit)
"""
import json
from pulse.core.paths import get_state_dir
from pulse.brain.memory.working_memory import get_active_contexts
from pulse.brain.workspace.attention import get_attention_weights

class Coalition:
    def __init__(self, source: str, items: list, activation: float):
        self.source = source
        self.items = items[:5]
        self.activation = min(1.0, max(0.0, float(activation)))
        self.access_count: int = 0
        self.reentrant_weight: float = 1.0
        self.last_broadcast_item: dict = {}

    def update(self, items: list, base_activation: float):
        self.items = items[:5]
        self.activation = min(1.0, max(0.0, float(base_activation) * self.reentrant_weight))

    def to_dict(self):
        return {"source": self.source, "activation": self.activation, "items": self.items, "reentrant_weight": self.reentrant_weight}

    def receive_broadcast(self, broadcast_data: dict):
        """Item 59: GWT global broadcast — receive info from workspace."""
        try:
            self.access_count = getattr(self, "access_count", 0) + 1
            self.last_broadcast_item = broadcast_data 
        except Exception:
            pass

    def receive_reentrant(self, item: dict):
        """Item 60: Reentrant signal from GWT — strengthen internal representations."""
        try:
            self.access_count = getattr(self, "access_count", 0) + 1
            self.reentrant_weight = min(2.0, getattr(self, "reentrant_weight", 1.0) + 0.1)
            if hasattr(self, "last_broadcast_item"):  
                self.last_broadcast_item = item       
        except Exception:
            pass

_SPECIALISTS = {}
def get_specialist(source: str) -> Coalition:
    if source not in _SPECIALISTS:
        _SPECIALISTS[source] = Coalition(source, [], 0.0)
    return _SPECIALISTS[source]

def _calc_activation(relevance: float, salience: float, urgency: float, reliability: float) -> float:
    return relevance * min(1.0, salience / 7.0) * urgency * reliability

# 1. Memory Retrieval
def get_memory_coalition(query: str, search_results: dict, task_type: str = "general") -> Coalition:        
    coal = get_specialist("memory")
    if not search_results or not search_results.get("results"):
        coal.update([], 0.0)
        return coal

    weights = get_attention_weights(task_type)        
    best_items = []

    for src, hits in search_results["results"].items():
        weight = weights.get(src, 1.0)
        for hit in hits:
            rel = hit.get("confidence", 0.5)
            sal = hit.get("salience", 1.0)
            act = _calc_activation(rel, sal, 0.5, weight) # baseline urgency 0.5
            hit["_gw_activation"] = act
            best_items.append(hit)

    best_items.sort(key=lambda x: x.get("_gw_activation", 0), reverse=True)
    
    # Item 9: Item-Level Competitive Suppression
    from pulse.brain.workspace.attention import AttentionCompetition
    comp = AttentionCompetition(similarity_threshold=0.8)
    best_items = comp.suppress_redundant(best_items)
    
    top_items = best_items[:5]
    avg_act = sum(i["_gw_activation"] for i in top_items) / len(top_items) if top_items else 0.0

    coal.update(top_items, avg_act)
    return coal

from .specialists_oracle import (
    get_prediction_coalition, get_dmn_coalition, get_reflex_coalition, get_neural_state_coalition,
)
from .specialists_broadcast import (
    get_working_memory_coalition, gwt_broadcast, get_governance_coalition,
)