"""Tavily web search — enrichment layer that finds content outside our feed sources.

Searches per-category interest queries, excluding domains we already have feeds for,
so results are always net-new discoveries.
"""

from __future__ import annotations

import os
import sys
from urllib.parse import urlparse

from platoon.models import Item

# Domains we already cover via RSS, Reddit, Google News, etc.
# Tavily will exclude these so we only get fresh sources.
EXCLUDED_DOMAINS = [
    # Feed sources we already fetch
    "reddit.com",
    "news.google.com",
    "bbc.co.uk", "bbc.com",
    "theverge.com",
    "arstechnica.com",
    "wired.com",
    "space.com",
    "nasa.gov",
    "nature.com",
    "arxiv.org",
    "news.ycombinator.com",
    "lobste.rs",
    "flipboard.com",
    "smithsonianmag.com",
    "atlasobscura.com",
    "eater.com",
    "bonappetit.com",
    "sciencenews.org",
    "newscientist.com",
    "github.com",
    "soompi.com",
    "koreaboo.com",
    "koreatimes.co.kr",
    "koreaherald.com",
    # Major mainstream (too generic, we want niche discoveries)
    "cnn.com",
    "foxnews.com",
    "msn.com",
    "yahoo.com",
    # Social media (not articles)
    "youtube.com",
    "twitter.com", "x.com",
    "facebook.com",
    "instagram.com",
    "tiktok.com",
    "pinterest.com",
    "wikipedia.org",
]


def _get_client(api_key: str | None = None):
    """Get Tavily client, or None if unavailable."""
    key = api_key or os.environ.get("TAVILY_API_KEY", "")
    if not key:
        return None
    try:
        from tavily import TavilyClient
        return TavilyClient(api_key=key)
    except ImportError:
        print("  tavily-python not installed, skipping web search", file=sys.stderr)
        return None


def web_search_enrich(
    categories: dict,
    interests: list[str],
    existing_urls: set[str],
    api_key: str | None = None,
    max_per_category: int = 3,
    time_range: str = "week",
) -> list[Item]:
    """Search the web for each category, excluding known feed domains.

    Args:
        categories: {cat_name: {keywords: [...], ...}} from the profile config
        interests: list of interest phrases from the profile
        existing_urls: set of URLs already fetched (for dedup)
        api_key: Tavily API key
        max_per_category: max results per category search
        time_range: Tavily time range (day, week, month)

    Returns:
        list of Items from web search
    """
    client = _get_client(api_key)
    if not client:
        return []

    # Build a query per category from its keywords + matching interest phrases
    items = []
    existing_domains = {urlparse(u).netloc.lower() for u in existing_urls}

    for cat_name, cat_cfg in categories.items():
        keywords = cat_cfg.get("keywords", [])
        if not keywords:
            continue

        # Build query: top 4 keywords + any matching interest words
        query_parts = keywords[:4]

        # Find interest phrases that overlap with this category
        kw_set = {k.lower() for k in keywords}
        for interest in interests:
            words = set(interest.lower().split())
            if words & kw_set:
                query_parts.append(interest)
                break

        query = " ".join(query_parts[:6])
        print(f"  Web search [{cat_name}]: {query[:50]}...")

        try:
            response = client.search(
                query=query,
                max_results=max_per_category + 2,  # over-fetch to handle filtering
                topic="news",
                time_range=time_range,
                exclude_domains=EXCLUDED_DOMAINS,
            )
        except Exception as e:
            print(f"    Search error: {e}", file=sys.stderr)
            continue

        count = 0
        for r in response.get("results", []):
            if count >= max_per_category:
                break
            url = r.get("url", "")
            domain = urlparse(url).netloc.lower()

            # Skip if we already have this URL or domain is in feeds
            if url in existing_urls:
                continue
            if domain in existing_domains:
                continue

            title = r.get("title", "")
            content = r.get("content", "")

            items.append(Item(
                title=title,
                url=url,
                source=f"Web Search",
                summary=content[:400],
                tags=[cat_name, "web"],
            ))
            count += 1

        print(f"    -> {count} new items")

    return items
