// Integration tests for SurrealDB 3 with server mode
//
// To run these tests, start SurrealDB server in another terminal:
// surreal start --bind 127.0.0.1:8000 memory --user root --pass root
//
// Then run: cargo test --test integration_surrealdb --features surrealdb-backend -- --test-threads=1

#[cfg(all(test, feature = "surrealdb-backend"))]
mod surrealdb_integration_tests {
    use chrono::Utc;
    use syntaxis_core::persistence::{
        Database, DbChecklistItem, DbPhaseTransition, DbProject, DbSecurityAssessment,
        DbTeamMember, SurrealDatabase, SurrealDbBackendConfig, SurrealEngineConfig,
    };
    use uuid::Uuid;

    /// Helper to connect to SurrealDB server.
    ///
    /// Requires: `surreal start --bind 127.0.0.1:8000 memory --user root --pass root`
    async fn get_server_db() -> Result<SurrealDatabase, Box<dyn std::error::Error>> {
        let cfg = SurrealDbBackendConfig {
            core: SurrealEngineConfig::Ws {
                url: "ws://localhost:8000".to_string(),
            },
            hot: SurrealEngineConfig::Ws {
                url: "ws://localhost:8000".to_string(),
            },
            namespace: "test_workspace".to_string(),
            username: Some("root".to_string()),
            password: Some("root".to_string()),
        };

        let db = SurrealDatabase::from_config(&cfg).await?;
        Ok(db)
    }

    // ========================================================================
    // PROJECT CRUD TESTS
    // ========================================================================

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_create_and_retrieve_project() {
        if let Ok(db) = get_server_db().await {
            let project_id = Uuid::new_v4().to_string();
            let project = DbProject {
                id: project_id.clone(),
                name: "Integration Test Project".to_string(),
                version: "0.1.0".to_string(),
                description: "Testing SurrealDB server mode".to_string(),
                project_type: "MultiLang".to_string(),
                current_phase: "Creation".to_string(),
                created_at: Utc::now().to_rfc3339(),
                updated_at: Utc::now().to_rfc3339(),
            };

            // Create
            let created = db.create_project(&project).await;
            assert!(created.is_ok());

            // Retrieve
            let retrieved = db.get_project(&project_id).await;
            assert!(retrieved.is_ok());
            let retrieved = retrieved.unwrap();
            assert!(retrieved.is_some());
            let retrieved_proj = retrieved.unwrap();
            assert_eq!(retrieved_proj.name, "Integration Test Project");
            assert_eq!(retrieved_proj.current_phase, "Creation");

            println!("✓ Create and retrieve project test passed");
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_list_projects() {
        if let Ok(db) = get_server_db().await {
            // Create multiple projects
            for i in 0..3 {
                let project = DbProject {
                    id: Uuid::new_v4().to_string(),
                    name: format!("Project {}", i),
                    version: "0.1.0".to_string(),
                    description: "Test project".to_string(),
                    project_type: "CLI".to_string(),
                    current_phase: "Creation".to_string(),
                    created_at: Utc::now().to_rfc3339(),
                    updated_at: Utc::now().to_rfc3339(),
                };
                let _ = db.create_project(&project).await;
            }

            // List all
            let projects = db.list_projects().await;
            assert!(projects.is_ok());
            let projects = projects.unwrap();
            assert!(projects.len() >= 3);

            println!(
                "✓ List projects test passed (found {} projects)",
                projects.len()
            );
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_update_project() {
        if let Ok(db) = get_server_db().await {
            let project_id = Uuid::new_v4().to_string();
            let mut project = DbProject {
                id: project_id.clone(),
                name: "Original Name".to_string(),
                version: "0.1.0".to_string(),
                description: "Original description".to_string(),
                project_type: "Web".to_string(),
                current_phase: "Creation".to_string(),
                created_at: Utc::now().to_rfc3339(),
                updated_at: Utc::now().to_rfc3339(),
            };

            // Create
            let _ = db.create_project(&project).await;

            // Update
            project.name = "Updated Name".to_string();
            project.current_phase = "Development".to_string();
            project.updated_at = Utc::now().to_rfc3339();

            let updated = db.update_project(&project).await;
            assert!(updated.is_ok());

            // Verify
            let retrieved = db.get_project(&project_id).await.unwrap().unwrap();
            assert_eq!(retrieved.name, "Updated Name");
            assert_eq!(retrieved.current_phase, "Development");

            println!("✓ Update project test passed");
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_delete_project() {
        if let Ok(db) = get_server_db().await {
            let project_id = Uuid::new_v4().to_string();
            let project = DbProject {
                id: project_id.clone(),
                name: "To Delete".to_string(),
                version: "0.1.0".to_string(),
                description: "Will be deleted".to_string(),
                project_type: "CLI".to_string(),
                current_phase: "Creation".to_string(),
                created_at: Utc::now().to_rfc3339(),
                updated_at: Utc::now().to_rfc3339(),
            };

            // Create and delete
            let _ = db.create_project(&project).await;
            let deleted = db.delete_project(&project_id).await;
            assert!(deleted.is_ok());

            // Verify deleted
            let retrieved = db.get_project(&project_id).await;
            assert!(retrieved.is_ok());
            assert!(retrieved.unwrap().is_none());

            println!("✓ Delete project test passed");
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    // ========================================================================
    // CHECKLIST ITEM TESTS
    // ========================================================================

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_create_checklist_item() {
        if let Ok(db) = get_server_db().await {
            let project_id = Uuid::new_v4().to_string();
            let item_id = Uuid::new_v4().to_string();

            // Create project first
            let project = DbProject {
                id: project_id.clone(),
                name: "Checklist Test Project".to_string(),
                version: "0.1.0".to_string(),
                description: "For testing checklists".to_string(),
                project_type: "MultiLang".to_string(),
                current_phase: "Creation".to_string(),
                created_at: Utc::now().to_rfc3339(),
                updated_at: Utc::now().to_rfc3339(),
            };
            let _ = db.create_project(&project).await;

            // Create checklist item
            let item = DbChecklistItem {
                id: item_id.clone(),
                project_id: project_id.clone(),
                phase: "Creation".to_string(),
                task_id: "setup-1".to_string(),
                description: "Initialize project structure".to_string(),
                completed: false,
                completed_at: None,
                created_at: Utc::now().to_rfc3339(),
                task_type: "Setup".to_string(),
                task_priority: "High".to_string(),
                task_due: Some("2025-12-31".to_string()),
                task_estimation: Some("2d".to_string()),
                task_deps: "[]".to_string(),
                task_note: Some("Remember to test".to_string()),
                task_name: Some("Setup".to_string()),
            };

            let created = db.create_checklist_item(&item).await;
            assert!(created.is_ok());

            println!("✓ Create checklist item test passed");
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_get_checklist_items_by_phase() {
        if let Ok(db) = get_server_db().await {
            let project_id = Uuid::new_v4().to_string();

            // Create project
            let project = DbProject {
                id: project_id.clone(),
                name: "Phase Test Project".to_string(),
                version: "0.1.0".to_string(),
                description: "For testing phases".to_string(),
                project_type: "MultiLang".to_string(),
                current_phase: "Creation".to_string(),
                created_at: Utc::now().to_rfc3339(),
                updated_at: Utc::now().to_rfc3339(),
            };
            let _ = db.create_project(&project).await;

            // Create items for Creation phase
            for i in 0..3 {
                let item = DbChecklistItem {
                    id: Uuid::new_v4().to_string(),
                    project_id: project_id.clone(),
                    phase: "Creation".to_string(),
                    task_id: format!("task-{}", i),
                    description: format!("Task {}", i),
                    completed: i == 0, // First one completed
                    completed_at: if i == 0 {
                        Some(Utc::now().to_rfc3339())
                    } else {
                        None
                    },
                    created_at: Utc::now().to_rfc3339(),
                    task_type: "Feature".to_string(),
                    task_priority: "Normal".to_string(),
                    task_due: None,
                    task_estimation: None,
                    task_deps: "[]".to_string(),
                    task_note: None,
                    task_name: Some(format!("Task {}", i)),
                };
                let _ = db.create_checklist_item(&item).await;
            }

            // Get items by phase
            let items = db
                .get_checklist_items_by_phase(&project_id, "Creation")
                .await;
            assert!(items.is_ok());
            let items = items.unwrap();
            assert!(items.len() >= 3);

            // Verify completion status
            let completed_count = items.iter().filter(|i| i.completed).count();
            assert_eq!(completed_count, 1);

            println!(
                "✓ Get checklist items by phase test passed ({} items, {} completed)",
                items.len(),
                completed_count
            );
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_complete_checklist_item() {
        if let Ok(db) = get_server_db().await {
            let project_id = Uuid::new_v4().to_string();
            let item_id = Uuid::new_v4().to_string();

            // Create project
            let project = DbProject {
                id: project_id.clone(),
                name: "Completion Test".to_string(),
                version: "0.1.0".to_string(),
                description: "Test completion".to_string(),
                project_type: "MultiLang".to_string(),
                current_phase: "Creation".to_string(),
                created_at: Utc::now().to_rfc3339(),
                updated_at: Utc::now().to_rfc3339(),
            };
            let _ = db.create_project(&project).await;

            // Create item
            let item = DbChecklistItem {
                id: item_id.clone(),
                project_id: project_id.clone(),
                phase: "Creation".to_string(),
                task_id: "complete-test".to_string(),
                description: "To be completed".to_string(),
                completed: false,
                completed_at: None,
                created_at: Utc::now().to_rfc3339(),
                task_type: "Feature".to_string(),
                task_priority: "High".to_string(),
                task_due: None,
                task_estimation: None,
                task_deps: "[]".to_string(),
                task_note: None,
                task_name: Some("Complete".to_string()),
            };
            let _ = db.create_checklist_item(&item).await;

            // Complete it
            let completed = db.complete_checklist_item(&item_id).await;
            assert!(completed.is_ok());

            println!("✓ Complete checklist item test passed");
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    // ========================================================================
    // PHASE TRANSITION TESTS
    // ========================================================================

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_record_phase_transition() {
        if let Ok(db) = get_server_db().await {
            let project_id = Uuid::new_v4().to_string();

            // Create project
            let project = DbProject {
                id: project_id.clone(),
                name: "Phase Transition Test".to_string(),
                version: "0.1.0".to_string(),
                description: "Test transitions".to_string(),
                project_type: "MultiLang".to_string(),
                current_phase: "Creation".to_string(),
                created_at: Utc::now().to_rfc3339(),
                updated_at: Utc::now().to_rfc3339(),
            };
            let _ = db.create_project(&project).await;

            // Record transition
            let transition = DbPhaseTransition {
                id: Uuid::new_v4().to_string(),
                project_id: project_id.clone(),
                from_phase: "Creation".to_string(),
                to_phase: "Development".to_string(),
                timestamp: Utc::now().to_rfc3339(),
                reason: Some("Setup complete".to_string()),
            };

            let recorded = db.record_phase_transition(&transition).await;
            assert!(recorded.is_ok());

            println!("✓ Record phase transition test passed");
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_get_phase_history() {
        if let Ok(db) = get_server_db().await {
            let project_id = Uuid::new_v4().to_string();

            // Create project
            let project = DbProject {
                id: project_id.clone(),
                name: "History Test".to_string(),
                version: "0.1.0".to_string(),
                description: "Test history".to_string(),
                project_type: "MultiLang".to_string(),
                current_phase: "Creation".to_string(),
                created_at: Utc::now().to_rfc3339(),
                updated_at: Utc::now().to_rfc3339(),
            };
            let _ = db.create_project(&project).await;

            // Record multiple transitions
            for (from, to) in &[
                ("Creation", "Development"),
                ("Development", "Testing"),
                ("Testing", "Publication"),
            ] {
                let transition = DbPhaseTransition {
                    id: Uuid::new_v4().to_string(),
                    project_id: project_id.clone(),
                    from_phase: from.to_string(),
                    to_phase: to.to_string(),
                    timestamp: Utc::now().to_rfc3339(),
                    reason: Some("Phase complete".to_string()),
                };
                let _ = db.record_phase_transition(&transition).await;
            }

            // Get history
            let history = db.get_phase_history(&project_id).await;
            assert!(history.is_ok());
            let history = history.unwrap();
            assert!(history.len() >= 3);

            println!(
                "✓ Get phase history test passed ({} transitions)",
                history.len()
            );
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    // ========================================================================
    // SECURITY ASSESSMENT TESTS
    // ========================================================================

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_create_security_assessment() {
        if let Ok(db) = get_server_db().await {
            let project_id = Uuid::new_v4().to_string();

            // Create project
            let project = DbProject {
                id: project_id.clone(),
                name: "Security Test".to_string(),
                version: "0.1.0".to_string(),
                description: "Test security".to_string(),
                project_type: "MultiLang".to_string(),
                current_phase: "Development".to_string(),
                created_at: Utc::now().to_rfc3339(),
                updated_at: Utc::now().to_rfc3339(),
            };
            let _ = db.create_project(&project).await;

            // Create assessment
            let assessment = DbSecurityAssessment {
                id: Uuid::new_v4().to_string(),
                project_id: project_id.clone(),
                profile: "OWASP".to_string(),
                risk_level: "Medium".to_string(),
                passed_rules: 45,
                failed_rules: 5,
                critical_issues: 0,
                assessment_date: Utc::now().to_rfc3339(),
            };

            let created = db.create_security_assessment(&assessment).await;
            assert!(created.is_ok());

            println!("✓ Create security assessment test passed");
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_get_latest_assessment() {
        if let Ok(db) = get_server_db().await {
            let project_id = Uuid::new_v4().to_string();

            // Create project
            let project = DbProject {
                id: project_id.clone(),
                name: "Latest Assessment Test".to_string(),
                version: "0.1.0".to_string(),
                description: "Test latest".to_string(),
                project_type: "MultiLang".to_string(),
                current_phase: "Development".to_string(),
                created_at: Utc::now().to_rfc3339(),
                updated_at: Utc::now().to_rfc3339(),
            };
            let _ = db.create_project(&project).await;

            // Create multiple assessments
            for i in 0..3 {
                let assessment = DbSecurityAssessment {
                    id: Uuid::new_v4().to_string(),
                    project_id: project_id.clone(),
                    profile: "OWASP".to_string(),
                    risk_level: if i == 2 { "Low" } else { "Medium" }.to_string(),
                    passed_rules: 45 + (i * 5),
                    failed_rules: 5 - i,
                    critical_issues: 0,
                    assessment_date: Utc::now().to_rfc3339(),
                };
                let _ = db.create_security_assessment(&assessment).await;
            }

            // Get latest
            let latest = db.get_latest_assessment(&project_id).await;
            assert!(latest.is_ok());
            let latest = latest.unwrap();
            assert!(latest.is_some());
            let latest = latest.unwrap();
            assert_eq!(latest.risk_level, "Low");

            println!("✓ Get latest assessment test passed");
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    // ========================================================================
    // COMPLETION PERCENTAGE TEST
    // ========================================================================

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_get_completion_percentage() {
        if let Ok(db) = get_server_db().await {
            let project_id = Uuid::new_v4().to_string();

            // Create project
            let project = DbProject {
                id: project_id.clone(),
                name: "Completion Percentage Test".to_string(),
                version: "0.1.0".to_string(),
                description: "Test percentage".to_string(),
                project_type: "MultiLang".to_string(),
                current_phase: "Creation".to_string(),
                created_at: Utc::now().to_rfc3339(),
                updated_at: Utc::now().to_rfc3339(),
            };
            let _ = db.create_project(&project).await;

            // Create 4 items: 2 completed, 2 pending
            for i in 0..4 {
                let item = DbChecklistItem {
                    id: Uuid::new_v4().to_string(),
                    project_id: project_id.clone(),
                    phase: "Creation".to_string(),
                    task_id: format!("pct-{}", i),
                    description: format!("Item {}", i),
                    completed: i < 2,
                    completed_at: if i < 2 {
                        Some(Utc::now().to_rfc3339())
                    } else {
                        None
                    },
                    created_at: Utc::now().to_rfc3339(),
                    task_type: "Feature".to_string(),
                    task_priority: "Normal".to_string(),
                    task_due: None,
                    task_estimation: None,
                    task_deps: "[]".to_string(),
                    task_note: None,
                    task_name: Some(format!("Item {}", i)),
                };
                let _ = db.create_checklist_item(&item).await;
            }

            // Get percentage
            let percentage = db.get_completion_percentage(&project_id, "Creation").await;
            assert!(percentage.is_ok());
            let percentage = percentage.unwrap();
            assert!(percentage > 0.0 && percentage <= 100.0);

            println!(
                "✓ Get completion percentage test passed ({:.1}%)",
                percentage
            );
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    // ========================================================================
    // TEAM MEMBER TESTS
    // ========================================================================

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_create_team_member() {
        if let Ok(db) = get_server_db().await {
            let member = DbTeamMember {
                id: Uuid::new_v4().to_string(),
                name: "John Doe".to_string(),
                email: "john@example.com".to_string(),
            };

            let created = db.create_team_member(&member).await;
            assert!(created.is_ok());

            println!("✓ Create team member test passed");
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_list_team_members() {
        if let Ok(db) = get_server_db().await {
            // Create multiple members
            for i in 0..3 {
                let member = DbTeamMember {
                    id: Uuid::new_v4().to_string(),
                    name: format!("Team Member {}", i),
                    email: format!("member{}@example.com", i),
                };
                let _ = db.create_team_member(&member).await;
            }

            // List all
            let members = db.list_team_members().await;
            assert!(members.is_ok());
            let members = members.unwrap();
            assert!(members.len() >= 3);

            println!(
                "✓ List team members test passed ({} members)",
                members.len()
            );
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }

    // ========================================================================
    // HEALTH CHECK TEST
    // ========================================================================

    #[tokio::test]
    #[ignore = "Requires SurrealDB server running on localhost:8000"]
    async fn test_ping() {
        if let Ok(db) = get_server_db().await {
            let ping = db.ping().await;
            assert!(ping.is_ok());

            println!("✓ Ping test passed (database healthy)");
        } else {
            eprintln!("⚠ Skipping: SurrealDB server not running");
        }
    }
}
