//! Integration tests for syntaxis-core library
//!
//! These tests verify that multiple components work together correctly.

use syntaxis_core::{
    checklist::{Checklist, ChecklistItem},
    config::ProjectConfig,
    phase::PhaseManager,
    ChecklistManager, ProjectPhase, ToolConfig, ToolManager,
};

#[test]
fn test_full_project_lifecycle() {
    // 1. Create project configuration
    let mut config = ProjectConfig::new("integration-test");
    config.project.description = "Integration test project".to_string();
    config.languages = vec!["rust".to_string()];
    config.primary_language = "rust".to_string();

    // 2. Validate config
    assert!(config.validate().is_ok());
    assert_eq!(config.project.name, "integration-test");

    // 3. Initialize phase manager
    let mut phase_manager = PhaseManager::new(ProjectPhase::Creation);
    assert_eq!(phase_manager.current_phase(), ProjectPhase::Creation);

    // 4. Transition through phases
    phase_manager.transition_to(ProjectPhase::Devel, true).ok();
    assert_eq!(phase_manager.current_phase(), ProjectPhase::Devel);

    phase_manager.transition_to(ProjectPhase::Update, true).ok();
    assert_eq!(phase_manager.current_phase(), ProjectPhase::Update);

    // 5. Verify history
    let history = phase_manager.history();
    assert!(history.len() >= 2);
}

#[test]
fn test_tool_management_integration() {
    let mut tool_manager = ToolManager::builtin();

    // 1. Enable tools
    tool_manager.enable_tool("tracking").ok();
    tool_manager.enable_tool("docs").ok();

    // 2. Query tools
    assert!(tool_manager.get_tool("tracking").is_some());
    assert!(tool_manager.get_tool("docs").is_some());
    assert!(tool_manager.get_tool("nonexistent").is_none());

    // 3. Verify tools are enabled
    let tracking_tool = tool_manager.get_tool("tracking");
    assert!(tracking_tool.is_some_and(|t| t.enabled));

    let docs_tool = tool_manager.get_tool("docs");
    assert!(docs_tool.is_some_and(|t| t.enabled));
}

#[test]
fn test_checklist_creation_and_tracking() {
    let mut checklist = Checklist::new(ProjectPhase::Creation);

    // 1. Add items
    checklist.add_item(ChecklistItem::new("setup-repo", "Setup repository"));
    checklist.add_item(ChecklistItem::new("init-docs", "Create initial docs"));

    assert_eq!(checklist.items.len(), 2);

    // 2. Mark items complete
    if let Some(item) = checklist.items.first_mut() {
        item.mark_completed();
    }

    // 3. Verify completion
    let completion = checklist.completion_percentage();
    assert!(completion > 0.0 && completion < 100.0);

    // 4. Export to markdown
    let markdown = checklist.export_to_markdown();
    // Verify markdown contains expected content
    assert!(!markdown.is_empty());
    assert!(markdown.contains("Checklist") || markdown.contains("Creation"));
    assert!(markdown.contains("50")); // 50% completion
}

#[test]
fn test_checklist_manager_multiple_phases() {
    let mut manager = ChecklistManager::new();

    // 1. Load checklists for different phases
    manager.load_checklist(ProjectPhase::Creation).ok();
    manager.load_checklist(ProjectPhase::Devel).ok();

    // 2. Add items to checklists
    manager
        .add_item(
            ProjectPhase::Creation,
            ChecklistItem::new("create-repo", "Create repo"),
        )
        .ok();
    manager
        .add_item(
            ProjectPhase::Devel,
            ChecklistItem::new("write-code", "Write code"),
        )
        .ok();

    // 3. Retrieve and verify
    assert!(manager.get_checklist_mut(ProjectPhase::Creation).is_some());
    assert!(manager.get_checklist_mut(ProjectPhase::Devel).is_some());
    assert!(manager.get_checklist_mut(ProjectPhase::Archive).is_none());
}

#[test]
fn test_phase_transition_validation() {
    let mut manager = PhaseManager::new(ProjectPhase::Devel);

    // 1. Invalid backward transition should fail
    let result = manager.transition_to(ProjectPhase::Creation, true);
    assert!(result.is_err());
    assert_eq!(manager.current_phase(), ProjectPhase::Devel); // Phase unchanged

    // 2. Valid forward transition should succeed
    let result = manager.transition_to(ProjectPhase::Update, true);
    assert!(result.is_ok());
    assert_eq!(manager.current_phase(), ProjectPhase::Update);
}

#[test]
fn test_config_serialization() {
    // 1. Create configuration
    let config = ProjectConfig::new("serialization-test");

    // 2. Convert to TOML
    let toml_str = toml::to_string_pretty(&config).expect("Failed to serialize");
    assert!(toml_str.contains("serialization-test"));

    // 3. Deserialize back
    let deserialized: ProjectConfig = toml::from_str(&toml_str).expect("Failed to deserialize");

    // 4. Verify fields match
    assert_eq!(deserialized.project.name, config.project.name);
    assert_eq!(deserialized.primary_language, config.primary_language);
}

#[test]
fn test_valid_phase_transitions() {
    // Test forward transitions that should work
    let mut manager = PhaseManager::new(ProjectPhase::Creation);
    assert!(manager.transition_to(ProjectPhase::Devel, true).is_ok());
    assert_eq!(manager.current_phase(), ProjectPhase::Devel);

    assert!(manager.transition_to(ProjectPhase::Review, true).is_ok());
    assert_eq!(manager.current_phase(), ProjectPhase::Review);

    assert!(manager.transition_to(ProjectPhase::Publish, true).is_ok());
    assert_eq!(manager.current_phase(), ProjectPhase::Publish);
}

#[test]
fn test_tool_config_builder() {
    let tool = ToolConfig::new("my-tool")
        .enable()
        .with_phases(vec![ProjectPhase::Devel]);

    assert_eq!(tool.name, "my-tool");
    assert!(tool.enabled);
    assert!(tool.phases.contains(&ProjectPhase::Devel));
}

#[test]
fn test_checklist_completion_calculation() {
    let mut checklist = Checklist::new(ProjectPhase::Review);

    // Add 3 items
    let mut item1 = ChecklistItem::new("item1", "First");
    let mut item2 = ChecklistItem::new("item2", "Second");
    let item3 = ChecklistItem::new("item3", "Third");

    // Complete 2 items
    item1.mark_completed();
    item2.mark_completed();

    checklist.add_item(item1);
    checklist.add_item(item2);
    checklist.add_item(item3);

    // Verify completion: 2/3 = 66.67%
    let completion = checklist.completion_percentage();
    assert!((completion - 66.666664).abs() < 0.01);
}

#[test]
fn test_checklist_item_properties() {
    let mut item = ChecklistItem::new("task-1", "Complete unit test");

    // Initially incomplete
    assert!(!item.completed);
    assert!(item.completed_at.is_none());

    // Mark complete
    item.mark_completed();
    assert!(item.completed);
    assert!(item.completed_at.is_some());

    // Mark incomplete again
    item.mark_incomplete();
    assert!(!item.completed);
    assert!(item.completed_at.is_none());
}

#[test]
fn test_integrated_workflow() {
    // Simulate a complete workflow
    let _config = ProjectConfig::new("workflow-test");
    let mut phase_manager = PhaseManager::new(ProjectPhase::Creation);
    let mut tool_manager = ToolManager::builtin();
    let mut checklist_manager = ChecklistManager::new();

    // Setup tools
    tool_manager.enable_tool("tracking").ok();
    tool_manager.enable_tool("docs").ok();

    // Setup checklist for Creation phase
    checklist_manager
        .load_checklist(ProjectPhase::Creation)
        .ok();
    checklist_manager
        .add_item(
            ProjectPhase::Creation,
            ChecklistItem::new("setup", "Setup environment"),
        )
        .ok();

    // Verify initial state
    assert_eq!(phase_manager.current_phase(), ProjectPhase::Creation);
    assert_eq!(tool_manager.list_tools().len(), 2);
    assert!(checklist_manager
        .get_checklist_mut(ProjectPhase::Creation)
        .is_some());

    // Transition to Devel
    phase_manager.transition_to(ProjectPhase::Devel, true).ok();

    // Add Devel phase checklist
    checklist_manager.load_checklist(ProjectPhase::Devel).ok();
    checklist_manager
        .add_item(
            ProjectPhase::Devel,
            ChecklistItem::new("code", "Write code"),
        )
        .ok();

    // Verify new state
    assert_eq!(phase_manager.current_phase(), ProjectPhase::Devel);
    assert!(checklist_manager
        .get_checklist_mut(ProjectPhase::Devel)
        .is_some());

    // Transition to Review
    phase_manager.transition_to(ProjectPhase::Review, true).ok();
    assert_eq!(phase_manager.current_phase(), ProjectPhase::Review);

    // Verify transition history
    let history = phase_manager.history();
    assert_eq!(history.len(), 2);
}
