"""CMS adapter registry — read-only."""
from __future__ import annotations

from typing import Any

from fastapi import Depends
from sqlalchemy import func, select
from sqlalchemy.orm import Session

from govcrawler.models import CrawlSite

from ._common import _session, router


@router.get("/api/adapters")
def adapters(s: Session = Depends(_session)) -> dict[str, Any]:
    """List registered CMS adapter modules + how many sites currently bind each.

    Adapter internals (ADAPTER_ID, docstring, DEFAULT_DETAIL_SELECTORS) come
    from `govcrawler.adapters.ADAPTERS`. Site counts come from the DB so the
    UI can flag unused adapters or orphan `cms_adapter` values.
    """
    from govcrawler.adapters import ADAPTERS

    # count sites bound to each adapter
    rows = s.execute(
        select(CrawlSite.cms_adapter, func.count(CrawlSite.id))
        .where(CrawlSite.cms_adapter.isnot(None))
        .group_by(CrawlSite.cms_adapter)
    ).all()
    bound_counts = {name: int(n) for name, n in rows}

    items = []
    for name, mod in sorted(ADAPTERS.items()):
        doc = (getattr(mod, "__doc__", "") or "").strip()
        # First non-empty line = short description
        summary = next((ln.strip() for ln in doc.splitlines() if ln.strip()), "")
        items.append({
            "adapter_id": name,
            "summary": summary,
            "site_count": bound_counts.pop(name, 0),
            "has_default_selectors": bool(getattr(mod, "DEFAULT_DETAIL_SELECTORS", None)),
        })

    # Any cms_adapter values present in DB but not in the registry → orphans
    orphans = [
        {"adapter_id": name, "site_count": n, "orphan": True}
        for name, n in sorted(bound_counts.items())
    ]
    return {"adapters": items, "orphans": orphans}
