from datetime import datetime
from pathlib import Path
import shutil
from types import SimpleNamespace

import pandas as pd

from nemo_library_etl.adapter.migman.load import (
    _beautify_report_column_name,
    _create_deficiency_report_html,
    _filter_customer_report_columns,
    _get_nemo_etl_version,
    MigManLoad,
)


def test_beautify_report_column_name_removes_csv_separators() -> None:
    raw = (
        "S_Lieferant.ZahlungsArt is not a valid number "
        "(expected German format, e.g. 1.234,56; format: z9)"
    )

    beautified = _beautify_report_column_name(raw)

    assert beautified == (
        "S_Lieferant.ZahlungsArt is not a valid number "
        "(expected German format e.g. 1.234 56 format: z9)"
    )
    assert "," not in beautified
    assert ";" not in beautified


def test_filter_customer_report_columns_removes_zero_count_pairs() -> None:
    df = pd.DataFrame(
        {
            "Field A error": ["1", "0"],
            "Field A error Count": ["1", "1"],
            "Field B error": ["0", "0"],
            "Field B error Count": ["0", "0"],
            "ERROR_CODE_CONCAT": ["10", "10"],
            "ERROR_CODE_COUNT_OVERALL": ["2", "2"],
            "RECORD_PIPE": ["row1", "row2"],
        }
    )

    filtered = _filter_customer_report_columns(df)

    assert list(filtered.columns) == [
        "Field A error",
        "Field A error Count",
        "ERROR_CODE_CONCAT",
        "ERROR_CODE_COUNT_OVERALL",
        "RECORD_PIPE",
    ]


def test_create_deficiency_report_html_contains_metadata_and_table_payload() -> None:
    df = pd.DataFrame(
        {
            "Spalte A": ["eins", ""],
            "Spalte B": ["<script>alert('x')</script>", "zwei"],
        }
    )
    file_path = Path("reports/to_customer/Kunden_with_messages.html")
    created_at = datetime(2026, 3, 13, 14, 30, 0)

    html_content = _create_deficiency_report_html(
        report_title="Kunden & Lieferanten",
        file_path=file_path,
        created_at=created_at,
        df=df,
        error_row_count=1,
        generated_by_version="MigMan / Nemo ETL Version 0.1.91",
    )

    assert "<h1>Kunden &amp; Lieferanten</h1>" in html_content
    assert "Dateipfad" in html_content
    assert "Anzahl Eintraege / Fehlerzeilen" in html_content
    assert "Erzeugt am" in html_content
    assert "Erzeugt durch / Version" in html_content
    assert file_path.as_posix() in html_content
    assert "2026-03-13 14:30:00" in html_content
    assert "2 / 1" in html_content
    assert "MigMan / Nemo ETL Version 0.1.91" in html_content
    assert 'const columns = ["Spalte A", "Spalte B"];' in html_content
    assert "\\u003cscript\\u003ealert('x')\\u003c/script\\u003e" in html_content
    assert "Filter anzeigen" in html_content
    assert "Sortierung zurücksetzen" in html_content


def test_load_reports_writes_csv_and_html_files() -> None:
    class DummyNL:
        def LoadReport(self, projectname, report_name, data_types):
            if report_name == "(Customer) All records with message":
                return pd.DataFrame(
                    {
                        "Fehlermeldung": ["Lieferant fehlt", "Zahlungsart ungueltig"],
                        "Fehlermeldung Count": ["2", "2"],
                        "ERROR_CODE_CONCAT": ["10", "01"],
                        "ERROR_CODE_COUNT_OVERALL": ["1", "1"],
                        "RECORD_PIPE": ["row1", "row2"],
                    }
                )
            return pd.DataFrame(
                {
                    "Spalte": ["A", "B"],
                    "Wert": ["1", "2"],
                }
            )

    dummy_logger = SimpleNamespace(
        info=lambda *args, **kwargs: None,
        debug=lambda *args, **kwargs: None,
        warning=lambda *args, **kwargs: None,
        error=lambda *args, **kwargs: None,
    )

    tmpdir = Path("tests") / ".tmp_migman_load_reports"
    if tmpdir.exists():
        shutil.rmtree(tmpdir)
    tmpdir.mkdir(parents=True, exist_ok=True)

    try:
        loader = object.__new__(MigManLoad)
        loader.nl = DummyNL()
        loader.cfg = SimpleNamespace(etl_directory=str(tmpdir))
        loader.logger = dummy_logger

        MigManLoad._load_reports(
            loader,
            nemo_project_name="NEMO_Kunden",
            project_name="Kunden",
            addon="",
            postfix="",
        )

        customer_csv = tmpdir / "reports" / "to_customer" / "Kunden_with_messages.csv"
        customer_html = customer_csv.with_suffix(".html")
        proalpha_csv = tmpdir / "reports" / "to_proalpha" / "Kunden.csv"
        proalpha_html = proalpha_csv.with_suffix(".html")
        expected_customer_relative = customer_html.as_posix()
        expected_proalpha_relative = proalpha_html.as_posix()

        assert customer_csv.exists()
        assert customer_html.exists()
        assert proalpha_csv.exists()
        assert proalpha_html.exists()

        customer_csv_text = customer_csv.read_text(encoding="utf-8-sig")
        assert customer_csv_text.startswith("Fehlermeldung;Fehlermeldung Count")

        customer_html_text = customer_html.read_text(encoding="utf-8")
        assert "<h1>Kunden</h1>" in customer_html_text
        assert expected_customer_relative in customer_html_text
        assert str(customer_html.absolute()) not in customer_html_text
        assert "const columns = [\"Fehlermeldung\", \"Fehlermeldung Count\"" in customer_html_text
        assert "Filter anzeigen" in customer_html_text
        assert "Fehlermeldung" in customer_html_text
        assert "2 / 2" in customer_html_text
        assert f"MigMan / Nemo ETL Version {_get_nemo_etl_version()}" in customer_html_text

        proalpha_html_text = proalpha_html.read_text(encoding="utf-8")
        assert expected_proalpha_relative in proalpha_html_text
        assert str(proalpha_html.absolute()) not in proalpha_html_text
        assert "2 / 0" in proalpha_html_text
        assert "const columns = [\"Spalte\", \"Wert\"];" in proalpha_html_text
    finally:
        if tmpdir.exists():
            shutil.rmtree(tmpdir)
