"""Regression test for the bug where chart <a:t> text was never written back
to the .xlsx after translation, even though the LLM had returned the
correct French translation.

Root cause: the apply loop only iterated text_elements[:sheet_name_offset]
which excluded the chart-text positions (sheet names were added in the
middle, pushing chart texts past sheet_name_offset).
"""
import sys
import shutil
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from lxml import etree
from openpyxl import load_workbook
import zipfile

from translators.excel_translator import ExcelTranslator

NS_A = "http://schemas.openxmlformats.org/drawingml/2006/main"
NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart"

# Force a known translation for every chart-relevant string.
FR = {
    "Monthly Sales Volume (Units)": "Volume de ventes mensuel (unites)",
    "Month": "Mois",
    "Quantity": "Quantite",
    "Revenue by Product": "Chiffre d'affaires par produit",
    "Quantity Trend": "Tendance des quantites",
    "Order #": "Numero de commande",
}


class FixedProvider:
    def translate_batch(self, *args, **kwargs):
        if args and hasattr(args[0], 'text'):
            return [type("R", (), {"translated_text": FR.get(req.text, req.text)})() for req in args[0]]
        texts = args[0] if args else kwargs.get('texts', [])
        return [FR.get(t, t) for t in texts]


def _read_chart_a_t(xlsx_path: Path):
    out = {}
    with zipfile.ZipFile(xlsx_path, 'r') as zf:
        for name in zf.namelist():
            if name.startswith('xl/charts/') and name.endswith('.xml'):
                xml = etree.fromstring(zf.read(name))
                out[name] = [t.text for t in xml.iter(f'{{{NS_A}}}t') if t.text]
    return out


def test_chart_texts_get_applied_to_output(tmp_path):
    src = Path(r'D:\dev1405\office_translator\sample_files\test_corpus\test_excel.xlsx')
    dst = tmp_path / "out.xlsx"
    shutil.copy(src, dst)

    tr = ExcelTranslator()
    tr.set_provider(FixedProvider())
    tr.translate_file(
        input_path=src,
        output_path=dst,
        target_language="fr",
        source_language="en",
        translate_images=False,
    )

    chart_texts = _read_chart_a_t(dst)
    # All chart a:t elements should be translated, not still English.
    for cf, texts in chart_texts.items():
        for t in texts:
            assert t in FR.values(), (
                f"{cf} still has untranslated text: {t!r}. "
                f"Expected one of: {list(FR.values())}"
            )


def test_chart_refs_also_rewritten(tmp_path):
    """Sheet refs are rewritten as part of the same fix flow."""
    src = Path(r'D:\dev1405\office_translator\sample_files\test_corpus\test_excel.xlsx')
    dst = tmp_path / "out2.xlsx"
    shutil.copy(src, dst)

    tr = ExcelTranslator()
    tr.set_provider(FixedProvider())
    tr.translate_file(
        input_path=src,
        output_path=dst,
        target_language="fr",
        source_language="en",
        translate_images=False,
    )

    # Sheet name 'Sales 2024' is not in FR so it should not be renamed.
    # The chart refs should still point at 'Sales 2024' (no rename happened).
    with zipfile.ZipFile(dst, 'r') as zf:
        for name in zf.namelist():
            if name.startswith('xl/charts/') and name.endswith('.xml'):
                xml = etree.fromstring(zf.read(name))
                refs = [f.text for f in xml.iter(f'{{{NS_C}}}f') if f.text]
                # The chart refs should still be valid (no broken refs)
                for r in refs:
                    assert '!' in r, f"Invalid chart ref in {name}: {r!r}"


if __name__ == "__main__":
    import tempfile
    with tempfile.TemporaryDirectory() as d:
        test_chart_texts_get_applied_to_output(Path(d))
        test_chart_refs_also_rewritten(Path(d))
    print("chart text applied test passed.")
