# mkdocs_vwidalias/plugin.py
from __future__ import annotations
import os
import re
from pathlib import Path
from typing import Optional

from mkdocs.plugins import BasePlugin
from mkdocs.config import config_options
from mkdocs.config.defaults import MkDocsConfig
from mkdocs.structure.pages import Page
from mkdocs.utils import write_file
import logging

log = logging.getLogger("mkdocs.plugins.vwidalias")

VALID_HTML_ID = re.compile(r"^[A-Za-z][\w\\-\\:\\.]*$")

def normalize_id(raw: str) -> Optional[str]:
    """Normalize and validate a front-matter ID value."""
    if not raw:
        return None
    raw = str(raw).strip()
    raw = re.sub(r"\s+", "-", raw)
    if not VALID_HTML_ID.match(raw):
        return None
    return raw


REDIRECT_TEMPLATE = """<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Redirecting…</title>
    <meta http-equiv="refresh" content="0; url=/{target}">
    <link rel="canonical" href="/{target}">
    <script>location.replace("/{target}");</script>
    <style>body{{font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;padding:2rem}}</style>
  </head>
  <body>
    <p>Redirecting to <a href="/{target}">/{target}</a>…</p>
  </body>
</html>
"""


class VwidAliasPlugin(BasePlugin):
    """
    vwidalias — generate alias pages for MkDocs based on front-matter IDs.

    For each Markdown page with a front-matter key (default: `id`),
    creates an alias page at /<ID>/index.html (or /<prefix>/<ID>/index.html)
    that redirects to the canonical page (optionally with '#<ID>').
    """

    config_scheme = (
        ("id_field", config_options.Type(str, default="id")),
        ("alias_prefix", config_options.Type(str, default="")),
        ("append_hash", config_options.Type(bool, default=True)),
        ("fail_on_duplicate", config_options.Type(bool, default=False)),
    )

    def __init__(self):
        super().__init__()
        self.site_dir: Optional[str] = None
        self.alias_map: dict[str, str] = {}

    # -- setup --
    def on_config(self, config: MkDocsConfig, **kwargs):
        self.site_dir = config.site_dir
        log.info("[vwidalias] Initialized (site_dir=%s)", self.site_dir)
        return config

    # -- main logic: per page --
    def on_page_markdown(self, markdown: str, page: Page, config: MkDocsConfig, files, **kwargs):
        meta = getattr(page, "meta", {}) or {}
        raw_id = meta.get(self.config["id_field"])
        html_id = normalize_id(raw_id) if raw_id else None
        if not html_id:
            return markdown

        # Determine page target (canonical URL)
        page_url = page.url or ""
        if page_url.endswith(".html"):
            page_url = page_url[:-5]
        if not page_url.endswith("/"):
            page_url += "/"

        target = f"{page_url}#{html_id}" if self.config["append_hash"] else page_url
        prefix = (self.config["alias_prefix"] or "").strip("/")
        alias_parts = [p for p in (prefix, html_id) if p]
        alias_dir = os.path.join(self.site_dir or "site", *alias_parts)
        alias_index = os.path.join(alias_dir, "index.html")

        # Create alias redirect page
        Path(alias_dir).mkdir(parents=True, exist_ok=True)
        html = REDIRECT_TEMPLATE.format(target=target)
        write_file(html.encode("utf-8"), alias_index)

        log.info("[vwidalias] Alias created: /%s -> /%s", "/".join(alias_parts), target)
        return markdown
