"""
Phase 102: The Swarm Feedback Loop

This module serves as the connective tissue between the Execution Layer (Swarm, ERP, Tasks)
and the Learning Layer (Hive Mind, Decision Memory). It reads completed task artifacts
and automatically distills them into permanent, queryable knowledge to make future
operations cheaper, faster, and more accurate.
"""

import json
import logging
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional, List, Dict

logger = logging.getLogger("brynq.feedback_loop")

# Attempt imports gracefully to support both shelled and future locations
try:
    from brynq.decentralized_memory import KnowledgeStore
except ImportError:
    try:
        from brynq._future.decentralized_memory import KnowledgeStore
    except ImportError:
        KnowledgeStore = None

try:
    from brynq.erp import get_cost_report
except ImportError:
    try:
        from brynq._future.erp import get_cost_report
    except ImportError:
        get_cost_report = lambda *args: {}

# A simple local file for tracking strategy performance (the beginnings of Decision Memory)
STRATEGY_MEMORY_FILE = Path("state/broker/routing/strategy_memory.jsonl")

def _ensure_dir(path: Path):
    path.parent.mkdir(parents=True, exist_ok=True)


def on_swarm_complete(session_id: str, task_dict: dict, erp_data: dict = None) -> None:
    """
    Channel 1: Outcome Learning.
    Extract what worked from a completed swarm task and record it to Decision Memory.
    """
    _ensure_dir(STRATEGY_MEMORY_FILE)
    
    # Calculate simple performance metrics
    success = task_dict.get("status") == "completed"
    elapsed = 0.0
    if task_dict.get("completed_at") and task_dict.get("accepted_at"):
        try:
            t1 = datetime.fromisoformat(task_dict["accepted_at"])
            t2 = datetime.fromisoformat(task_dict["completed_at"])
            elapsed = (t2 - t1).total_seconds()
        except:
            pass
            
    # Record the literal outcome to the strategy ledger
    outcome_record = {
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "session_id": session_id,
        "task_id": task_dict.get("task_id"),
        "task_title": task_dict.get("title", ""),
        "task_description": task_dict.get("description", ""),
        "agent_name": task_dict.get("assignee_name", "unknown"),
        "success": success,
        "elapsed_seconds": elapsed,
        "tokens_spent": erp_data.get("actual_tokens", 0) if erp_data else 0,
        "cost_usd": erp_data.get("actual_cost_usd", 0.0) if erp_data else 0.0,
        "result_length": len(task_dict.get("result", "")) if task_dict.get("result") else 0
    }
    
    with open(STRATEGY_MEMORY_FILE, "a", encoding="utf-8") as f:
        f.write(json.dumps(outcome_record) + "\n")
        
    logger.info(f"Feedback Loop: Recorded outcome for task {task_dict.get('task_id')}")

    # Channel 3: Knowledge Distillation
    # If this was a high-quality success, permanently distill the result into the Hive Mind
    if success and KnowledgeStore:
        result_text = task_dict.get("result", "")
        # Very rough heuristic: if the result is substantial and took time, it's worth remembering
        if len(result_text) > 500 and elapsed > 10:
            store = KnowledgeStore()
            store.publish(
                content=f"Solution for '{task_dict.get('title')}': {result_text[:2000]}",
                author=task_dict.get("assignee_name", "swarm_consensus"),
                tags=["distilled_knowledge", "swarm_consensus", task_dict.get("channel", "general")],
                importance=8.0 # High importance because it cost compute to generate
            )
            logger.info(f"Feedback Loop: Distilled task {task_dict.get('task_id')} into Hive Mind.")


def run_feedback_cycle() -> dict:
    """
    Channel 2: Strategy Evolution.
    Called automatically at 3 AM by Oroboros/Watchdog. 
    Analyzes all past outcomes to promote winning strategies to preferences.
    """
    if not STRATEGY_MEMORY_FILE.exists():
        return {"status": "no_data"}
        
    lines = STRATEGY_MEMORY_FILE.read_text(encoding="utf-8").strip().splitlines()
    records = [json.loads(line) for line in lines if line.strip()]
    
    if not records:
        return {"status": "empty"}
        
    # Analyze who is the most cost-effective agent for frontend vs backend tasks
    frontend_successes = [r for r in records if "frontend" in r["task_title"].lower() or "ui" in r["task_title"].lower() and r["success"]]
    backend_successes = [r for r in records if "backend" in r["task_title"].lower() or "api" in r["task_title"].lower() and r["success"]]
    
    # In a full implementation, this would update `state/broker/routing/smart_rules.json`
    # For now, we just log the insight to the Hive Mind
    if KnowledgeStore and frontend_successes:
        # Find agent with lowest avg cost for frontend
        agent_costs = {}
        for r in frontend_successes:
            agent = r["agent_name"]
            if agent not in agent_costs:
                agent_costs[agent] = []
            agent_costs[agent].append(r["cost_usd"])
            
        if agent_costs:
            best_agent = min(agent_costs, key=lambda k: sum(agent_costs[k])/len(agent_costs[k]))
            store = KnowledgeStore()
            store.publish(
                content=f"STRATEGY EVOLUTION: Agent '{best_agent}' has the highest ROI for frontend/UI tasks based on historical Swarm data.",
                author="System Feedback Loop",
                tags=["strategy", "evolution"],
                importance=9.0
            )
            
    return {"status": "completed", "records_analyzed": len(records)}
