"""Integration tests for cross-reference detection and resolution."""

import pytest
from uuid import uuid4

from src.extraction.cross_ref_detector import (
    CrossRefDetector,
    CrossReferenceMatch,
    CrossRefResolutionSummary,
)
from src.extraction.models import CrossRefResolutionSummary as ModelCrossRefSummary


class TestCrossRefDetectorIntegration:
    """Integration tests for CrossRefDetector end-to-end flows."""

    def test_full_detection_flow(self):
        """Test complete detection flow from content to matches."""
        detector = CrossRefDetector()

        # Content with multiple reference types
        content = {
            "description": "Main specification document",
            "notes": "See Sheet Configuration for settings",
            "reference": "Item 2024-4_0019 applies here",
            "link": "Ref: ABC-123",
            "source": "Page 01.2-5, Item 3",
        }

        matches = detector.detect_references(content)

        # Verify we detected multiple reference types
        ref_types = {m.reference_type for m in matches}
        assert "sheet_ref" in ref_types
        assert "item_ref" in ref_types
        # May or may not have code_ref depending on pattern overlap

        # Verify field names are captured
        field_names = {m.field_name for m in matches}
        assert len(field_names) > 1

    def test_japanese_reference_detection(self):
        """Test detection of Japanese cross-reference patterns."""
        detector = CrossRefDetector()

        content = {
            "説明": "このドキュメントは設定を説明します",
            "参考": "参照 シート「データ一覧」を確認してください",
            "項目リンク": "項目 ABC-001 を参照",
        }

        matches = detector.detect_references(content)

        # Should detect at least one Japanese reference
        assert len(matches) >= 1

        # Verify Japanese patterns work
        jp_matches = [
            m
            for m in matches
            if "参照" in m.reference_text or "項目" in m.reference_text
        ]
        assert len(jp_matches) >= 1

    def test_combined_sheet_item_reference(self):
        """Test detection and parsing of combined sheet+item references."""
        detector = CrossRefDetector()

        content = {
            "cross_ref": "See Sheet Mapping, Item 2024-001",
        }

        matches = detector.detect_references(content)

        # Find sheet_item_ref or separate matches
        has_combined = any(m.reference_type == "sheet_item_ref" for m in matches)
        has_sheet = any(m.reference_type == "sheet_ref" for m in matches)

        # Should detect either combined or individual patterns
        assert has_combined or has_sheet

    def test_no_false_positives_normal_text(self):
        """Test that normal text doesn't generate false positive matches."""
        detector = CrossRefDetector()

        content = {
            "name": "John Smith",
            "address": "123 Main Street",
            "description": "This is a normal description without references",
            "status": "Active",
            "date": "2024-01-15",
        }

        matches = detector.detect_references(content)

        # Should have few or no matches
        sheet_refs = [m for m in matches if m.reference_type == "sheet_ref"]
        assert len(sheet_refs) == 0

    def test_content_item_search_integration(self):
        """Test item code search across content dictionaries."""
        detector = CrossRefDetector()

        # Test various content structures
        test_cases = [
            ({"item_code": "ABC-123"}, "ABC-123", True),
            ({"Item": "ABC-123"}, "ABC-123", True),
            ({"description": "Linked to ABC-123"}, "ABC-123", True),
            ({"value": "XYZ-999"}, "ABC-123", False),
            ({}, "ABC-123", False),
        ]

        for content, item_code, expected in test_cases:
            result = detector._content_contains_item(content, item_code)
            assert result == expected, f"Failed for content={content}, item={item_code}"

    def test_summary_statistics(self):
        """Test that summary statistics are correctly calculated."""
        doc_id = uuid4()
        summary = CrossRefResolutionSummary(
            document_id=doc_id,
            references_found=10,
            references_resolved=7,
            unresolved_count=3,
            unresolved_refs=["Ref A", "Ref B", "Ref C"],
            warnings=[],
        )

        # Verify arithmetic
        assert summary.references_resolved + summary.unresolved_count == summary.references_found
        assert len(summary.unresolved_refs) == summary.unresolved_count

        # Verify dict conversion
        d = summary.to_dict()
        assert d["references_found"] == 10
        assert d["references_resolved"] == 7
        assert d["unresolved_count"] == 3


class TestCrossRefResolutionSummaryCompatibility:
    """Test compatibility between CrossRefResolutionSummary definitions."""

    def test_model_summary_compatibility(self):
        """Test that models.py and cross_ref_detector.py definitions are compatible."""
        doc_id = uuid4()

        # Create from extraction models
        model_summary = ModelCrossRefSummary(
            document_id=doc_id,
            references_found=5,
            references_resolved=3,
            unresolved_count=2,
            unresolved_refs=["A", "B"],
            warnings=["Warning 1"],
        )

        # Both should have same to_dict structure
        d = model_summary.to_dict()
        assert "document_id" in d
        assert "references_found" in d
        assert "references_resolved" in d
        assert "unresolved_count" in d
        assert "unresolved_refs" in d
        assert "warnings" in d


class TestCrossRefPatternCoverage:
    """Test coverage of various cross-reference patterns."""

    def test_pattern_variations(self):
        """Test various pattern variations are detected."""
        detector = CrossRefDetector()

        test_cases = [
            # English sheet references
            ("See Sheet Data", "sheet_ref"),
            ("see sheet config", "sheet_ref"),
            ("SEE SHEET MAIN", "sheet_ref"),
            ("Refer to Sheet Settings", "sheet_ref"),
            # Item references
            ("Item ABC-123", "item_ref"),
            ("item xyz_001", "item_ref"),
            ("ITEM 2024-001", "item_ref"),
            # Code references
            ("Ref: ABC-123", "code_ref"),
            ("ref: xyz_001", "code_ref"),
            ("Reference: CODE-001", "code_ref"),
        ]

        for text, expected_type in test_cases:
            content = {"field": text}
            matches = detector.detect_references(content)

            # Find match of expected type
            type_matches = [m for m in matches if m.reference_type == expected_type]
            assert (
                len(type_matches) >= 1
            ), f"Expected {expected_type} for '{text}', got {[m.reference_type for m in matches]}"


class TestExtractionSummaryIntegration:
    """Test integration with extraction pipeline summary."""

    def test_extraction_summary_includes_cross_refs(self):
        """Test that ExtractionSummary includes cross-reference fields."""
        from src.extraction.pipeline import ExtractionSummary

        doc_id = uuid4()
        summary = ExtractionSummary(
            document_id=doc_id,
            sheets_processed=3,
            tables_detected=5,
            records_extracted=100,
            duration_ms=5000,
            warnings=[],
            cross_references_found=10,
            cross_references_resolved=8,
            cross_references_unresolved=2,
        )

        d = summary.to_dict()

        assert d["cross_references_found"] == 10
        assert d["cross_references_resolved"] == 8
        assert d["cross_references_unresolved"] == 2

    def test_extraction_summary_defaults(self):
        """Test that cross-reference fields default to 0."""
        from src.extraction.pipeline import ExtractionSummary

        doc_id = uuid4()
        summary = ExtractionSummary(
            document_id=doc_id,
            sheets_processed=3,
            tables_detected=5,
            records_extracted=100,
            duration_ms=5000,
            warnings=[],
        )

        assert summary.cross_references_found == 0
        assert summary.cross_references_resolved == 0
        assert summary.cross_references_unresolved == 0
