"""Gap analysis data access functions."""
from __future__ import annotations

import re

from ietf_analyzer.db import Database


def get_all_gaps(db: Database) -> list[dict]:
    """Return all gap analysis results, sorted by severity (critical first)."""
    _sev_order = {"critical": 0, "high": 1, "medium": 2, "low": 3}
    gaps = db.all_gaps()
    gaps.sort(key=lambda g: _sev_order.get(g.get("severity", "low"), 99))
    return gaps

def get_gap_detail(db: Database, gap_id: int) -> dict | None:
    """Return a single gap by ID, or None if not found."""
    gaps = db.all_gaps()
    for g in gaps:
        if g["id"] == gap_id:
            return g
    return None

def get_drafts_for_gap(db: Database, gap_id: int) -> list[dict]:
    """Find drafts related to a gap by searching evidence for draft names
    and searching draft titles/abstracts for gap topic keywords."""
    gap = get_gap_detail(db, gap_id)
    if not gap:
        return []

    found_names: set[str] = set()

    # 1. Extract draft names mentioned in evidence text
    evidence = gap.get("evidence", "") or ""
    # Match draft-xxx-yyy-zzz patterns
    draft_refs = re.findall(r'draft-[\w-]+', evidence)
    found_names.update(draft_refs)

    # 2. Search drafts by gap topic keywords
    topic = gap.get("topic", "")
    # Extract meaningful keywords (3+ chars, skip common words)
    stopwords = {"the", "and", "for", "with", "from", "that", "this", "are", "was",
                 "not", "but", "have", "has", "had", "will", "can", "all", "each",
                 "which", "their", "been", "into", "more", "other", "some", "than",
                 "may", "its", "also", "between", "should", "would", "could", "does"}
    words = [w.lower() for w in re.findall(r'[A-Za-z]{3,}', topic) if w.lower() not in stopwords]

    # Search for drafts matching topic keywords
    if words:
        # Use the most specific keywords (longer words first)
        keywords = sorted(words, key=len, reverse=True)[:3]
        for kw in keywords:
            like = f"%{kw}%"
            rows = db.conn.execute(
                """SELECT name FROM drafts
                WHERE title LIKE ? OR abstract LIKE ?
                LIMIT 20""",
                (like, like),
            ).fetchall()
            for r in rows:
                found_names.add(r["name"])

    if not found_names:
        return []

    # Fetch draft details + ratings
    drafts_map = db.get_drafts_by_names(list(found_names))
    rated = db.drafts_with_ratings(limit=2000)
    rating_map = {d.name: r for d, r in rated}

    results = []
    for name in sorted(found_names):
        d = drafts_map.get(name)
        if not d:
            continue
        r = rating_map.get(name)
        results.append({
            "name": d.name,
            "title": d.title,
            "date": d.date,
            "score": round(r.composite_score, 2) if r else None,
            "categories": r.categories if r else [],
        })

    # Sort by score descending
    results.sort(key=lambda x: x.get("score") or 0, reverse=True)
    return results
