from __future__ import annotations

import re

from app.core.agent.processes.v2.workflows.doc_update_from_feature.steps.docs_state_loader import DocsState
from app.core.agent.processes.v2.workflows.doc_update_from_feature.steps.plan_hints import (
    normalize_inferred_path,
    normalize_path_segment,
    page_type_for_doc_type,
)

_VALID_PLATFORMS = {"web", "ufs", "pprb"}


class PlanPathPolicy:
    def __init__(self, doc_type_to_folder: dict[str, str]) -> None:
        self._doc_type_to_folder = dict(doc_type_to_folder)

    def make_doc_id(self, *, doc_type: str, heading: str, hinted_doc_id: str) -> str:
        return str(hinted_doc_id or f"{doc_type}.{self._slugify(heading).replace('-', '_')}").strip(".")

    def resolve_path(
        self,
        *,
        doc_type: str,
        unit_id: str,
        application: str,
        platform: str,
        page_type: str,
        inferred_path: str,
        state: DocsState,
    ) -> str:
        if unit_id in state.by_doc_id:
            return state.by_doc_id[unit_id]
        normalized_inferred = normalize_inferred_path(inferred_path, unit_id)
        if normalized_inferred:
            return normalized_inferred
        page = normalize_path_segment(page_type or page_type_for_doc_type(doc_type, self._doc_type_to_folder))
        app = normalize_path_segment(application or "unknown_app")
        plat = platform if platform in _VALID_PLATFORMS else "unknown_platform"
        return f"docs/{app}/{plat}/{page}/{unit_id}.md"

    def resolve_op(self, *, op_hint: str, unit_id: str, path: str, state: DocsState) -> str:
        if op_hint == "delete":
            return "delete"
        if op_hint == "create":
            return "create"
        if op_hint == "update":
            return "update"
        if path in state.by_path or unit_id in state.by_doc_id:
            return "update"
        return "create"

    def default_page_type(self, doc_type: str) -> str:
        return page_type_for_doc_type(doc_type, self._doc_type_to_folder)

    def _slugify(self, value: str) -> str:
        cleaned = re.sub(r"[^a-zA-Z0-9а-яА-Я_-]+", "-", value.lower()).strip("-")
        return re.sub(r"-+", "-", cleaned) or "doc"
