"""REVIEW-PROCESS.md section 1 and the code say the same thing (Stream K3.2).

The boundary between what a rule may do alone and what must be proposed lives in one readable
place, and changing it is a rules version. A doc that drifts from the code is how the next word
list slips back into the key, so the two are held equal here: the concentration vocabulary item
by item (the running list's two K3 issues), the rules version, and the chosen boundary.
"""

from __future__ import annotations

import re
from pathlib import Path

from app.models.catalog import IDENTITY_RULES_VERSION
from app.services import product_lines

DOC = (Path(__file__).resolve().parents[1] / "docs" / "REVIEW-PROCESS.md").read_text()
SECTION = DOC[DOC.index("## 1. What a rule may do without review"): DOC.index("## 2. Grouping defaults")]
CANONICAL = {"Eau de Parfum": "edp", "Eau de Toilette": "edt", "Eau de Cologne": "edc", "Parfum": "parfum",
             "Elixir": "elixir", "Mist": "mist", "Intense": "intense", "Extreme": "extreme", "Absolu": "absolu"}


def documented() -> dict[str, str]:
    """Every synonym the doc lists, to the canonical label its heading names."""
    out: dict[str, str] = {}
    for label, synonyms in re.findall(r"\*\*([A-Z][A-Za-z ]+)\*\*:?\s*\(?([^;)\n]+(?:\n\s{5}[^-\n][^;)\n]*)?)", SECTION[SECTION.index("6. **The closed"):SECTION.index("7. **Case")]):
        if label not in CANONICAL:
            continue
        for word in synonyms.split("("):
            for synonym in word.split(","):
                text = synonym.strip(" .\n)").lower()
                if text and "dominates" not in text and "kept beside" not in text:
                    out[text] = CANONICAL[label]
    return out


def test_every_documented_synonym_reads_as_its_canonical_word():
    synonyms = documented()
    assert len(synonyms) >= 24, synonyms
    for synonym, canonical in synonyms.items():
        raw, read = product_lines.attribute_of(f"Some Scent {synonym} 50ml", "beauty")
        assert canonical in read.split() or read == canonical, (synonym, raw, read)


def test_every_rule_the_code_reads_is_in_the_document():
    text = SECTION.lower()
    for pattern, label in product_lines._ATTRIBUTE_RULES:
        words = re.sub(r"\\[bs]\+?|\(\?:|[()?\[\]+]|\|.*", " ", pattern.pattern.replace("[eé]", "e").replace("[eêè]", "e"))
        first = " ".join(words.split()).split(" ")[0]
        assert first and first[:5] in text, (pattern.pattern, label)


def test_the_document_names_the_rules_version_and_the_boundary_the_code_keys_under():
    assert IDENTITY_RULES_VERSION == "6" and f"identity rules v{IDENTITY_RULES_VERSION}" in SECTION
    assert product_lines.BOUNDARY == "a" and "boundary (a)" in SECTION
    assert product_lines.BOUNDARIES["a"] == frozenset(), "the chosen boundary deletes no list"


def test_a_word_off_the_list_stays_in_the_residual_name():
    for name in ("Allure Homme Sport 100ml", "La Nuit de L'Homme 60 ml", "Le Parfum Essentiel"):
        assert product_lines.attribute_of(name, "beauty")[1] in ("", "parfum")
    assert "sport" in product_lines.product_line_key("Allure Homme Sport Eau de Toilette 100ml", listed_brand="CHANEL", vertical="beauty")
