"""
Light-weight HTML slicer
========================
Przyjmuje:
    • pierwotny `html`
    • słownik `spec` (taki jak w Twoim JSON-ie).

Zwraca:
    • string z „przyciętym” HTML-em – idealny do karmienia
      SchemaAnalyzer-owi, żeby rysował TYLKO to, co naprawdę pobierasz.
"""
from __future__ import annotations
import copy
from typing import Dict, Any, List
from bs4 import BeautifulSoup

ERROR_MARKERS = {"error", "<body>error</body>"}

def _remove_selectors(soup: BeautifulSoup, selectors: List[str]) -> None:
    for sel in selectors:
        for node in soup.select(sel):
            node.decompose()

def _extract_piece(soup: BeautifulSoup, selector: str, inner: bool) -> str:
    """Zwraca outer- lub inner-HTML pierwszych pasujących elementów."""
    out: List[str] = []
    for el in soup.select(selector):
        out.append(el.decode_contents() if inner else el.decode())
    return "\n".join(out)

def slice_html(html: str, spec: Dict[str, Any]) -> str:
    """
    • usuwa `skip_selectors`
    • dla każdego klucza **zakończonego na `_html`** wycina fragment
    • jeśli `merge` = True  → łączenie w jeden HTML-korpus
    """
    if not html or html.strip().lower() in ERROR_MARKERS:
        # Zabezpieczenie — jeśli html to "error", zwracamy bez przerabiania
        return "error"

    bs = BeautifulSoup(html, "lxml")

    # 1) usuń śmieci / bannery / cookie-bars…
    _remove_selectors(bs, spec.get("skip_selectors", []))

    # 2) wytnij wskazane pod-bloki
    parts: List[str] = []
    for key, cfg in spec.items():
        if not key.endswith("_html"):  # pomijamy meta-pola
            continue
        selector = cfg["selector"]
        inner = cfg.get("playwright_action") == "inner_html"
        parts.append(_extract_piece(bs, selector, inner))

    # 3) merge → sklej w jeden strumień, inaczej zwróć pierwszy element
    if spec.get("merge", False):
        body = "\n".join(parts)
        return f"<body>{body}</body>"
    return parts[0] if parts else ""
