"""Integration tests for v1.2.x features."""

import pytest
import json
from pathlib import Path
from unittest.mock import Mock, patch
from sourcescribe.engine.generator import DocumentationGenerator
from sourcescribe.config.models import SourceScribeConfig, LLMConfig
from sourcescribe.api.base import LLMResponse


@pytest.fixture
def sample_project(tmp_path):
    """Create a sample project structure."""
    project = tmp_path / "sample-project"
    project.mkdir()
    
    # Create package.json
    package_json = project / "package.json"
    package_json.write_text(json.dumps({
        "name": "awesome-app",
        "version": "1.0.0"
    }))
    
    # Create source files
    src = project / "src"
    src.mkdir()
    (src / "index.js").write_text("console.log('Hello');")
    (src / "utils.js").write_text("export const add = (a, b) => a + b;")
    
    # Create README
    (project / "README.md").write_text("# Awesome App")
    
    # Create website directory
    website = project / "website"
    website.mkdir()
    (website / "package.json").write_text('{}')
    
    return project


@pytest.fixture
def mock_llm_provider():
    """Create a mock LLM provider."""
    provider = Mock()
    provider.generate.return_value = LLMResponse(
        content="A modern application for managing tasks",
        model="test-model",
        usage={"total_tokens": 20}
    )
    return provider


def test_end_to_end_documentation_generation(sample_project, mock_llm_provider):
    """Test complete documentation generation workflow."""
    config = SourceScribeConfig()
    config.repository.path = str(sample_project)
    config.output.path = str(sample_project / "website" / "docs")
    config.repository.github_url = "https://github.com/testorg/awesome-app"
    
    # Create output directory
    Path(config.output.path).mkdir(parents=True, exist_ok=True)
    
    generator = DocumentationGenerator(config)
    generator.llm_provider = mock_llm_provider
    
    # Run generation
    with patch.object(generator, '_analyze_file') as mock_analyze:
        mock_analyze.return_value = {
            'path': str(sample_project / 'src' / 'index.js'),
            'name': 'index.js',
            'language': 'javascript',
            'lines': 1,
            'size': 20,
            'elements': [],
            'imports': [],
            'content': "console.log('Hello');"
        }
        
        generator.generate_documentation()
    
    # Check outputs
    output_path = Path(config.output.path)
    assert output_path.exists()
    
    # Check sidebar was generated
    sidebar_path = sample_project / "website" / "sidebars.ts"
    assert sidebar_path.exists()
    sidebar_content = sidebar_path.read_text()
    assert "tutorialSidebar" in sidebar_content
    assert "Auto-generated by SourceScribe" in sidebar_content
    
    # Check docusaurus config was generated
    config_path = sample_project / "website" / "docusaurus.config.ts"
    assert config_path.exists()
    config_content = config_path.read_text()
    assert "title: 'Awesome App'" in config_content
    assert "mermaid: true" in config_content
    assert "organizationName: 'testorg'" in config_content


def test_sidebar_reflects_actual_structure(sample_project, mock_llm_provider):
    """Test that generated sidebar matches actual documentation structure."""
    config = SourceScribeConfig()
    config.repository.path = str(sample_project)
    config.output.path = str(sample_project / "website" / "docs")
    
    # Create docs with specific structure
    docs_path = Path(config.output.path)
    docs_path.mkdir(parents=True, exist_ok=True)
    
    (docs_path / "README.md").write_text("# Documentation")
    
    overview = docs_path / "overview"
    overview.mkdir()
    (overview / "index.md").write_text("# Overview")
    (overview / "architecture.md").write_text("# Architecture")
    
    features = docs_path / "features"
    features.mkdir()
    (features / "index.md").write_text("# Features")
    
    # Create website structure
    website = sample_project / "website"
    website.mkdir(exist_ok=True)
    (website / "package.json").write_text('{}')
    
    generator = DocumentationGenerator(config)
    generator.llm_provider = mock_llm_provider
    
    # Generate sidebar
    analyses = []
    generator._generate_docusaurus_sidebar(analyses)
    
    # Check sidebar
    sidebar_path = website / "sidebars.ts"
    sidebar_content = sidebar_path.read_text()
    
    # Should include both categories
    assert "'overview/index'" in sidebar_content or '"overview/index"' in sidebar_content
    assert "'overview/architecture'" in sidebar_content or '"overview/architecture"' in sidebar_content
    assert "'features/index'" in sidebar_content or '"features/index"' in sidebar_content


def test_cloud_storage_protection(tmp_path):
    """Test that cloud storage paths are properly excluded."""
    from sourcescribe.utils.file_utils import find_files
    
    # Create structure with cloud storage
    project = tmp_path / "project"
    project.mkdir()
    
    # Create normal files
    src = project / "src"
    src.mkdir()
    (src / "app.py").write_text("print('hello')")
    
    # Create cloud storage paths
    cloud = project / "Library" / "CloudStorage" / "GoogleDrive-user@gmail.com"
    cloud.mkdir(parents=True)
    (cloud / "bad_file.py").write_text("# Should be excluded")
    
    config = SourceScribeConfig()
    config.repository.path = str(project)
    
    files = find_files(
        str(project),
        include_patterns=["*.py"],
        exclude_patterns=config.repository.exclude_patterns
    )
    
    # Should only find the app.py, not the cloud storage file
    assert len(files) == 1
    assert files[0].endswith("app.py")


def test_tagline_generation_with_fallback(sample_project):
    """Test tagline generation with fallback on error."""
    config = SourceScribeConfig()
    config.repository.path = str(sample_project)
    config.output.path = str(sample_project / "website" / "docs")
    
    # Create website structure
    website = sample_project / "website"
    website.mkdir(exist_ok=True)
    (website / "package.json").write_text('{}')
    Path(config.output.path).mkdir(parents=True, exist_ok=True)
    
    generator = DocumentationGenerator(config)
    
    # Make LLM fail
    generator.llm_provider.generate.side_effect = Exception("API Error")
    
    # Should use fallback
    tagline = generator._generate_tagline([])
    assert tagline == "Auto-generated documentation for your project"


def test_mermaid_config_in_generated_docusaurus(sample_project, mock_llm_provider):
    """Test that Mermaid configuration is properly set up."""
    config = SourceScribeConfig()
    config.repository.path = str(sample_project)
    config.output.path = str(sample_project / "website" / "docs")
    config.repository.github_url = "https://github.com/test/repo"
    
    website = sample_project / "website"
    website.mkdir(exist_ok=True)
    Path(config.output.path).mkdir(parents=True, exist_ok=True)
    
    generator = DocumentationGenerator(config)
    generator.llm_provider = mock_llm_provider
    
    generator._update_docusaurus_config([])
    
    config_path = website / "docusaurus.config.ts"
    content = config_path.read_text()
    
    # Check Mermaid is enabled
    assert "markdown: {" in content
    assert "mermaid: true" in content
    assert "themes: ['@docusaurus/theme-mermaid']" in content
    
    # Check Mermaid theme configuration
    assert "mermaid: {" in content
    assert "theme: {light: 'neutral', dark: 'dark'}" in content
    assert "fontSize: 16" in content
    
    # Ensure no Tutorial references
    assert "Tutorial" not in content
    assert "/docs/intro" not in content
