"""Test per il Profiler (test di integrazione end-to-end)."""

import json
import pytest

from dataprofiler import Profiler
from dataprofiler.models.column_profile import ColumnType


class TestProfiler:
    """Test di integrazione per la classe Profiler."""

    def test_profile_csv(self, csv_path):
        profiler = Profiler(csv_path)
        report = profiler.profile()
        assert report.row_count == 15
        assert report.column_count == 9
        assert report.filename == "studenti.csv"

    def test_profile_json(self, json_path):
        profiler = Profiler(json_path)
        report = profiler.profile()
        assert report.row_count == 12
        assert report.column_count == 6

    def test_column_type_detection_csv(self, csv_path):
        """Verifica che i tipi colonna vengano rilevati correttamente."""
        profiler = Profiler(csv_path)
        report = profiler.profile()

        # 'eta' dovrebbe essere numerico
        eta = report.get_column("eta")
        assert eta is not None
        assert eta.dtype == ColumnType.NUMERIC

        # 'nome' dovrebbe essere testuale
        nome = report.get_column("nome")
        assert nome is not None
        assert nome.dtype == ColumnType.TEXT

        # 'data_iscrizione' dovrebbe essere datetime
        data = report.get_column("data_iscrizione")
        assert data is not None
        assert data.dtype == ColumnType.DATETIME

        # 'attivo' dovrebbe essere booleano
        attivo = report.get_column("attivo")
        assert attivo is not None
        assert attivo.dtype == ColumnType.BOOLEAN

    def test_missing_values_detected(self, csv_path):
        profiler = Profiler(csv_path)
        report = profiler.profile()

        # 'eta' ha 3 valori mancanti su 15
        eta = report.get_column("eta")
        assert eta.missing_count == 3

        # 'email' ha 3 valori mancanti
        email = report.get_column("email")
        assert email.missing_count == 3

    def test_overall_completeness(self, csv_path):
        profiler = Profiler(csv_path)
        report = profiler.profile()
        assert 0 < report.overall_completeness <= 100

    def test_numeric_stats(self, csv_path):
        profiler = Profiler(csv_path)
        report = profiler.profile()
        voto = report.get_column("voto_medio")
        assert voto.dtype == ColumnType.NUMERIC
        assert "media" in voto.stats
        assert "mediana" in voto.stats
        assert voto.stats["min"] >= 0
        assert voto.stats["max"] <= 40

    def test_export_markdown(self, csv_path, tmp_output):
        profiler = Profiler(csv_path)
        report = profiler.profile()
        out = str(tmp_output / "report.md")
        profiler.export(report, out, fmt="md")
        with open(out) as f:
            content = f.read()
        assert "Report DataProfiler" in content
        assert "studenti.csv" in content

    def test_export_json(self, csv_path, tmp_output):
        profiler = Profiler(csv_path)
        report = profiler.profile()
        out = str(tmp_output / "report.json")
        profiler.export(report, out, fmt="json")
        with open(out) as f:
            data = json.load(f)
        assert data["dataset"]["righe"] == 15

    def test_export_html(self, csv_path, tmp_output):
        profiler = Profiler(csv_path)
        report = profiler.profile()
        out = str(tmp_output / "report.html")
        profiler.export(report, out, fmt="html")
        with open(out) as f:
            content = f.read()
        assert "<!DOCTYPE html>" in content

    def test_quick_summary(self, csv_path):
        profiler = Profiler(csv_path)
        summary = profiler.quick_summary()
        assert "studenti.csv" in summary
        assert "15" in summary

    def test_get_column_returns_none_for_missing(self, csv_path):
        profiler = Profiler(csv_path)
        report = profiler.profile()
        assert report.get_column("colonna_inesistente") is None

    def test_warnings_generated(self, tmp_output):
        """Test con dati che generano warnings."""
        csv_file = tmp_output / "warning_test.csv"
        csv_file.write_text(
            "id,valore,costante\n"
            + "\n".join(
                f"{i},,X" for i in range(1, 21)
            )
        )
        profiler = Profiler(str(csv_file))
        report = profiler.profile()
        # La colonna 'valore' ha 100% mancanti → warning
        assert any("valore" in w for w in report.warnings)

    def test_dataset_profile_summary(self, csv_path):
        profiler = Profiler(csv_path)
        report = profiler.profile()
        summary = report.summary()
        assert summary["righe"] == 15
        assert summary["colonne"] == 9
        assert "completezza" in summary

    def test_profile_json_types(self, json_path):
        """Verifica tipi colonna su dati JSON."""
        profiler = Profiler(json_path)
        report = profiler.profile()

        prezzo = report.get_column("prezzo")
        assert prezzo.dtype == ColumnType.NUMERIC

        nome = report.get_column("nome")
        assert nome.dtype == ColumnType.TEXT
