"""
Pre-Game Chatter Module for Luke.

Pulls headlines, injury news, and betting buzz from RSS feeds
and free sports news sources. Filters for teams in the matchup
so Bill gets relevant context alongside his strategy picks.

Sources:
  - ESPN (NHL, Soccer, NFL)
  - TSN (Canadian — Bill's home turf)
  - BBC Sport (Football + General)
  - Sportsnet (NHL/Canadian sports)
  - Sky Sports (Football)
  - The Guardian (Football)
  - Goal.com (Global football)

No API key required — pure RSS.
"""

import logging
import requests
import re
import xml.etree.ElementTree as ET
from datetime import datetime, timedelta

logger = logging.getLogger("pregame-chatter")

# ── RSS Feed Sources ─────────────────────────────────────────

RSS_FEEDS = {
    "nhl": [
        {"name": "ESPN NHL", "url": "https://www.espn.com/espn/rss/nhl/news"},
        {"name": "TSN Hockey", "url": "https://www.tsn.ca/rss/hockey"},
        {"name": "Sportsnet NHL", "url": "https://www.sportsnet.ca/hockey/nhl/feed/"},
        {"name": "BBC Sport", "url": "https://feeds.bbci.co.uk/sport/rss.xml"},
    ],
    "nfl": [
        {"name": "ESPN NFL", "url": "https://www.espn.com/espn/rss/nfl/news"},
        {"name": "TSN NFL", "url": "https://www.tsn.ca/rss/nfl"},
    ],
    "soccer": [
        {"name": "ESPN FC", "url": "https://www.espn.com/espn/rss/soccer/news"},
        {"name": "BBC Football", "url": "https://feeds.bbci.co.uk/sport/football/rss.xml"},
        {"name": "TSN Soccer", "url": "https://www.tsn.ca/rss/soccer"},
        {"name": "Sky Sports Football", "url": "https://www.skysports.com/rss/11095"},
        {"name": "The Guardian Football", "url": "https://www.theguardian.com/football/rss"},
        {"name": "Goal.com", "url": "http://www.goal.com/en/feeds/news?fmt=rss"},
    ],
    "mls": [
        {"name": "ESPN FC", "url": "https://www.espn.com/espn/rss/soccer/news"},
        {"name": "Goal.com", "url": "http://www.goal.com/en/feeds/news?fmt=rss"},
        {"name": "BBC Football", "url": "https://feeds.bbci.co.uk/sport/football/rss.xml"},
        {"name": "TSN Soccer", "url": "https://www.tsn.ca/rss/soccer"},
    ],
}

# Map sport keys to feed categories
SPORT_TO_FEED = {
    "nhl": "nhl",
    "nfl": "nfl",
    "epl": "soccer",
    "seriea": "soccer", "serie_a": "soccer",
    "ligue1": "soccer", "ligue_1": "soccer",
    "laliga": "soccer", "la_liga": "soccer",
    "liga_portugal": "soccer",
    "mls": "mls",
    "bundesliga": "soccer",
    "eredivisie": "soccer",
    "ucl": "soccer", "champions_league": "soccer",
    "europa": "soccer", "europa_league": "soccer",
    "conference": "soccer", "conference_league": "soccer",
}

# Team name fragments for matching in headlines
# Shorter forms that are likely to appear in news headlines
TEAM_SEARCH_NAMES = {
    # NHL — last names / common headline forms
    "Montreal Canadiens": ["canadiens", "habs", "montreal"],
    "Toronto Maple Leafs": ["maple leafs", "leafs", "toronto"],
    "Ottawa Senators": ["senators", "sens", "ottawa"],
    "Boston Bruins": ["bruins", "boston"],
    "New York Rangers": ["rangers"],
    "Pittsburgh Penguins": ["penguins", "pens", "pittsburgh"],
    "Edmonton Oilers": ["oilers", "edmonton"],
    "Calgary Flames": ["flames", "calgary"],
    "Winnipeg Jets": ["jets", "winnipeg"],
    "Vancouver Canucks": ["canucks", "vancouver"],
    "Tampa Bay Lightning": ["lightning", "tampa bay"],
    "Florida Panthers": ["panthers", "florida"],
    "Washington Capitals": ["capitals", "caps", "washington"],
    "Carolina Hurricanes": ["hurricanes", "carolina"],
    "New Jersey Devils": ["devils"],
    "New York Islanders": ["islanders"],
    "Minnesota Wild": ["wild", "minnesota"],
    "Colorado Avalanche": ["avalanche", "avs", "colorado"],
    "Dallas Stars": ["stars", "dallas"],
    "St. Louis Blues": ["blues", "st. louis"],
    "Nashville Predators": ["predators", "preds", "nashville"],
    "Chicago Blackhawks": ["blackhawks", "chicago"],
    "Detroit Red Wings": ["red wings", "detroit"],
    "Buffalo Sabres": ["sabres", "buffalo"],
    "Seattle Kraken": ["kraken", "seattle"],
    "Utah Hockey Club": ["utah"],
    "Anaheim Ducks": ["ducks", "anaheim"],
    "San Jose Sharks": ["sharks", "san jose"],
    "Los Angeles Kings": ["kings", "la kings"],
    "Vegas Golden Knights": ["golden knights", "vegas"],
    "Columbus Blue Jackets": ["blue jackets", "columbus"],
    # EPL
    "Arsenal": ["arsenal", "gunners"],
    "Liverpool": ["liverpool"],
    "Manchester City": ["man city", "manchester city"],
    "Manchester United": ["man united", "manchester united", "man utd"],
    "Chelsea": ["chelsea"],
    "Tottenham Hotspur": ["tottenham", "spurs"],
    "Newcastle United": ["newcastle"],
    "Aston Villa": ["aston villa", "villa"],
    # NFL (abbreviated — add more as needed)
    "Kansas City Chiefs": ["chiefs", "kansas city"],
    "Buffalo Bills": ["bills", "buffalo"],
    "Philadelphia Eagles": ["eagles", "philadelphia"],
    "Dallas Cowboys": ["cowboys", "dallas"],
    "San Francisco 49ers": ["49ers", "san francisco", "niners"],
    "Baltimore Ravens": ["ravens", "baltimore"],
    "Detroit Lions": ["lions", "detroit"],
    "Green Bay Packers": ["packers", "green bay"],
    # European Soccer — top clubs for headline matching
    "AC Milan": ["milan", "ac milan", "rossoneri"],
    "Inter Milan": ["inter", "inter milan", "nerazzurri"],
    "Juventus": ["juventus", "juve"],
    "Napoli": ["napoli"],
    "AS Roma": ["roma"],
    "Lazio": ["lazio"],
    "Atalanta": ["atalanta"],
    "Fiorentina": ["fiorentina"],
    "Paris Saint-Germain": ["psg", "paris saint-germain"],
    "Olympique Marseille": ["marseille", "om"],
    "Lyon": ["lyon", "olympique lyonnais"],
    "Monaco": ["monaco"],
    "Lille": ["lille"],
    "Benfica": ["benfica"],
    "Porto": ["porto"],
    "Sporting CP": ["sporting", "sporting cp", "sporting lisbon"],
    "Braga": ["braga"],
    "Real Madrid": ["real madrid"],
    "Barcelona": ["barcelona", "barca"],
    "Atletico Madrid": ["atletico", "atletico madrid"],
    "Real Sociedad": ["real sociedad", "sociedad"],
    "Athletic Bilbao": ["athletic bilbao", "bilbao"],
    "Villarreal": ["villarreal"],
    "Sevilla": ["sevilla"],
    "Bayern Munich": ["bayern", "bayern munich"],
    "Borussia Dortmund": ["dortmund", "bvb"],
    "RB Leipzig": ["leipzig", "rb leipzig"],
    "Bayer Leverkusen": ["leverkusen", "bayer leverkusen"],
    # MLS
    "CF Montreal": ["cf montreal", "montreal cf", "cf montréal"],
    "Toronto FC": ["toronto fc", "tfc"],
    "Vancouver Whitecaps": ["whitecaps", "vancouver whitecaps"],
    "Inter Miami": ["inter miami"],
    "LAFC": ["lafc", "los angeles fc"],
    "LA Galaxy": ["la galaxy", "galaxy"],
    "New York Red Bulls": ["red bulls", "ny red bulls"],
    "New York City FC": ["nycfc", "new york city fc"],
    "Atlanta United": ["atlanta united"],
    "Seattle Sounders": ["sounders", "seattle sounders"],
    "Portland Timbers": ["timbers", "portland timbers"],
    "Columbus Crew": ["columbus crew", "crew"],
    "Nashville SC": ["nashville sc"],
    "Charlotte FC": ["charlotte fc"],
    "St. Louis City SC": ["st. louis city", "stl city"],
    "Austin FC": ["austin fc"],
    "FC Cincinnati": ["fc cincinnati", "fcc"],
    "Orlando City": ["orlando city"],
    "Houston Dynamo": ["dynamo", "houston dynamo"],
    "Minnesota United": ["minnesota united", "loons"],
    "Real Salt Lake": ["real salt lake", "rsl"],
    "Colorado Rapids": ["rapids", "colorado rapids"],
    "Philadelphia Union": ["union", "philadelphia union"],
    "New England Revolution": ["revolution", "revs", "new england"],
    "Chicago Fire": ["chicago fire"],
    "FC Dallas": ["fc dallas"],
    "Sporting Kansas City": ["sporting kc", "sporting kansas city", "skc"],
    "San Jose Earthquakes": ["earthquakes", "san jose earthquakes"],
    "D.C. United": ["dc united", "d.c. united"],
    "San Diego FC": ["san diego fc"],
}


def _parse_rss_stdlib(content):
    """Parse RSS XML using stdlib xml.etree (no dependencies)."""
    items = []
    try:
        root = ET.fromstring(content)
        # Standard RSS 2.0
        for item in root.iter("item"):
            entry = {}
            title_el = item.find("title")
            desc_el = item.find("description")
            link_el = item.find("link")
            pub_el = item.find("pubDate")

            if title_el is not None and title_el.text:
                entry["title"] = title_el.text.strip()
            if desc_el is not None and desc_el.text:
                # Strip HTML tags from description
                clean = re.sub(r"<[^>]+>", "", desc_el.text)
                entry["summary"] = clean.strip()[:200]
            if link_el is not None and link_el.text:
                entry["link"] = link_el.text.strip()
            if pub_el is not None and pub_el.text:
                entry["published"] = pub_el.text.strip()

            if "title" in entry:
                items.append(entry)
    except ET.ParseError as e:
        logger.warning(f"RSS parse error: {e}")
    return items


def _parse_rss(content):
    """Parse RSS content, preferring feedparser if available."""
    try:
        import feedparser
        feed = feedparser.parse(content)
        items = []
        for entry in feed.entries:
            items.append({
                "title": getattr(entry, "title", ""),
                "summary": getattr(entry, "summary", "")[:200],
                "link": getattr(entry, "link", ""),
                "published": getattr(entry, "published", ""),
            })
        return items
    except ImportError:
        return _parse_rss_stdlib(content)


def _fetch_feed(url, timeout=8):
    """Fetch and parse a single RSS feed."""
    try:
        resp = requests.get(url, timeout=timeout, headers={
            "User-Agent": "Luke-Sports-Agent/1.0"
        })
        if resp.status_code == 200:
            return _parse_rss(resp.text)
        else:
            logger.debug(f"Feed returned {resp.status_code}: {url}")
            return []
    except Exception as e:
        logger.debug(f"Feed fetch failed ({url}): {e}")
        return []


def _matches_team(text, team_name):
    """Check if text mentions a team."""
    if not text:
        return False
    text_lower = text.lower()
    search_names = TEAM_SEARCH_NAMES.get(team_name, [team_name.lower()])
    for name in search_names:
        if name.lower() in text_lower:
            return True
    # Also try the full team name
    if team_name.lower() in text_lower:
        return True
    return False


def get_pregame_chatter(home_team, away_team, sport="nhl", max_items=5):
    """
    Fetch pre-game chatter for a matchup.

    Returns a list of dicts with:
      - title: headline
      - summary: short snippet
      - source: feed name
      - relevance: 'home', 'away', or 'both'

    Sorted by relevance (both > single team).
    """
    feed_category = SPORT_TO_FEED.get(sport, sport)
    feeds = RSS_FEEDS.get(feed_category, [])

    if not feeds:
        logger.debug(f"No RSS feeds configured for sport: {sport}")
        return []

    all_matches = []

    for feed_info in feeds:
        items = _fetch_feed(feed_info["url"])
        for item in items:
            title = item.get("title", "")
            summary = item.get("summary", "")
            combined = f"{title} {summary}"

            home_match = _matches_team(combined, home_team)
            away_match = _matches_team(combined, away_team)

            if home_match or away_match:
                relevance = "both" if (home_match and away_match) else ("home" if home_match else "away")
                all_matches.append({
                    "title": title,
                    "summary": summary,
                    "source": feed_info["name"],
                    "link": item.get("link", ""),
                    "relevance": relevance,
                })

    # Deduplicate by title similarity
    seen_titles = set()
    unique = []
    for m in all_matches:
        # Simple dedup: first 40 chars of lowercase title
        key = m["title"].lower()[:40]
        if key not in seen_titles:
            seen_titles.add(key)
            unique.append(m)

    # Sort: 'both' first, then by source diversity
    unique.sort(key=lambda x: (0 if x["relevance"] == "both" else 1))

    return unique[:max_items]


def format_chatter_for_whatsapp(chatter_items, home_team, away_team):
    """
    Format chatter items into a WhatsApp-friendly text block.
    Returns empty string if no chatter found.
    """
    if not chatter_items:
        return ""

    lines = ["PRE-GAME BUZZ:"]

    for item in chatter_items:
        icon = ""
        if item["relevance"] == "both":
            icon = "H2H"
        elif item["relevance"] == "home":
            # Use last word of team name (e.g., "Leafs", "Arsenal")
            icon = home_team.split()[-1]
        else:
            icon = away_team.split()[-1]

        lines.append(f"  [{icon}] {item['title']}")
        if item.get("summary") and len(item["summary"]) > 20:
            # Truncate summary for WhatsApp readability
            snippet = item["summary"][:120]
            if len(item["summary"]) > 120:
                snippet += "..."
            lines.append(f"    {snippet}")
        lines.append(f"    — {item['source']}")

    return "\n".join(lines)


def get_general_sport_headlines(sport="nhl", max_items=5):
    """
    Get general sport headlines (not filtered by team).
    Useful for the daily slate overview.
    """
    feed_category = SPORT_TO_FEED.get(sport, sport)
    feeds = RSS_FEEDS.get(feed_category, [])

    if not feeds:
        return []

    all_items = []
    for feed_info in feeds:
        items = _fetch_feed(feed_info["url"])
        for item in items:
            all_items.append({
                "title": item.get("title", ""),
                "summary": item.get("summary", "")[:150],
                "source": feed_info["name"],
            })

    # Deduplicate
    seen = set()
    unique = []
    for item in all_items:
        key = item["title"].lower()[:40]
        if key not in seen:
            seen.add(key)
            unique.append(item)

    return unique[:max_items]
