"""Tests for the ClarificationManager."""
import pytest
from datetime import datetime
from unittest.mock import Mock, patch
from bat_genie.clarification_manager import (
    ClarificationManager,
    ClarificationQuestion,
    RequirementAnalysis,
    DevelopmentPlan
)
from dataclasses import asdict

@pytest.fixture
def mock_managers():
    """Create mock managers for testing."""
    context_manager = Mock()
    intelligence_manager = Mock()
    product_manager = Mock()
    engineering_manager = Mock()
    
    # Set up context manager mock
    context_manager.get_project_context.return_value = {
        'clarification_data': {
            'questions': [],
            'analyses': [],
            'plans': []
        }
    }
    
    return {
        'context_manager': context_manager,
        'intelligence_manager': intelligence_manager,
        'product_manager': product_manager,
        'engineering_manager': engineering_manager
    }

@pytest.fixture
def clarification_manager(mock_managers):
    """Create a ClarificationManager instance for testing."""
    return ClarificationManager(
        mock_managers['context_manager'],
        mock_managers['intelligence_manager'],
        mock_managers['product_manager'],
        mock_managers['engineering_manager']
    )

def test_analyze_request_needs_all_clarifications(clarification_manager):
    """Test analyzing a request that needs all types of clarification."""
    request = "make it better"
    
    analysis = clarification_manager.analyze_request(request)
    
    assert 'objectives' in analysis['required_clarifications']
    assert 'scope' in analysis['required_clarifications']
    assert 'technical_constraints' in analysis['required_clarifications']
    assert 'business_context' in analysis['required_clarifications']
    assert len(analysis['suggested_questions']) == 4

def test_analyze_request_clear_objectives(clarification_manager):
    """Test analyzing a request with clear objectives."""
    request = "Our goal is to improve performance by optimizing the database queries"
    
    analysis = clarification_manager.analyze_request(request)
    
    assert 'objectives' not in analysis['required_clarifications']
    assert 'technical_constraints' not in analysis['required_clarifications']
    assert 'scope' in analysis['required_clarifications']
    assert 'business_context' in analysis['required_clarifications']

def test_analyze_request_complete_context(clarification_manager):
    """Test analyzing a request with complete context."""
    request = """
    Our goal is to improve the customer experience by optimizing database performance.
    This will include query optimization and indexing.
    Technical requirements include maintaining response times under 100ms.
    The business value is increased customer satisfaction and reduced churn.
    """
    
    analysis = clarification_manager.analyze_request(request)
    
    assert len(analysis['required_clarifications']) == 0
    assert len(analysis['suggested_questions']) == 0
    assert analysis['clarity_analysis']['clarity_score'] > 0.8

def test_create_question(clarification_manager):
    """Test creating a clarification question."""
    question = clarification_manager.create_question(
        "What is the performance target?",
        "Need to improve performance",
        'technical',
        priority=2
    )
    
    assert isinstance(question, ClarificationQuestion)
    assert question.status == "pending"
    assert question.priority == 2
    assert question.answer is None
    assert question.id.startswith("question_")

def test_record_answer(clarification_manager, mock_managers):
    """Test recording an answer to a clarification question."""
    # Create a question first
    question = clarification_manager.create_question(
        "What is the performance target?",
        "Need to improve performance",
        'technical'
    )
    
    # Record the answer
    updated_question = clarification_manager.record_answer(
        question.id,
        "Response time should be under 100ms"
    )
    
    assert updated_question.status == "answered"
    assert updated_question.answer == "Response time should be under 100ms"
    assert updated_question.answered_at is not None
    
    # Verify insight was added
    mock_managers['context_manager'].add_insight.assert_called_once()

def test_analyze_clarity_ambiguous_terms(clarification_manager):
    """Test analyzing text with ambiguous terms."""
    text = "We need to make it better and do something about these issues"
    
    analysis = clarification_manager._analyze_clarity(text)
    
    assert 'it' in analysis['ambiguous_terms']
    assert 'something' in analysis['ambiguous_terms']
    assert 'these' in analysis['ambiguous_terms']
    assert analysis['clarity_score'] < 0.5

def test_analyze_clarity_clear_text(clarification_manager):
    """Test analyzing clear and specific text."""
    text = "We need to optimize database queries because the current response time exceeds 200ms"
    
    analysis = clarification_manager._analyze_clarity(text)
    
    assert len(analysis['ambiguous_terms']) == 0
    assert len(analysis['missing_context']) == 0
    assert analysis['clarity_score'] > 0.8

def test_create_development_plan(clarification_manager, mock_managers):
    """Test creating a development plan."""
    plan = clarification_manager.create_development_plan(
        title="Database Optimization",
        description="Improve database performance",
        objectives=["Reduce query response time", "Optimize indexes"],
        success_criteria=["Response time < 100ms", "95th percentile < 200ms"],
        constraints=["Zero downtime", "Backward compatible"]
    )
    
    assert isinstance(plan, DevelopmentPlan)
    assert plan.status == "draft"
    assert len(plan.objectives) == 2
    assert len(plan.success_criteria) == 2
    assert len(plan.constraints) == 2
    
    # Verify insight was added
    mock_managers['context_manager'].add_insight.assert_called_once()

def test_invalid_question_id(clarification_manager):
    """Test handling invalid question ID when recording answer."""
    with pytest.raises(ValueError):
        clarification_manager.record_answer(
            "invalid_id",
            "Some answer"
        )

def test_persistence(mock_managers):
    """Test that clarification data is properly persisted."""
    manager = ClarificationManager(
        mock_managers['context_manager'],
        mock_managers['intelligence_manager'],
        mock_managers['product_manager'],
        mock_managers['engineering_manager']
    )
    
    # Create some test data
    question = manager.create_question(
        "Test question?",
        "Test context",
        'technical'
    )
    
    # Verify save was called with dict representation
    mock_managers['context_manager'].update_project_context.assert_called_with({
        'clarification_data': {
            'questions': [asdict(question)],
            'analyses': [],
            'plans': []
        }
    }) 