#!/usr/bin/env python3
"""Bell Feed MCP Server — 提供加密推特情報給 Claude Code"""

import json
import time
from datetime import datetime, timezone
from urllib.request import urlopen

from mcp.server.fastmcp import FastMCP

BASE_URL = "https://data.degendar.com"
CACHE_TTL = 300

_cache: dict[str, tuple[float, any]] = {}


def _fetch(filename: str) -> list | dict:
    now = time.time()
    if filename in _cache:
        ts, data = _cache[filename]
        if now - ts < CACHE_TTL:
            return data

    url = f"{BASE_URL}/{filename}"
    with urlopen(url, timeout=15) as resp:
        data = json.loads(resp.read().decode("utf-8"))
    _cache[filename] = (now, data)
    return data


mcp = FastMCP("Bell Feed", json_response=True)


@mcp.tool()
def get_latest_summaries(count: int = 5) -> list[dict]:
    """Get the latest N crypto Twitter summaries from bell notification accounts.

    Returns summaries with: id, timestamp, summary_text, signals, tokens, tweet_count.
    """
    summaries = _fetch("summaries.json")
    results = []
    for s in summaries[:count]:
        results.append({
            "id": s.get("id"),
            "timestamp": s.get("timestamp"),
            "summary_text": s.get("summary_text"),
            "signals": s.get("signals"),
            "tokens": s.get("tokens", []),
            "tweet_count": s.get("tweet_count", 0),
        })
    return results


@mcp.tool()
def get_trending_tokens(hours: int = 24) -> list[dict]:
    """Get trending crypto tokens ranked by mention frequency.

    Analyzes summaries from the past N hours and returns tokens sorted by frequency.
    """
    summaries = _fetch("summaries.json")
    cutoff = datetime.now(timezone.utc).timestamp() - (hours * 3600)

    token_counts: dict[str, int] = {}
    for s in summaries:
        ts_str = s.get("timestamp", "")
        if not ts_str:
            continue
        try:
            ts = datetime.fromisoformat(ts_str).timestamp()
        except ValueError:
            continue
        if ts < cutoff:
            continue
        for token in s.get("tokens", []):
            token_counts[token] = token_counts.get(token, 0) + 1

    ranked = sorted(token_counts.items(), key=lambda x: x[1], reverse=True)
    return [{"token": t, "mentions": c} for t, c in ranked]


@mcp.tool()
def get_daily_tldr() -> dict:
    """Get today's TL;DR summary of crypto Twitter activity."""
    data = _fetch("daily_tldr.json")
    if isinstance(data, dict):
        return data
    return {"error": "No TL;DR available"}


@mcp.tool()
def search_summaries(query: str, max_results: int = 10) -> list[dict]:
    """Search summaries by keyword. Matches against summary text, signals, and tokens."""
    summaries = _fetch("summaries.json")
    query_lower = query.lower()
    results = []

    for s in summaries:
        text = (
            s.get("summary_text", "")
            + " "
            + s.get("signals", "")
            + " "
            + " ".join(s.get("tokens", []))
        ).lower()

        if query_lower in text:
            results.append({
                "id": s.get("id"),
                "timestamp": s.get("timestamp"),
                "summary_text": s.get("summary_text"),
                "signals": s.get("signals"),
                "tokens": s.get("tokens", []),
                "tweet_count": s.get("tweet_count", 0),
            })
            if len(results) >= max_results:
                break

    return results


if __name__ == "__main__":
    mcp.run()
