"""Integration round-trip tests for v1.2.0 features.

Cycle 29-33/40: Tests the full chain of export → import → quality check → merge
across databases. Validates that all v1.2.0 features work together.
"""
import json
from datetime import datetime, timedelta

import pytest

_has_sqlite_vec = True
try:
    import sqlite_vec  # noqa: F401
except ImportError:
    _has_sqlite_vec = False


@pytest.fixture
def source_db(tmp_path):
    from greymatter_core.db import SQLiteDatabase
    return SQLiteDatabase(str(tmp_path / "source.db"))


@pytest.fixture
def target_db(tmp_path):
    from greymatter_core.db import SQLiteDatabase
    return SQLiteDatabase(str(tmp_path / "target.db"))


def _insert(db, entry_id, title, content, entry_type="pattern",
            domain="general", days_ago=0):
    created = datetime.now() - timedelta(days=days_ago)
    db._conn.execute(
        "INSERT INTO knowledge_entries (id, entry_type, title, content, domain, "
        "scope, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
        (entry_id, entry_type, title, content, domain, "cross-cutting",
         created.isoformat(), created.isoformat()),
    )
    db._conn.commit()


@pytest.mark.skipif(not _has_sqlite_vec, reason="sqlite_vec not installed")
class TestExportImportRoundTrip:

    def test_export_import_cross_db(self, source_db, target_db, tmp_path):
        """Export from source, import to target, verify entries arrive."""
        from greymatter_core.export import KnowledgeExporter, KnowledgeImporter

        _insert(source_db, "s1", "Python type hints", "Always use type hints",
                entry_type="correction", domain="python")
        _insert(source_db, "s2", "Docker multi-stage", "Use multi-stage builds",
                entry_type="expertise", domain="docker")

        exporter = KnowledgeExporter(source_db)
        path = str(tmp_path / "transfer.json")
        exporter.to_json_file(path)

        importer = KnowledgeImporter(target_db)
        result = importer.from_json_file(path)
        assert result["imported"] == 2
        assert result["skipped"] == 0

        # Verify entries in target
        from greymatter_core.knowledge import KnowledgeStore
        ks = KnowledgeStore(target_db)
        entries = ks.search()
        assert len(entries) == 2

    def test_import_then_quality_check(self, source_db, target_db, tmp_path):
        """Import duplicates, then quality engine detects them."""
        from greymatter_core.export import KnowledgeExporter, KnowledgeImporter
        from greymatter_core.quality import QualityEngine

        # Same content, different entry types → both import
        _insert(source_db, "s1", "Use pytest", "Pytest for testing",
                entry_type="pattern")
        _insert(source_db, "s2", "Use pytest fixtures", "Pytest fixtures for setup",
                entry_type="expertise")

        exporter = KnowledgeExporter(source_db)
        data = exporter.to_json()

        importer = KnowledgeImporter(target_db)
        importer.from_json(data)

        # Also insert a near-duplicate directly
        _insert(target_db, "t1", "Use pytest", "Pytest for testing",
                entry_type="pattern")

        # Quality check should find duplicate
        qe = QualityEngine(target_db)
        issues = qe.find_duplicates(threshold=0.5)
        assert len(issues) >= 1

    def test_quality_then_merge_cleanup(self, source_db):
        """Quality finds duplicates, merge resolves them."""
        from greymatter_core.quality import QualityEngine

        _insert(source_db, "d1", "Always use type hints",
                "Type hints improve code quality",
                entry_type="observation")
        _insert(source_db, "d2", "Always use type hints",
                "Type hints improve tooling and readability",
                entry_type="correction")

        qe = QualityEngine(source_db)
        issues = qe.find_duplicates(threshold=0.5)
        assert len(issues) >= 1

        # Merge: correction (1.0 trust) wins over observation (0.4)
        success = qe.merge_duplicates("d2", "d1")
        assert success

        # After merge, d1 is pruned
        kept = source_db.execute_one(
            "SELECT * FROM knowledge_entries WHERE id = 'd2'"
        )
        assert "code quality" in kept["content"]
        assert "tooling" in kept["content"]

        pruned = source_db.execute_one(
            "SELECT pruned_at FROM knowledge_entries WHERE id = 'd1'"
        )
        assert pruned["pruned_at"] is not None

    def test_export_excludes_pruned(self, source_db):
        """Pruned entries don't appear in exports."""
        from greymatter_core.export import KnowledgeExporter

        _insert(source_db, "e1", "Active entry", "Still relevant")
        _insert(source_db, "e2", "Pruned entry", "Outdated")
        source_db._conn.execute(
            "UPDATE knowledge_entries SET pruned_at = datetime('now') WHERE id = 'e2'"
        )
        source_db._conn.commit()

        exporter = KnowledgeExporter(source_db)
        data = exporter.to_json()
        assert data["counts"]["knowledge_entries"] == 1
        titles = [e["title"] for e in data["knowledge_entries"]]
        assert "Pruned entry" not in titles

    def test_markdown_export_readable(self, source_db, tmp_path):
        """Markdown export is human-readable and contains key fields."""
        from greymatter_core.export import KnowledgeExporter

        _insert(source_db, "m1", "Python async/await", "Use asyncio for concurrency",
                entry_type="expertise", domain="python")
        _insert(source_db, "m2", "Docker compose", "Use compose for multi-container",
                entry_type="reference", domain="docker")

        exporter = KnowledgeExporter(source_db)
        md = exporter.to_markdown()

        assert "## docker" in md
        assert "## python" in md
        assert "### Python async/await" in md
        assert "asyncio" in md
        assert "**Type**: expertise" in md

    def test_idempotent_import(self, source_db, target_db, tmp_path):
        """Importing the same file twice doesn't create duplicates."""
        from greymatter_core.export import KnowledgeExporter, KnowledgeImporter

        _insert(source_db, "i1", "Unique entry", "Important knowledge")

        exporter = KnowledgeExporter(source_db)
        path = str(tmp_path / "idem.json")
        exporter.to_json_file(path)

        importer = KnowledgeImporter(target_db)
        r1 = importer.from_json_file(path)
        r2 = importer.from_json_file(path)

        assert r1["imported"] == 1
        assert r2["imported"] == 0
        assert r2["skipped"] == 1

        from greymatter_core.knowledge import KnowledgeStore
        ks = KnowledgeStore(target_db)
        assert ks.count() == 1


@pytest.mark.skipif(not _has_sqlite_vec, reason="sqlite_vec not installed")
class TestQualityEdgeCases:

    def test_single_entry_no_duplicates(self, source_db):
        from greymatter_core.quality import QualityEngine
        _insert(source_db, "solo", "Only entry", "Content")
        qe = QualityEngine(source_db)
        assert len(qe.find_duplicates()) == 0
        assert len(qe.find_contradictions()) == 0

    def test_empty_content_no_crash(self, source_db):
        from greymatter_core.quality import QualityEngine
        _insert(source_db, "empty1", "", "")
        _insert(source_db, "empty2", "", "")
        qe = QualityEngine(source_db)
        report = qe.full_check()
        assert isinstance(report.score, float)

    def test_many_entries_performance(self, source_db):
        """50 entries should complete quality check in reasonable time."""
        from greymatter_core.quality import QualityEngine
        import time

        for i in range(50):
            _insert(source_db, f"perf_{i}", f"Entry number {i}",
                    f"Content for entry {i} with some words", domain=f"domain_{i % 5}")

        qe = QualityEngine(source_db)
        start = time.time()
        report = qe.full_check()
        elapsed = time.time() - start

        assert elapsed < 5.0  # Should complete in under 5 seconds
        assert report.total_entries == 50
