"""Tests for Stage 3: Issue Routing."""

from __future__ import annotations

import pytest

from reviewiq_pipeline.stages.stage3_route import Stage3Router
from reviewiq_pipeline.validation.validators import Stage3Validator


class TestStage3Router:
    """Tests for Stage 3 router."""

    def test_generate_routing_key(self):
        """Test routing key generation."""
        from reviewiq_pipeline.config import Config

        config = Config()
        router = Stage3Router(config)

        span = {
            "span_id": "test-span",
            "business_id": "acme-corp",
            "place_id": "place123",
            "urt_primary": "J1.01",
            "valence": "V-",
            "intensity": "I3",
            "entity_normalized": "mike",
            "review_time": "2026-01-20T14:30:00Z",
            "confidence": "high",
            "trust_score": 0.85,
        }

        key = router._generate_routing_key(span)
        assert key == "acme-corp|place123|J1.01|mike"

    def test_generate_routing_key_no_entity(self):
        """Test routing key generation without entity."""
        from reviewiq_pipeline.config import Config

        config = Config()
        router = Stage3Router(config)

        span = {
            "span_id": "test-span",
            "business_id": "acme-corp",
            "place_id": "place123",
            "urt_primary": "J1.01",
            "valence": "V-",
            "intensity": "I3",
            "entity_normalized": None,
            "review_time": "2026-01-20T14:30:00Z",
            "confidence": "high",
            "trust_score": 0.85,
        }

        key = router._generate_routing_key(span)
        assert key == "acme-corp|place123|J1.01|"

    def test_generate_issue_id(self):
        """Test deterministic issue ID generation."""
        from reviewiq_pipeline.config import Config

        config = Config()
        router = Stage3Router(config)

        key1 = "acme-corp|place123|J1.01|"
        key2 = "acme-corp|place123|J1.01|"
        key3 = "acme-corp|place123|J1.02|"

        id1 = router._generate_issue_id(key1)
        id2 = router._generate_issue_id(key2)
        id3 = router._generate_issue_id(key3)

        # Same key = same ID
        assert id1 == id2
        # Different key = different ID
        assert id1 != id3
        # Format check
        assert id1.startswith("ISS-")
        assert len(id1) == 20  # ISS- + 16 hex chars

    def test_route_span_sync(self):
        """Test synchronous span routing."""
        from reviewiq_pipeline.config import Config

        config = Config()
        router = Stage3Router(config)

        span = {
            "span_id": "test-span",
            "business_id": "acme-corp",
            "place_id": "place123",
            "urt_primary": "J1.01",
            "valence": "V-",
            "intensity": "I3",
            "entity_normalized": None,
            "review_time": "2026-01-20T14:30:00Z",
            "confidence": "high",
            "trust_score": 0.85,
        }

        result = router.route_span_sync(span)

        assert result["span_id"] == "test-span"
        assert result["issue_id"].startswith("ISS-")
        assert "J1.01" in result["routing_key"]

    def test_route_span_rejects_positive(self):
        """Test that positive spans cannot be routed."""
        from reviewiq_pipeline.config import Config

        config = Config()
        router = Stage3Router(config)

        span = {
            "span_id": "test-span",
            "business_id": "acme-corp",
            "place_id": "place123",
            "urt_primary": "O1.01",
            "valence": "V+",  # Positive
            "intensity": "I2",
            "entity_normalized": None,
            "review_time": "2026-01-20T14:30:00Z",
            "confidence": "high",
            "trust_score": 0.85,
        }

        with pytest.raises(ValueError, match="Cannot route positive span"):
            router.route_span_sync(span)


class TestStage3Validation:
    """Tests for Stage 3 validation."""

    def test_validate_valid_output(self, sample_stage3_output):
        """Test validation of valid Stage 3 output."""
        validator = Stage3Validator()
        result = validator.validate_sync(sample_stage3_output)

        assert result["stage"] == "stage3"
        assert result["passed"] is True

    def test_validate_invalid_issue_id(self, sample_stage3_output):
        """Test validation catches invalid issue ID format."""
        sample_stage3_output["routed_spans"][0]["issue_id"] = "INVALID"

        validator = Stage3Validator()
        result = validator.validate_sync(sample_stage3_output)

        assert result["passed"] is False
        assert any(e["rule"] == "V3.1" for e in result["errors"])

    def test_validate_empty_routing_key(self, sample_stage3_output):
        """Test validation catches empty routing key."""
        sample_stage3_output["routed_spans"][0]["routing_key"] = ""

        validator = Stage3Validator()
        result = validator.validate_sync(sample_stage3_output)

        assert result["passed"] is False
        assert any(e["rule"] == "V3.2" for e in result["errors"])
