"""Sheet-name translation must not break references.

openpyxl does not rewrite references on rename — cell formulas, defined
names and validations pointing at a translated sheet would break (#REF!).
These tests cover the full rename + rewrite path.
"""

from openpyxl import Workbook, load_workbook
from openpyxl.workbook.defined_name import DefinedName

from translators.excel_translator import ExcelTranslator


class _FrToEn:
    """Minimal legacy-style provider: French sheet name → English."""

    def translate_batch(self, texts, target_language, source_language="auto"):
        mapping = {
            "Ventes": "Sales",
            "Données": "Data",
            "Rapport des ventes": "Sales report",
            "Total": "Total",
        }
        return [mapping.get(t, t) for t in texts]


def _make_workbook(path):
    wb = Workbook()
    ws = wb.active
    ws.title = "Ventes"
    ws["A1"] = "Rapport des ventes"
    ws["A2"] = "Total"
    ws["A3"] = 10
    ws["A4"] = 20
    # Cross-sheet formula (unquoted name)
    ws2 = wb.create_sheet("Données")
    ws2["A1"] = "=SUM(Ventes!A3:A4)"
    # Quoted name (name would need quotes if it had spaces — keep simple here)
    ws2["A2"] = "=Ventes!A3+Ventes!A4"
    # Defined name pointing at the renamed sheet
    wb.defined_names["TotalVentes"] = DefinedName(
        "TotalVentes", attr_text="'Ventes'!$A$3"
    )
    wb.save(path)
    return wb


class TestSheetRenameReferences:
    def test_cell_formulas_and_defined_names_rewritten(self, tmp_path):
        from pathlib import Path

        src = tmp_path / "in.xlsx"
        out = tmp_path / "out.xlsx"
        _make_workbook(src)

        translator = ExcelTranslator(provider=_FrToEn())
        translator.translate_file(Path(src), Path(out), "en", "fr")

        wb = load_workbook(out)
        data = wb["Data"]
        assert data["A1"].value == "=SUM(Sales!A3:A4)", data["A1"].value
        assert data["A2"].value == "=Sales!A3+Sales!A4", data["A2"].value

        # Defined name follows the rename
        dn = wb.defined_names["TotalVentes"]
        assert "Sales" in (dn.attr_text or ""), dn.attr_text
        assert "Ventes" not in (dn.attr_text or "")

        # The renamed sheet actually exists under its new name
        assert "Sales" in wb.sheetnames
        assert "Ventes" not in wb.sheetnames

    def test_3d_and_multiple_refs(self, tmp_path):
        mapping = {"Sheet1": "Feuille1", "Sheet2": "Feuille2"}
        formula = "=SUM(Sheet1!A1:Sheet2!B2)+Sheet1!C3"
        out = ExcelTranslator._rewrite_sheet_refs_in_formula(formula, mapping)
        assert out == "=SUM(Feuille1!A1:Feuille2!B2)+Feuille1!C3"

    def test_quoted_refs_and_prefix_safety(self, tmp_path):
        mapping = {"Ventes": "Sales", "Ventes 2026": "Sales 2026"}
        out = ExcelTranslator._rewrite_sheet_refs_in_formula(
            "=SUM('Ventes 2026'!A1:A2)+'Ventes'!B1", mapping
        )
        # "Ventes 2026" (longest first) keeps its quotes (name with space);
        # "Sales" needs no quotes so the canonical unquoted form is emitted.
        assert out == "=SUM('Sales 2026'!A1:A2)+Sales!B1"

    def test_non_sheet_bang_not_touched(self, tmp_path):
        mapping = {"Ventes": "Sales"}
        # "Total!A1" is not a renamed sheet — must stay untouched
        out = ExcelTranslator._rewrite_sheet_refs_in_formula("=Total!A1", mapping)
        assert out == "=Total!A1"
