"""Common utilities for the reference curator pipeline."""

from __future__ import annotations

import hashlib
import logging
import re
import unicodedata
from urllib.parse import urlparse, urlunparse, parse_qs, urlencode


def normalize_url(url: str) -> str:
    """Normalize a URL for deduplication.

    - Lowercase scheme and host
    - Remove trailing slashes
    - Sort query parameters
    - Remove common tracking params (utm_*, ref, fbclid)
    - Remove fragment
    """
    parsed = urlparse(url)
    scheme = parsed.scheme.lower()
    netloc = parsed.netloc.lower()
    path = parsed.path.rstrip("/") or "/"

    # Sort query params, removing tracking params
    tracking_params = {"utm_source", "utm_medium", "utm_campaign", "utm_content",
                       "utm_term", "ref", "fbclid", "gclid", "mc_cid", "mc_eid"}
    params = parse_qs(parsed.query, keep_blank_values=True)
    filtered = {k: v for k, v in sorted(params.items()) if k not in tracking_params}
    query = urlencode(filtered, doseq=True)

    return urlunparse((scheme, netloc, path, "", query, ""))


def url_hash(url: str) -> str:
    """SHA-256 hash of normalized URL. Matches the url_hash column in schema.sql."""
    return hashlib.sha256(normalize_url(url).encode()).hexdigest()


def slugify(text: str) -> str:
    """Convert text to a URL/folder-friendly slug.

    >>> slugify("Prompt Engineering Best Practices")
    'prompt-engineering-best-practices'
    """
    text = unicodedata.normalize("NFKD", text)
    text = text.encode("ascii", "ignore").decode()
    text = text.lower()
    text = re.sub(r"[^a-z0-9]+", "-", text)
    text = text.strip("-")
    return text or "untitled"


def count_tokens(text: str) -> int:
    """Approximate token count using chars/4 heuristic.

    Good enough for compression ratio calculations without requiring tiktoken.
    """
    return max(1, len(text) // 4)


def setup_logging(level: str = "INFO", run_id: int | None = None) -> logging.Logger:
    """Configure and return a logger for the reference curator pipeline."""
    logger = logging.getLogger("refcurator")
    if not logger.handlers:
        handler = logging.StreamHandler()
        fmt = "[refcurator]"
        if run_id:
            fmt += f" [run:{run_id}]"
        fmt += " %(levelname)s: %(message)s"
        handler.setFormatter(logging.Formatter(fmt))
        logger.addHandler(handler)
    logger.setLevel(getattr(logging, level.upper(), logging.INFO))
    return logger
