"""Versioned record BFF adapter for every Pages starter (Nuxt, React, HTML)."""
from __future__ import annotations

from pathlib import Path

from src.domain.codegen.local_backup import move_to_bak

_PAGES_TYPES = frozenset({"html", "react_app", "nuxt_app"})
BACKUP_SUFFIX = ".p2hs-local.bak"
ADAPTER_MARKER = "p2hs-records"

_LOCAL_RECORD_ROUTES = (
    "functions/_lib/p2hs-records.mjs",
    "functions/api/records/[[path]].js",
    "functions/api/records.js",
    "server/utils/p2hs-records.mjs",
    "server/api/records/[...path].ts",
    "server/api/records.ts",
    "server/api/records/index.ts",
)


def record_adapter_files(project_type: str) -> dict[str, str]:
    if project_type not in _PAGES_TYPES:
        return {}
    root = Path(__file__).with_name("runtime")
    shared = (root / "p2hs-records.mjs").read_text(encoding="utf-8")
    files = {
        "functions/_lib/p2hs-records.mjs": shared,
        "functions/api/records/[[path]].js": (root / "records-pages-fn.js").read_text(
            encoding="utf-8"
        ),
    }
    if project_type == "nuxt_app":
        files["server/utils/p2hs-records.mjs"] = shared
        files["server/api/records/[...path].ts"] = (
            root / "records-route.ts"
        ).read_text(encoding="utf-8")
    return files


def _is_platform_adapter(path: Path) -> bool:
    try:
        return ADAPTER_MARKER in path.read_text(encoding="utf-8")
    except OSError:
        return False


def backup_local_record_routes(repo_path: str) -> list[str]:
    root = Path(repo_path)
    backed: list[str] = []
    seen: set[Path] = set()
    candidates = [root / rel for rel in _LOCAL_RECORD_ROUTES]
    for directory in (root / "server/api/records", root / "functions/api/records"):
        if directory.is_dir():
            candidates.extend(
                path
                for path in directory.rglob("*")
                if path.suffix in {".ts", ".js"} and path.is_file()
            )
    for path in candidates:
        resolved = path.resolve()
        if resolved in seen or not path.is_file() or _is_platform_adapter(path):
            continue
        seen.add(resolved)
        dest = move_to_bak(root, path.relative_to(root).as_posix())
        backed.append(dest)
    return backed


def install_record_adapter(
    repo_path: str,
    project_type: str,
    *,
    replace_local: bool = False,
) -> dict[str, list[str]]:
    written: list[str] = []
    skipped: list[str] = []
    backed = backup_local_record_routes(repo_path) if replace_local else []
    for name, content in record_adapter_files(project_type).items():
        path = Path(repo_path) / name
        if path.exists() and not replace_local and not _is_platform_adapter(path):
            skipped.append(name)
            continue
        path.parent.mkdir(parents=True, exist_ok=True)
        path.write_text(content, encoding="utf-8", newline="\n")
        written.append(name)
    return {"written": written, "backed_up": backed, "skipped": skipped}


def platform_adapter_files(project_type: str, context: dict | None = None) -> dict[str, str]:
    from src.domain.codegen.port_adapter import catalog_adapter_files

    return catalog_adapter_files(project_type, context)
