from typing import Dict, Set
from urllib.parse import urlparse, urljoin
import httpx


async def _resolve_sub_redirects(
    base_url: str,
    candidates: Set[str],
    allowed_tops: Set[str],
    valid_subs_by_top: Dict[str, Set[str]],
) -> Dict[str, str]:
    mapping: Dict[str, str] = {}
    if not candidates:
        return mapping
    timeout = httpx.Timeout(20.0, connect=10.0)
    async with httpx.AsyncClient(follow_redirects=True, timeout=timeout, http2=True) as client:
        for path in sorted(candidates):
            try:
                url = urljoin(base_url, path)
                r = await client.get(url)
                final = str(r.url)
                p = urlparse(final)
                parts = [x for x in (p.path or "").split("/") if x]
                if len(parts) >= 2:
                    top_new = parts[0].lower()
                    sub_new = parts[1].lower().removesuffix(".html").removesuffix(".htm")
                    if top_new in allowed_tops:
                        new_path = f"/{top_new}/{sub_new}"
                        if new_path != path:
                            mapping[path] = new_path
                            valid_subs_by_top.setdefault(top_new, set()).add(sub_new)
            except Exception:
                continue
    return mapping
