"""Integration coverage for DataTable end-to-end workflows."""

from pathlib import Path

import soigia.datatable as dtpkg
from soigia.datatable import DataTable


def test_end_to_end_dataframe_pipeline(monkeypatch):
    def fake_query(self, sql, backend, connection_string=None, **kwargs):
        return DataTable({"backend": [backend], "sql": [sql]})

    monkeypatch.setattr(dtpkg.DatabaseConnector, "query", fake_query)
    monkeypatch.setattr(dtpkg, "_DEFAULT_CONNECTOR", None)

    assert dtpkg.from_sqlite_db("select 1").iloc[0]["backend"] == "sqlite"
    assert dtpkg.from_sql("select 1", backend="sqlite").iloc[0]["backend"] == "sqlite"

    class DemoFactory:
        @classmethod
        def build_batch(cls, size=1, **kwargs):
            return [{"name": f"user_{i}", "age": 20 + i} for i in range(size)]

    fake_users = dtpkg.from_factory(DemoFactory, count=2)
    assert fake_users.shape == (2, 2)

    generated = dtpkg.from_faker({"name": "name", "city": "city"}, count=2, seed=3)
    assert generated.shape == (2, 2)

    base = DataTable.from_records(
        [
            {"id": 1, "name": "alice", "age": "19"},
            {"id": 2, "name": "bob", "age": "24"},
        ]
    ).auto_version("seed")

    prepared = base.clean_columns().ensure_columns("city", fill_value="unknown").to_numeric(["age"])
    assert prepared.validate_schema({"id": {"type": int}, "name": {"nullable": False}, "age": {"type": int}}).equals(
        prepared
    )

    enriched = prepared.join(DataTable({"id": [1, 2], "remote_city": ["hn", "sg"]}), on="id")
    assert "remote_city" in enriched.columns

    report = prepared.diff_report(prepared.copy(), key_columns=["id"])
    assert report["same_count"] == 2
    assert report["added_count"] == 0
    assert report["removed_count"] == 0
    assert report["has_changes"] is False

    manager = enriched.objects
    assert manager.values("id", "name").first()["id"] == 1
    assert manager.filter(age__gte=20).count() == 1
    assert manager.aggregate(total=("age", "sum")) == {"total": 43}
    assert manager.group_by("remote_city").annotate(total=("age", "sum")).to_df().shape[0] == 2
    assert manager.diff_report(joined := enriched.copy(), key_columns=["id"])["same_count"] == 2

    rendered = enriched.render_table("markdown")
    assert rendered.startswith("|")

    excel_path = Path("tests") / "_datatable_pipeline.xlsx"
    try:
        enriched.to_csv_table()
        assert enriched.to_markdown_table().startswith("|")
        assert enriched.to_html_table().startswith("<table")
    finally:
        if excel_path.exists():
            excel_path.unlink()
