from __future__ import annotations

import json
import re
from dataclasses import dataclass


@dataclass(slots=True)
class PlanUnitHint:
    doc_type: str = ""
    doc_id: str = ""
    application: str = ""
    platform: str = ""
    page_type: str = ""
    path: str = ""


def parse_plan_hints(raw: str, allowed_doc_types: tuple[str, ...]) -> dict[int, PlanUnitHint]:
    try:
        data = json.loads(str(raw or "").strip())
    except json.JSONDecodeError:
        return {}
    rows = data.get("items") if isinstance(data, dict) else []
    if not isinstance(rows, list):
        return {}
    result: dict[int, PlanUnitHint] = {}
    for row in rows:
        if not isinstance(row, dict):
            continue
        index = row.get("index")
        if not isinstance(index, int):
            continue
        doc_type = str(row.get("doc_type") or "").strip()
        result[index] = PlanUnitHint(
            doc_type=doc_type if doc_type in allowed_doc_types else "",
            doc_id=str(row.get("id") or "").strip(),
            application=str(row.get("application") or "").strip(),
            platform=str(row.get("platform") or "").strip().lower(),
            page_type=str(row.get("page_type") or "").strip(),
            path=str(row.get("path") or "").strip(),
        )
    return result


def page_type_for_doc_type(doc_type: str, doc_type_to_folder: dict[str, str]) -> str:
    if doc_type == "index_page":
        return "index"
    folder = doc_type_to_folder.get(doc_type, "docs")
    parts = folder.split("/")
    return parts[-1] if parts else "docs"


def normalize_inferred_path(inferred_path: str, unit_id: str) -> str:
    path = str(inferred_path or "").strip()
    if not path or not path.startswith("docs/"):
        return ""
    if not path.endswith(f"/{unit_id}.md"):
        return ""
    return path


def normalize_path_segment(value: str) -> str:
    cleaned = re.sub(r"[^a-zA-Z0-9._-]+", "-", str(value or "").strip().lower()).strip("-")
    return re.sub(r"-+", "-", cleaned) or "unknown"
