//! Database migration support
//!
//! Provides utilities for migrating data between different database backends.

/// Migration report detailing what was migrated
#[derive(Debug, Clone, Default)]
pub struct MigrationReport {
    /// Number of projects migrated
    pub projects_migrated: usize,
    /// Number of checklist items migrated
    pub checklist_items_migrated: usize,
    /// Number of phase transitions migrated
    pub phase_transitions_migrated: usize,
    /// Number of security assessments migrated
    pub assessments_migrated: usize,
    /// Number of phase history records migrated
    pub phase_history_migrated: usize,
    /// Number of tool configurations migrated
    pub tool_configs_migrated: usize,
    /// Number of team members migrated
    pub team_members_migrated: usize,
    /// Any warnings encountered during migration
    pub warnings: Vec<String>,
    /// Any errors encountered during migration
    pub errors: Vec<String>,
}

impl MigrationReport {
    /// Check if migration was successful (no errors)
    pub fn is_success(&self) -> bool {
        self.errors.is_empty()
    }

    /// Get total items migrated
    pub fn total_items(&self) -> usize {
        self.projects_migrated
            + self.checklist_items_migrated
            + self.phase_transitions_migrated
            + self.assessments_migrated
            + self.phase_history_migrated
            + self.tool_configs_migrated
            + self.team_members_migrated
    }

    /// Add a warning
    pub fn warn(&mut self, warning: String) {
        self.warnings.push(warning);
    }

    /// Add an error
    pub fn error(&mut self, error: String) {
        self.errors.push(error);
    }
}

impl std::fmt::Display for MigrationReport {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        writeln!(f, "Migration Report")?;
        writeln!(f, "=================")?;
        writeln!(f, "Projects: {}", self.projects_migrated)?;
        writeln!(f, "Checklist Items: {}", self.checklist_items_migrated)?;
        writeln!(f, "Phase Transitions: {}", self.phase_transitions_migrated)?;
        writeln!(f, "Assessments: {}", self.assessments_migrated)?;
        writeln!(f, "Phase History: {}", self.phase_history_migrated)?;
        writeln!(f, "Tool Configurations: {}", self.tool_configs_migrated)?;
        writeln!(f, "Team Members: {}", self.team_members_migrated)?;
        writeln!(f, "Total Items: {}", self.total_items())?;

        if !self.warnings.is_empty() {
            writeln!(f, "\nWarnings:")?;
            for warning in &self.warnings {
                writeln!(f, "  - {}", warning)?;
            }
        }

        if !self.errors.is_empty() {
            writeln!(f, "\nErrors:")?;
            for error in &self.errors {
                writeln!(f, "  - {}", error)?;
            }
        }

        if self.is_success() {
            writeln!(f, "\nStatus: SUCCESS ✓")?;
        } else {
            writeln!(f, "\nStatus: FAILED ✗")?;
        }

        Ok(())
    }
}

/// Backup creation strategy
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BackupStrategy {
    /// No backup
    None,
    /// Create backup with timestamp
    AutoTimestamp,
    /// Use specific backup file
    Custom(usize), // For testing, this would be a path in real usage
}

/// Rollback information
#[derive(Debug, Clone)]
pub struct Rollback {
    /// Path to backup file
    pub backup_path: String,
    /// Timestamp of backup
    pub created_at: String,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_migration_report_success() {
        let report = MigrationReport {
            projects_migrated: 5,
            checklist_items_migrated: 50,
            ..Default::default()
        };

        assert!(report.is_success());
        assert_eq!(report.total_items(), 55);
    }

    #[test]
    fn test_migration_report_with_errors() {
        let mut report = MigrationReport::default();
        report.error("Failed to migrate project 1".to_string());

        assert!(!report.is_success());
        assert_eq!(report.errors.len(), 1);
    }

    #[test]
    fn test_migration_report_display() {
        let mut report = MigrationReport {
            projects_migrated: 5,
            checklist_items_migrated: 50,
            ..Default::default()
        };
        report.warn("Some items had missing data".to_string());

        let display_str = report.to_string();
        assert!(display_str.contains("Projects: 5"));
        assert!(display_str.contains("SUCCESS"));
    }
}
