from __future__ import annotations

import re
from typing import Iterable, List, Optional


def slugify_segment(text: str) -> str:
    """Lowercase URL segment: letters, numbers, hyphens only."""
    s = str(text or "").strip().lower()
    s = re.sub(r"[^a-z0-9]+", "-", s)
    s = re.sub(r"-+", "-", s).strip("-")
    return s or "product"


def normalize_plp_path(path: str) -> str:
    """Canonical PLP path slug without leading/trailing slashes."""
    parts = [slugify_segment(p) for p in str(path or "").split("/") if str(p).strip()]
    return "/".join(p for p in parts if p)


def build_pdp_slug(
    title: Optional[str],
    sku: str,
    *,
    existing_slug: Optional[str] = None,
) -> str:
    """PDP slug at site root: {pretty-name}-{sku}, e.g. anna-snow-white-b15-aswb15."""
    sku_part = slugify_segment(str(sku or "").strip())
    if existing_slug:
        slug = normalize_plp_path(existing_slug)
        if slug.endswith(f"-{sku_part}"):
            return slug
        if sku_part and sku_part not in slug.split("-"):
            return f"{slug}-{sku_part}" if slug else sku_part
        return slug or sku_part
    pretty = slugify_segment(title or sku or "product")
    if not sku_part:
        return pretty
    if pretty.endswith(f"-{sku_part}") or pretty == sku_part:
        return pretty
    return f"{pretty}-{sku_part}"


def build_pdp_url(slug: str) -> str:
    slug = str(slug or "").strip().strip("/")
    return f"/{slug}" if slug else "/"


def build_plp_url(path_slug: str) -> str:
    path = normalize_plp_path(path_slug)
    return f"/{path}/" if path else "/"


def build_magento_plp_url(path_slug: str) -> str:
    """Magento category-style PLP URL (path.html)."""
    path = normalize_plp_path(path_slug)
    return f"/{path}.html" if path else "/"


def path_segments(path_slug: str) -> List[str]:
    return [p for p in normalize_plp_path(path_slug).split("/") if p]


def infer_path_kind(path_slug: str) -> str:
    segments = path_segments(path_slug)
    if not segments:
        return "hub"
    if len(segments) == 1:
        return "hub"
    if len(segments) == 2:
        return "facet"
    return "combo"


def listing_paths_from_facets(
    hub_slug: str,
    facets: Iterable[str],
    *,
    include_hub: bool = True,
) -> List[str]:
    """Build hub + single-facet + combo PLP paths from a hub and facet head terms."""
    hub = normalize_plp_path(hub_slug)
    facet_list = [normalize_plp_path(f) for f in facets if normalize_plp_path(f)]
    paths: List[str] = []
    if include_hub and hub:
        paths.append(hub)
    for facet in facet_list:
        if not facet:
            continue
        if hub:
            paths.append(f"{hub}/{facet}")
        else:
            paths.append(facet)
        for other in facet_list:
            if other != facet and hub:
                combo = f"{hub}/{facet}-{other}" if "-" not in facet else f"{hub}/{facet}/{other}"
                paths.append(normalize_plp_path(combo))
    seen: set[str] = set()
    out: List[str] = []
    for path in paths:
        if path and path not in seen:
            seen.add(path)
            out.append(path)
    return out
