"""
Local insights client
Fetches network insights and compares local usage against the network.
"""
import json
import time
from pathlib import Path
from typing import Dict, Any, List
import urllib.request
from runtime.learning.usage_tracker import UsageTracker

class NetworkInsights:
    def __init__(self, data_dir: Path, cloud_url: str = "http://localhost:8000"):
        self.data_dir = data_dir
        self.cache_file = self.data_dir / "network_cache.json"
        self.cloud_url = cloud_url

    def _read_cache(self) -> Dict[str, Any]:
        if not self.cache_file.exists():
            return {}
        try:
            return json.loads(self.cache_file.read_text("utf-8"))
        except:
            return {}

    def _write_cache(self, data: Dict[str, Any]):
        self.cache_file.write_text(json.dumps(data, indent=2), "utf-8")

    def is_cache_fresh(self, cache_key: str, max_age_hours: int = 24) -> bool:
        cache = self._read_cache()
        entry = cache.get(cache_key)
        if not entry:
            return False
        return (time.time() - entry.get("timestamp", 0)) < (max_age_hours * 3600)

    def get_cached(self, cache_key: str) -> Dict[str, Any] | None:
        if self.is_cache_fresh(cache_key):
            return self._read_cache()[cache_key]["data"]
        return None

    def fetch_insights(self) -> Dict[str, Any]:
        cached = self.get_cached("insights")
        if cached:
            return cached
            
        try:
            req = urllib.request.Request(f"{self.cloud_url}/v1/network/insights")
            with urllib.request.urlopen(req, timeout=5) as resp:
                data = json.loads(resp.read().decode("utf-8"))
                
            cache = self._read_cache()
            cache["insights"] = {"timestamp": time.time(), "data": data}
            self._write_cache(cache)
            return data
        except Exception:
            return {}

    def fetch_model_stats(self) -> Dict[str, Any]:
        cached = self.get_cached("model_stats")
        if cached:
            return cached
            
        try:
            req = urllib.request.Request(f"{self.cloud_url}/v1/network/model-stats")
            with urllib.request.urlopen(req, timeout=5) as resp:
                data = json.loads(resp.read().decode("utf-8"))
                
            cache = self._read_cache()
            cache["model_stats"] = {"timestamp": time.time(), "data": data}
            self._write_cache(cache)
            return data
        except Exception:
            return {}

    def display_insights(self) -> str:
        insights = self.fetch_insights()
        if not insights:
            return "No network insights available."
            
        lines = []
        lines.append("--- Network Insights ---")
        lines.append(f"Most Popular Model: {insights.get('most_popular_model', 'N/A')}")
        lines.append(f"Fastest Model: {insights.get('fastest_model', 'N/A')}")
        lines.append(f"Trending Strategy: {insights.get('trending_strategy', 'N/A')}")
        lines.append(f"Recommendation: {insights.get('recommendation', 'N/A')}")
        return "\n".join(lines)

    def factor_into_model_selection(self, candidates: List[str]) -> List[str]:
        stats = self.fetch_model_stats()
        pop = stats.get("model_popularity", {})
        # Sort by popularity descending
        return sorted(candidates, key=lambda m: pop.get(m, 0), reverse=True)

    def network_vs_local(self, tracker: UsageTracker) -> Dict[str, Any]:
        net_stats = self.fetch_model_stats()
        net_pop = net_stats.get("model_popularity", {})
        net_lat = net_stats.get("avg_latency_by_model", {})
        
        loc_models = tracker.top_models(days=30, limit=100)
        loc_pop = {m["model"]: m["count"] for m in loc_models}
        loc_lat = {m["model"]: m["avg_latency_ms"] for m in loc_models}
        
        # very simple alignment score
        alignment = 0.0
        if net_pop and loc_pop:
            net_top = set(sorted(net_pop.keys(), key=lambda k: net_pop[k], reverse=True)[:3])
            loc_top = set(sorted(loc_pop.keys(), key=lambda k: loc_pop[k], reverse=True)[:3])
            alignment = len(net_top.intersection(loc_top)) / 3.0
            
        faster = []
        slower = []
        for m, ms in loc_lat.items():
            if m in net_lat:
                if ms < net_lat[m] * 0.9:
                    faster.append(m)
                elif ms > net_lat[m] * 1.1:
                    slower.append(m)
                    
        return {
            "model_alignment": alignment,
            "faster_than_avg": faster,
            "slower_than_avg": slower
        }

    def browse_community_templates(self, page: int = 1, sort: str = "popular") -> Dict[str, Any]:
        try:
            req = urllib.request.Request(f"{self.cloud_url}/v1/community/templates?page={page}&sort={sort}")
            with urllib.request.urlopen(req, timeout=5) as resp:
                return json.loads(resp.read().decode("utf-8"))
        except Exception:
            return {"templates": [], "total": 0, "page": page, "pages": 0}

    def fetch_leaderboard(self, task_type: str | None = None) -> List[Dict[str, Any]]:
        cached = self.get_cached(f"leaderboard_{task_type}")
        if cached:
            return cached
            
        try:
            url = f"{self.cloud_url}/v1/leaderboard"
            if task_type:
                url += f"?task_type={task_type}"
            req = urllib.request.Request(url)
            with urllib.request.urlopen(req, timeout=5) as resp:
                data = json.loads(resp.read().decode("utf-8"))
                
            cache = self._read_cache()
            cache[f"leaderboard_{task_type}"] = {"timestamp": time.time(), "data": data}
            self._write_cache(cache)
            return data
        except Exception:
            return []

    def discover_agents(self, category: str | None = None) -> List[Dict[str, Any]]:
        try:
            url = f"{self.cloud_url}/v1/discover"
            if category:
                url += f"?category={category}"
            req = urllib.request.Request(url)
            with urllib.request.urlopen(req, timeout=5) as resp:
                return json.loads(resp.read().decode("utf-8"))
        except Exception:
            return []
