"""Direct statute lookup, list, and chapter tree."""

import re

from ars25.core.db import get_table, table_exists
from ars25.models.statute import StatuteInfo

SECTION_PATTERN = re.compile(r"^25-\d+(\.\d+)?$")


def sanitize_section(raw: str) -> str | None:
    """Validate and clean a section reference. Returns None if invalid."""
    cleaned = raw.strip().lstrip("§").replace("A.R.S.", "").replace("ARS", "").strip()
    # Remove any surrounding whitespace or dots
    cleaned = cleaned.strip(". ")
    return cleaned if SECTION_PATTERN.match(cleaned) else None


def get_statute(section: str) -> dict | None:
    """Retrieve full statute text by section number.

    Returns all chunks concatenated as the full text, plus metadata.
    """
    if not table_exists():
        return None

    clean = sanitize_section(section)
    if not clean:
        return None

    table = get_table()
    rows = (
        table.search()
        .where(f"section = '{clean}'")
        .limit(100)
        .to_list()
    )

    if not rows:
        return None

    # Sort by chunk_index and concatenate text
    rows.sort(key=lambda r: r["chunk_index"])
    full_text = "\n\n".join(r["text"] for r in rows)

    first = rows[0]
    return {
        "section": first["section"],
        "title": first["title"],
        "chapter": f"Ch. {first['chapter_number']}: {first['chapter_title']}",
        "article": f"Art. {first['article_number']}: {first['article_title']}",
        "url": first["url"],
        "text": full_text,
        "chunk_count": len(rows),
    }


def list_statutes(
    chapter: int | None = None,
    article: int | None = None,
) -> list[dict]:
    """List all statute sections/titles, optionally filtered."""
    if not table_exists():
        return []

    table = get_table()

    # Build filter
    filters: list[str] = []
    if chapter is not None:
        filters.append(f"chapter_number = {int(chapter)}")
    if article is not None:
        filters.append(f"article_number = {int(article)}")

    builder = table.search()
    if filters:
        builder = builder.where(" AND ".join(filters))
    rows = builder.select(
        ["section", "title", "chapter_number", "chapter_title",
         "article_number", "article_title"]
    ).limit(5000).to_list()

    # Deduplicate by section (multiple chunks per statute)
    seen: dict[str, StatuteInfo] = {}
    for row in rows:
        sec = row["section"]
        if sec not in seen:
            seen[sec] = StatuteInfo(
                section=sec,
                title=row["title"],
                chapter_number=row["chapter_number"],
                chapter_title=row["chapter_title"],
                article_number=row["article_number"],
                article_title=row["article_title"],
            )

    # Sort by section number
    sorted_statutes = sorted(
        seen.values(),
        key=lambda s: _section_sort_key(s.section),
    )
    return [s.to_dict() for s in sorted_statutes]


def get_chapter_tree() -> list[dict]:
    """Build hierarchical chapter → article → statute structure."""
    if not table_exists():
        return []

    all_statutes = list_statutes()

    chapters: dict[int, dict] = {}
    for s in all_statutes:
        # Parse chapter/article from formatted strings
        ch_parts = s["chapter"].split(": ", 1)
        ch_num = int(ch_parts[0].replace("Ch. ", ""))
        ch_title = ch_parts[1] if len(ch_parts) > 1 else ""

        art_parts = s["article"].split(": ", 1)
        art_num = int(art_parts[0].replace("Art. ", ""))
        art_title = art_parts[1] if len(art_parts) > 1 else ""

        if ch_num not in chapters:
            chapters[ch_num] = {
                "chapter_number": ch_num,
                "chapter_title": ch_title,
                "articles": {},
            }

        chapter = chapters[ch_num]
        if art_num not in chapter["articles"]:
            chapter["articles"][art_num] = {
                "article_number": art_num,
                "article_title": art_title,
                "statutes": [],
            }

        chapter["articles"][art_num]["statutes"].append({
            "section": s["section"],
            "title": s["title"],
        })

    # Convert to sorted list
    result = []
    for ch_num in sorted(chapters.keys()):
        ch = chapters[ch_num]
        articles = []
        for art_num in sorted(ch["articles"].keys()):
            art = ch["articles"][art_num]
            articles.append({
                "article_number": art["article_number"],
                "article_title": art["article_title"],
                "statute_count": len(art["statutes"]),
                "statutes": art["statutes"],
            })
        result.append({
            "chapter_number": ch["chapter_number"],
            "chapter_title": ch["chapter_title"],
            "article_count": len(articles),
            "articles": articles,
        })

    return result


def _section_sort_key(section: str) -> tuple[int, int]:
    """Convert '25-403.01' → (403, 1) for sorting."""
    parts = section.split("-", 1)
    if len(parts) < 2:
        return (0, 0)
    num_str = parts[1]
    if "." in num_str:
        major, minor = num_str.split(".", 1)
        return (int(major), int(minor))
    return (int(num_str), 0)
