"""Tests for QualityReport."""

import tempfile
from pathlib import Path

import pytest

from datacheck.checker import CheckResult
from datacheck.report import QualityReport


@pytest.fixture
def sample_result():
    """Sample check result for testing."""
    return CheckResult(
        success=True,
        total_samples=100,
        passed_samples=92,
        failed_samples=8,
        error_count=2,
        warning_count=5,
        info_count=1,
        pass_rate=0.92,
        rule_results={
            "required_fields": {
                "name": "必填字段检查",
                "passed": 100,
                "failed": 0,
                "severity": "error",
                "failed_samples": [],
            },
            "non_empty": {
                "name": "非空检查",
                "passed": 92,
                "failed": 8,
                "severity": "error",
                "failed_samples": ["sample_1", "sample_2"],
            },
        },
        duplicates=[["sample_5", "sample_6"]],
        failed_sample_ids=["sample_1", "sample_2", "sample_3"],
    )


class TestQualityReport:
    """Tests for QualityReport."""

    def test_to_markdown(self, sample_result):
        """Test markdown report generation."""
        report = QualityReport(sample_result)
        md = report.to_markdown()

        assert "数据质量报告" in md
        assert "92.0%" in md
        assert "🟢 优秀" in md
        assert "必填字段检查" in md
        assert "非空检查" in md

    def test_to_json(self, sample_result):
        """Test JSON report generation."""
        report = QualityReport(sample_result)
        data = report.to_json()

        assert data["summary"]["total_samples"] == 100
        assert data["summary"]["pass_rate"] == 0.92
        assert "rule_results" in data
        assert "duplicates" in data

    def test_save_markdown(self, sample_result):
        """Test saving markdown report."""
        report = QualityReport(sample_result)

        with tempfile.TemporaryDirectory() as tmpdir:
            output_path = Path(tmpdir) / "report.md"
            report.save(str(output_path), "markdown")

            assert output_path.exists()
            content = output_path.read_text()
            assert "数据质量报告" in content

    def test_save_json(self, sample_result):
        """Test saving JSON report."""
        report = QualityReport(sample_result)

        with tempfile.TemporaryDirectory() as tmpdir:
            output_path = Path(tmpdir) / "report.json"
            report.save(str(output_path), "json")

            assert output_path.exists()

    def test_quality_grades(self):
        """Test different quality grades."""
        # Excellent
        result_excellent = CheckResult(pass_rate=0.95, total_samples=100)
        report = QualityReport(result_excellent)
        assert "🟢 优秀" in report.to_markdown()

        # Good
        result_good = CheckResult(pass_rate=0.75, total_samples=100)
        report = QualityReport(result_good)
        assert "🟡 良好" in report.to_markdown()

        # Average
        result_avg = CheckResult(pass_rate=0.55, total_samples=100)
        report = QualityReport(result_avg)
        assert "🟠 一般" in report.to_markdown()

        # Needs improvement
        result_poor = CheckResult(pass_rate=0.35, total_samples=100)
        report = QualityReport(result_poor)
        assert "🔴 需改进" in report.to_markdown()

    def test_custom_title(self, sample_result):
        """Test custom report title."""
        report = QualityReport(sample_result, title="自定义标题")
        md = report.to_markdown()

        assert "自定义标题" in md


class TestHTMLReport:
    """Tests for HTML report generation."""

    def test_to_html_basic(self, sample_result):
        report = QualityReport(sample_result)
        html = report.to_html()

        assert "<!DOCTYPE html>" in html
        assert "数据质量报告" in html
        assert "92.0%" in html

    def test_html_contains_rules(self, sample_result):
        report = QualityReport(sample_result)
        html = report.to_html()

        assert "必填字段检查" in html
        assert "非空检查" in html

    def test_html_contains_duplicates(self, sample_result):
        report = QualityReport(sample_result)
        html = report.to_html()

        assert "重复检测" in html
        assert "sample_5" in html

    def test_html_grade_colors(self):
        # Excellent
        result = CheckResult(pass_rate=0.95, total_samples=100)
        html = QualityReport(result).to_html()
        assert "优秀" in html
        assert "#22c55e" in html

        # Needs improvement
        result = CheckResult(pass_rate=0.3, total_samples=100)
        html = QualityReport(result).to_html()
        assert "需改进" in html
        assert "#ef4444" in html

    def test_save_html(self, sample_result):
        report = QualityReport(sample_result)

        with tempfile.TemporaryDirectory() as tmpdir:
            output_path = Path(tmpdir) / "report.html"
            report.save(str(output_path), "html")

            assert output_path.exists()
            content = output_path.read_text()
            assert "<!DOCTYPE html>" in content

    def test_html_sampling_notice(self):
        result = CheckResult(
            pass_rate=1.0, total_samples=10,
            sampled=True, sampled_count=10, original_count=100,
        )
        html = QualityReport(result).to_html()
        assert "10/100" in html


class TestDiffReport:
    """Tests for report diff."""

    def test_diff_basic(self):
        report_a = {
            "title": "报告 A",
            "generated_at": "2025-01-01",
            "summary": {
                "total_samples": 100,
                "passed_samples": 90,
                "failed_samples": 10,
                "pass_rate": 0.9,
                "error_count": 5,
                "warning_count": 3,
            },
            "rule_results": {
                "non_empty": {"name": "非空检查", "passed": 90, "failed": 10},
            },
            "duplicates": [["a", "b"]],
        }
        report_b = {
            "title": "报告 B",
            "generated_at": "2025-01-02",
            "summary": {
                "total_samples": 100,
                "passed_samples": 95,
                "failed_samples": 5,
                "pass_rate": 0.95,
                "error_count": 2,
                "warning_count": 1,
            },
            "rule_results": {
                "non_empty": {"name": "非空检查", "passed": 95, "failed": 5},
            },
            "duplicates": [],
        }

        diff = QualityReport.diff(report_a, report_b)
        assert "质量报告对比" in diff
        assert "报告 A" in diff
        assert "报告 B" in diff
        assert "非空检查" in diff

    def test_diff_arrows(self):
        report_a = {
            "summary": {"pass_rate": 0.8, "error_count": 10, "total_samples": 100,
                        "passed_samples": 80, "failed_samples": 20, "warning_count": 5},
        }
        report_b = {
            "summary": {"pass_rate": 0.9, "error_count": 5, "total_samples": 100,
                        "passed_samples": 90, "failed_samples": 10, "warning_count": 5},
        }
        diff = QualityReport.diff(report_a, report_b)
        # pass_rate increased
        assert "↑" in diff
        # error_count decreased
        assert "↓" in diff
