"""
Pipeline integration tests.
Tests the full pipeline components working together.
"""

import pytest
from pathlib import Path
from unittest.mock import patch, MagicMock


def test_pipeline_function_exists():
    """Test that process_stream function exists."""
    from ytqgen.pipeline import process_stream
    assert callable(process_stream)


def test_pipeline_all_components_importable():
    """Test that all pipeline components can be imported."""
    try:
        from ytqgen.audio_processor import download_youtube_audio
        from ytqgen.transcription import transcribe_audio
        from ytqgen.summarizer import summarize_text
        from ytqgen.questionnaire_generator import generate_questionnaire
        from ytqgen.pdf_generator import save_text_as_pdf
        assert True
    except ImportError as e:
        pytest.fail(f"Failed to import pipeline component: {e}")


def test_pipeline_steps_order():
    """Test that pipeline has correct step order."""
    # The pipeline should follow: audio -> transcription -> summarization -> questions -> PDF
    expected_steps = [
        "download_youtube_audio",
        "transcribe_audio",
        "summarize_text",
        "generate_questionnaire",
        "save_text_as_pdf"
    ]
    
    from ytqgen import pipeline
    import inspect
    
    source = inspect.getsource(pipeline.process_stream)
    
    # Verify steps are mentioned in correct order
    last_pos = -1
    for step in expected_steps:
        pos = source.find(step)
        if pos != -1:
            assert pos > last_pos, f"Pipeline step {step} out of order"
            last_pos = pos


def test_questionnaire_dynamic_prompt_generation():
    """Test that questionnaire generator uses dynamic prompts."""
    from ytqgen.questionnaire_generator import build_questionnaire_prompt
    
    # This should exist if prompt generation is dynamic
    assert callable(build_questionnaire_prompt)


def test_questionnaire_distribution_calculation():
    """Test that question distribution is calculated correctly."""
    from ytqgen.questionnaire_generator import calculate_question_distribution
    
    # This function uses config module values, not arguments
    # So we just test that it returns the expected structure
    dist = calculate_question_distribution()
    
    # Check structure exists
    assert 'total' in dist
    assert 'mcq' in dist
    assert 'subjective' in dist
    assert 'total' in dist['mcq']
    assert 'total' in dist['subjective']
    assert 'easy' in dist['mcq']
    assert 'medium' in dist['mcq']
    assert 'hard' in dist['mcq']
    assert 'easy' in dist['subjective']
    assert 'medium' in dist['subjective']
    assert 'hard' in dist['subjective']
    assert 'scenario' in dist['subjective']
    assert 'theoretical' in dist['subjective']


def test_summarizer_word_count_fix():
    """Test that summarizer prints word count correctly."""
    from ytqgen.summarizer import summarize_text
    import inspect
    
    source = inspect.getsource(summarize_text)
    
    # Check that word count printing exists for all providers
    assert 'len(words)' in source or 'word_count' in source


def test_summarizer_token_allocation():
    """Test that summarizer uses proper token allocation for final summary."""
    from ytqgen.summarizer import summarize_text
    import inspect
    
    source = inspect.getsource(summarize_text)
    
    # Check that final summary gets more tokens
    assert 'max_tokens * 2' in source or 'max_tokens*2' in source


@pytest.mark.parametrize("provider", ["openai", "mistral", "groq"])
def test_provider_lazy_loading(provider):
    """Test that providers are lazy-loaded."""
    import sys
    
    # Remove provider modules if already loaded
    modules_to_remove = [k for k in sys.modules.keys() if provider in k.lower()]
    for mod in modules_to_remove:
        del sys.modules[mod]
    
    # Import config - should not import provider yet
    from ytqgen import config
    
    # Provider should not be in sys.modules yet
    assert not any(provider in k.lower() for k in sys.modules.keys())


def test_pipeline_error_handling():
    """Test that pipeline has error handling."""
    from ytqgen.pipeline import process_stream
    import inspect
    
    source = inspect.getsource(process_stream)
    
    # Check for error handling
    assert 'try' in source or 'except' in source or 'raise' in source


def test_config_parameter_loading():
    """Test that config loads all generation parameters."""
    from ytqgen.config import (
        NUM_QUESTIONS,
        MCQ_PERCENTAGE,
        SUBJECTIVE_PERCENTAGE,
        EASY_PERCENTAGE,
        MEDIUM_PERCENTAGE,
        HARD_PERCENTAGE,
        SCENARIO_PERCENTAGE,
        THEORETICAL_PERCENTAGE
    )
    
    # All should be integers
    assert isinstance(NUM_QUESTIONS, int)
    assert isinstance(MCQ_PERCENTAGE, int)
    assert isinstance(SUBJECTIVE_PERCENTAGE, int)
    assert isinstance(EASY_PERCENTAGE, int)
    assert isinstance(MEDIUM_PERCENTAGE, int)
    assert isinstance(HARD_PERCENTAGE, int)
    assert isinstance(SCENARIO_PERCENTAGE, int)
    assert isinstance(THEORETICAL_PERCENTAGE, int)


def test_youtube_url_validation_in_pipeline():
    """Test that pipeline validates YouTube URLs."""
    from ytqgen.cli import validate_youtube_url
    
    # Valid URL should pass
    assert validate_youtube_url("https://youtube.com/watch?v=test") == True
    
    # Invalid URL should raise ValueError
    with pytest.raises(ValueError):
        validate_youtube_url("not_a_youtube_url")


def test_pdf_generator_exists():
    """Test that PDF generator module exists."""
    from ytqgen.pdf_generator import save_text_as_pdf
    assert callable(save_text_as_pdf)


def test_progress_tracking():
    """Test that tqdm is available as a dependency."""
    # Check if tqdm is importable (it's in dependencies)
    try:
        import tqdm
        assert True
    except ImportError:
        pytest.fail("tqdm not available - should be in dependencies")
