# from bs4 import BeautifulSoup

# def check_ad_inactive_v2(
#     html,
#     inactive_config,
#     url=None,
#     http_status=None,
#     redirects=None,
#     *,
#     trace: bool = False,       # ⬅️ NOWE
# ):
#     """
#     Zwraca:
#       - jeśli trace=False (domyślnie):    (is_inactive: bool, reason: str)
#       - jeśli trace=True:                 (is_inactive: bool, reason: str, debug: list[str])
#     debug zawiera krótkie linie opisujące co się dopasowało.
#     """
#     if not inactive_config:
#         out = (False, "Brak konfiguracji inactive")
#         return (*out, []) if trace else out

#     soup = None
#     debug = []
#     def _dbg(line): 
#         if trace: debug.append(line)

#     for idx, rule in enumerate(inactive_config):
#         rtype = rule.get("type")
#         # 1) text
#         if rtype == "text":
#             for phrase in (rule.get("text") or []):
#                 if phrase and phrase.lower() in (html or "").lower():
#                     reason = f"Znaleziono frazę '{phrase}' w HTML (type=text)"
#                     _dbg(f"[rule#{idx} type=text] hit: '{phrase}'")
#                     return (True, reason, debug) if trace else (True, reason)

#         # 2) selector
#         elif rtype == "selector":
#             if soup is None:
#                 try: soup = BeautifulSoup(html or "", "lxml")
#                 except Exception: soup = BeautifulSoup(html or "", "html.parser")
#             for sel_rule in (rule.get("selectors") or []):
#                 sel = sel_rule.get("selector")
#                 contains = (sel_rule.get("contains") or "").strip()
#                 if not sel or not contains:
#                     continue
#                 try:
#                     for el in soup.select(sel):
#                         txt = el.get_text(" ", strip=True)
#                         if contains.lower() in (txt or "").lower():
#                             reason = f"Znaleziono '{contains}' w selektorze {sel} (type=selector)"
#                             _dbg(f"[rule#{idx} type=selector] hit: {sel} ~ '{contains}'")
#                             return (True, reason, debug) if trace else (True, reason)
#                 except Exception as e:
#                     _dbg(f"[rule#{idx} type=selector] select error {sel}: {e}")

#         # 3) redirect
#         elif rtype == "redirect":
#             if redirects and len(redirects) > 1:
#                 reason = "Wykryto przekierowanie (type=redirect)"
#                 _dbg(f"[rule#{idx} type=redirect] hit: chain={redirects}")
#                 return (True, reason, debug) if trace else (True, reason)

#         # 4) redirect_contains
#         elif rtype == "redirect_contains":
#             phrases = rule.get("redirect_contains") or []
#             for ph in phrases:
#                 if ph and url and ph.lower() in url.lower():
#                     reason = f"URL po redirect zawiera '{ph}' (type=redirect_contains)"
#                     _dbg(f"[rule#{idx} type=redirect_contains] hit: '{ph}' in {url}")
#                     return (True, reason, debug) if trace else (True, reason)

#         # 5) text_missing (wszystkich)
#         elif rtype == "text_missing":
#             missing = [m for m in (rule.get("text_missing") or []) if m]
#             if missing:
#                 low = (html or "").lower()
#                 if all(m.lower() not in low for m in missing):
#                     reason = f"Brakuje fraz {missing} w HTML (type=text_missing)"
#                     _dbg(f"[rule#{idx} type=text_missing] hit: all missing {missing}")
#                     return (True, reason, debug) if trace else (True, reason)

#         # 6) status
#         elif rtype == "status":
#             codes = rule.get("http_status") or []
#             if http_status in codes:
#                 reason = f"HTTP status {http_status} (type=status)"
#                 _dbg(f"[rule#{idx} type=status] hit: {http_status}")
#                 return (True, reason, debug) if trace else (True, reason)

#     out = (False, "Brak oznak nieaktywności")
#     return (*out, debug) if trace else out
