//! Audit manager for orchestrating comprehensive repository and package audits.
//!
//! **What**: Provides the main `AuditManager` that coordinates all audit operations,
//! integrating upgrade detection, changes analysis, dependency graph construction,
//! and health scoring into a unified audit framework.
//!
//! **How**: The manager initializes with a workspace root and configuration, then
//! sets up all necessary subsystems (upgrade manager, changes analyzer, filesystem,
//! monorepo detector) to enable comprehensive auditing across all aspects of the
//! repository.
//!
//! **Why**: To provide a single entry point for all audit operations that handles
//! the complexity of coordinating multiple subsystems while presenting a clean,
//! simple API for users.

use crate::audit::sections::{
    BreakingChangesAuditSection, DependencyAuditSection, UpgradeAuditSection,
    VersionConsistencyAuditSection, audit_dependencies as audit_dependencies_impl,
    audit_upgrades as audit_upgrades_impl,
    audit_version_consistency as audit_version_consistency_impl,
};
use crate::changes::ChangesAnalyzer;
use crate::changeset::{ChangesetManager, FileBasedChangesetStorage};
use crate::config::PackageToolsConfig;
use crate::error::{AuditError, AuditResult};
use crate::types::PackageInfo;
use crate::upgrade::UpgradeManager;
use std::collections::HashSet;
use std::path::PathBuf;
use sublime_git_tools::Repo;
use sublime_standard_tools::filesystem::{AsyncFileSystem, FileSystemManager};
use sublime_standard_tools::monorepo::{MonorepoDetector, MonorepoDetectorTrait};

/// High-level manager for audit and health check operations.
///
/// `AuditManager` is the primary entry point for all audit operations. It orchestrates
/// the complete audit workflow by integrating:
/// - Upgrade manager for detecting available package updates
/// - Changes analyzer for analyzing file and commit changes
/// - Monorepo detector for understanding project structure
/// - Filesystem operations for reading package information
///
/// This provides a unified API that handles all complexity internally, including
/// configuration management, error handling, and coordination between subsystems.
///
/// # Architecture
///
/// The manager follows a composition pattern, aggregating functionality from:
/// - **UpgradeManager**: Detects available dependency upgrades
/// - **ChangesAnalyzer**: Analyzes changes in working directory and commit ranges
/// - **MonorepoDetector**: Detects and manages monorepo structures
/// - **FileSystemManager**: Provides filesystem operations
///
/// # Project Structure Support
///
/// - **Single Package**: Projects with one package.json at the root
/// - **Monorepo**: Projects with multiple packages in workspace structure
///
/// # Examples
///
/// ## Basic initialization
///
/// ```rust,ignore
/// use sublime_pkg_tools::audit::AuditManager;
/// use sublime_pkg_tools::config::PackageToolsConfig;
/// use std::path::PathBuf;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let workspace_root = PathBuf::from(".");
/// let config = PackageToolsConfig::default();
///
/// let manager = AuditManager::new(workspace_root, config).await?;
/// println!("Audit manager initialized");
/// # Ok(())
/// # }
/// ```
///
/// ## With custom configuration
///
/// ```rust,ignore
/// use sublime_pkg_tools::audit::AuditManager;
/// use sublime_pkg_tools::config::PackageToolsConfig;
/// use std::path::PathBuf;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let workspace_root = PathBuf::from(".");
///
/// // Load configuration from file or use custom settings
/// let mut config = PackageToolsConfig::default();
/// config.audit.enabled = true;
/// config.audit.min_severity = "warning".to_string();
///
/// let manager = AuditManager::new(workspace_root, config).await?;
/// # Ok(())
/// # }
/// ```
///
/// ## Future usage (to be implemented in subsequent stories)
///
/// ```rust,ignore
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// # use sublime_pkg_tools::audit::AuditManager;
/// # use sublime_pkg_tools::config::PackageToolsConfig;
/// # use std::path::PathBuf;
/// # let workspace_root = PathBuf::from(".");
/// # let config = PackageToolsConfig::default();
/// let manager = AuditManager::new(workspace_root, config).await?;
///
/// // Run complete audit (TODO: will be implemented in story 10.2+)
/// // let report = manager.run_audit().await?;
/// // println!("Health score: {}/100", report.health_score);
/// # Ok(())
/// # }
/// ```
pub struct AuditManager {
    /// Root directory of the workspace being audited.
    workspace_root: PathBuf,

    /// Upgrade manager for detecting available package updates.
    upgrade_manager: UpgradeManager,

    /// Changes analyzer for analyzing file and commit changes.
    changes_analyzer: ChangesAnalyzer<FileSystemManager>,

    /// Changeset manager for loading pending changesets.
    changeset_manager: ChangesetManager<FileBasedChangesetStorage<FileSystemManager>>,

    /// Filesystem abstraction for file operations.
    fs: FileSystemManager,

    /// Monorepo detector for understanding project structure.
    monorepo_detector: MonorepoDetector<FileSystemManager>,

    /// Configuration for audit operations.
    config: PackageToolsConfig,
}

impl AuditManager {
    /// Creates a new `AuditManager` with the default filesystem.
    ///
    /// This constructor initializes the audit manager with all necessary subsystems:
    /// - Opens and validates the Git repository
    /// - Initializes the upgrade manager for dependency update detection
    /// - Sets up the changes analyzer for change detection
    /// - Configures the monorepo detector for project structure detection
    ///
    /// # Arguments
    ///
    /// * `workspace_root` - Root directory of the workspace to audit
    /// * `config` - Configuration for all audit operations
    ///
    /// # Returns
    ///
    /// Returns a configured `AuditManager` ready to perform audit operations.
    ///
    /// # Errors
    ///
    /// Returns an error if:
    /// - The workspace root doesn't exist or is invalid
    /// - The Git repository cannot be opened or is corrupted
    /// - The upgrade manager cannot be initialized
    /// - The changes analyzer cannot be initialized
    /// - Any configuration validation fails
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// use sublime_pkg_tools::audit::AuditManager;
    /// use sublime_pkg_tools::config::PackageToolsConfig;
    /// use std::path::PathBuf;
    ///
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// let workspace_root = PathBuf::from(".");
    /// let config = PackageToolsConfig::default();
    ///
    /// let manager = AuditManager::new(workspace_root, config).await?;
    /// # Ok(())
    /// # }
    /// ```
    ///
    /// ## With disabled auditing
    ///
    /// ```rust,ignore
    /// # use sublime_pkg_tools::audit::AuditManager;
    /// # use sublime_pkg_tools::config::PackageToolsConfig;
    /// # use std::path::PathBuf;
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// let workspace_root = PathBuf::from(".");
    ///
    /// let mut config = PackageToolsConfig::default();
    /// config.audit.enabled = false;
    ///
    /// // Manager still initializes, but audit operations will check the flag
    /// let manager = AuditManager::new(workspace_root, config).await?;
    /// # Ok(())
    /// # }
    /// ```
    pub async fn new(workspace_root: PathBuf, config: PackageToolsConfig) -> AuditResult<Self> {
        let fs = FileSystemManager::new();
        // Validate workspace root exists
        if !fs.exists(&workspace_root).await {
            return Err(AuditError::InvalidWorkspaceRoot {
                path: workspace_root.clone(),
                reason: "Workspace root does not exist".to_string(),
            });
        }

        // Open Git repository
        let workspace_str =
            workspace_root.to_str().ok_or_else(|| AuditError::InvalidWorkspaceRoot {
                path: workspace_root.clone(),
                reason: "Workspace path contains invalid UTF-8".to_string(),
            })?;

        let git_repo = Repo::open(workspace_str).map_err(|e| AuditError::GitError {
            operation: "open repository".to_string(),
            reason: e.to_string(),
        })?;

        // Initialize monorepo detector
        let monorepo_detector = MonorepoDetector::new();

        // Detect if this is a monorepo to validate the structure
        let _is_monorepo =
            monorepo_detector.is_monorepo_root(&workspace_root).await.map_err(|e| {
                AuditError::WorkspaceAnalysisFailed {
                    reason: format!("Failed to detect monorepo structure: {}", e),
                }
            })?;

        // Initialize upgrade manager
        let upgrade_manager = UpgradeManager::new(workspace_root.clone(), config.upgrade.clone())
            .await
            .map_err(|e| AuditError::UpgradeDetectionFailed {
                reason: format!("Failed to initialize upgrade manager: {}", e),
            })?;

        // Initialize changes analyzer
        let changes_analyzer =
            ChangesAnalyzer::new(workspace_root.clone(), git_repo, fs.clone(), config.clone())
                .await
                .map_err(|e| AuditError::AnalysisFailed {
                    section: "changes".to_string(),
                    reason: format!("Failed to initialize changes analyzer: {}", e),
                })?;

        // Initialize changeset manager
        let changeset_manager =
            ChangesetManager::new(workspace_root.clone(), fs.clone(), config.clone())
                .await
                .map_err(|e| AuditError::WorkspaceAnalysisFailed {
                    reason: format!("Failed to initialize changeset manager: {}", e),
                })?;

        Ok(Self {
            workspace_root,
            upgrade_manager,
            changes_analyzer,
            changeset_manager,
            fs,
            monorepo_detector,
            config,
        })
    }

    /// Returns a reference to the workspace root path.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// # use sublime_pkg_tools::audit::AuditManager;
    /// # use sublime_pkg_tools::config::PackageToolsConfig;
    /// # use std::path::PathBuf;
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// # let workspace_root = PathBuf::from(".");
    /// # let config = PackageToolsConfig::default();
    /// let manager = AuditManager::new(workspace_root.clone(), config).await?;
    /// assert_eq!(manager.workspace_root(), &workspace_root);
    /// # Ok(())
    /// # }
    /// ```
    #[must_use]
    pub fn workspace_root(&self) -> &PathBuf {
        &self.workspace_root
    }

    /// Returns a reference to the configuration.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// # use sublime_pkg_tools::audit::AuditManager;
    /// # use sublime_pkg_tools::config::PackageToolsConfig;
    /// # use std::path::PathBuf;
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// # let workspace_root = PathBuf::from(".");
    /// # let config = PackageToolsConfig::default();
    /// let manager = AuditManager::new(workspace_root, config).await?;
    /// let audit_config = &manager.config().audit;
    /// assert!(audit_config.enabled);
    /// # Ok(())
    /// # }
    /// ```
    #[must_use]
    pub fn config(&self) -> &PackageToolsConfig {
        &self.config
    }

    /// Returns a reference to the upgrade manager.
    ///
    /// This provides access to the underlying upgrade manager for direct
    /// upgrade detection operations if needed.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// # use sublime_pkg_tools::audit::AuditManager;
    /// # use sublime_pkg_tools::config::PackageToolsConfig;
    /// # use std::path::PathBuf;
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// # let workspace_root = PathBuf::from(".");
    /// # let config = PackageToolsConfig::default();
    /// let manager = AuditManager::new(workspace_root, config).await?;
    /// let upgrade_mgr = manager.upgrade_manager();
    /// // Use upgrade manager directly if needed
    /// # Ok(())
    /// # }
    /// ```
    #[must_use]
    pub fn upgrade_manager(&self) -> &UpgradeManager {
        &self.upgrade_manager
    }

    /// Returns a reference to the changes analyzer.
    ///
    /// This provides access to the underlying changes analyzer for direct
    /// change analysis operations if needed.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// # use sublime_pkg_tools::audit::AuditManager;
    /// # use sublime_pkg_tools::config::PackageToolsConfig;
    /// # use std::path::PathBuf;
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// # let workspace_root = PathBuf::from(".");
    /// # let config = PackageToolsConfig::default();
    /// let manager = AuditManager::new(workspace_root, config).await?;
    /// let analyzer = manager.changes_analyzer();
    /// // Use changes analyzer directly if needed
    /// # Ok(())
    /// # }
    /// ```
    #[must_use]
    pub fn changes_analyzer(&self) -> &ChangesAnalyzer<FileSystemManager> {
        &self.changes_analyzer
    }

    /// Returns a reference to the monorepo detector.
    ///
    /// This provides access to the underlying monorepo detector for direct
    /// project structure queries if needed.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// # use sublime_pkg_tools::audit::AuditManager;
    /// # use sublime_pkg_tools::config::PackageToolsConfig;
    /// # use std::path::PathBuf;
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// # let workspace_root = PathBuf::from(".");
    /// # let config = PackageToolsConfig::default();
    /// let manager = AuditManager::new(workspace_root, config).await?;
    /// let detector = manager.monorepo_detector();
    /// let is_monorepo = detector.is_monorepo().await?;
    /// # Ok(())
    /// # }
    /// ```
    #[must_use]
    pub fn monorepo_detector(&self) -> &MonorepoDetector<FileSystemManager> {
        &self.monorepo_detector
    }

    /// Returns a reference to the filesystem.
    ///
    /// This provides access to the underlying filesystem implementation
    /// for direct file operations if needed.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// # use sublime_pkg_tools::audit::AuditManager;
    /// # use sublime_pkg_tools::config::PackageToolsConfig;
    /// # use std::path::PathBuf;
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// # let workspace_root = PathBuf::from(".");
    /// # let config = PackageToolsConfig::default();
    /// let manager = AuditManager::new(workspace_root, config).await?;
    /// let fs = manager.filesystem();
    /// // Use filesystem directly if needed
    /// # Ok(())
    /// # }
    /// ```
    #[must_use]
    pub fn filesystem(&self) -> &FileSystemManager {
        &self.fs
    }

    /// Audits available package upgrades.
    ///
    /// Performs a comprehensive analysis of available dependency upgrades, including:
    /// - Detection of all available upgrades (major, minor, patch)
    /// - Identification of deprecated packages
    /// - Generation of audit issues based on severity
    /// - Categorization of upgrades by package
    ///
    /// # Returns
    ///
    /// An `UpgradeAuditSection` containing all upgrade analysis results.
    ///
    /// # Errors
    ///
    /// Returns `AuditError` if:
    /// - The upgrades section is disabled in configuration
    /// - Upgrade detection fails (network issues, registry errors, etc.)
    /// - Package analysis fails
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// use sublime_pkg_tools::audit::AuditManager;
    /// use sublime_pkg_tools::config::PackageToolsConfig;
    /// use std::path::PathBuf;
    ///
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// let workspace_root = PathBuf::from(".");
    /// let config = PackageToolsConfig::default();
    ///
    /// let manager = AuditManager::new(workspace_root, config).await?;
    /// let section = manager.audit_upgrades().await?;
    ///
    /// println!("Total upgrades: {}", section.total_upgrades);
    /// println!("Major: {}, Minor: {}, Patch: {}",
    ///     section.major_upgrades,
    ///     section.minor_upgrades,
    ///     section.patch_upgrades
    /// );
    /// println!("Deprecated packages: {}", section.deprecated_packages.len());
    /// println!("Issues found: {}", section.issues.len());
    /// # Ok(())
    /// # }
    /// ```
    ///
    /// ## Checking for critical issues
    ///
    /// ```rust,ignore
    /// # use sublime_pkg_tools::audit::AuditManager;
    /// # use sublime_pkg_tools::config::PackageToolsConfig;
    /// # use std::path::PathBuf;
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// # let workspace_root = PathBuf::from(".");
    /// # let config = PackageToolsConfig::default();
    /// # let manager = AuditManager::new(workspace_root, config).await?;
    /// let section = manager.audit_upgrades().await?;
    ///
    /// let critical = section.critical_issue_count();
    /// if critical > 0 {
    ///     println!("WARNING: {} critical issues found!", critical);
    ///     for issue in section.issues.iter().filter(|i| i.is_critical()) {
    ///         println!("  - {}", issue.title);
    ///     }
    /// }
    /// # Ok(())
    /// # }
    /// ```
    pub async fn audit_upgrades(&self) -> AuditResult<UpgradeAuditSection> {
        audit_upgrades_impl(&self.upgrade_manager, &self.config).await
    }

    /// Audits dependency graph for circular dependencies and version conflicts.
    ///
    /// Performs comprehensive dependency analysis including:
    /// - Detection of circular dependencies between workspace packages
    /// - Identification of version conflicts for external dependencies
    /// - Generation of audit issues based on severity
    ///
    /// # Returns
    ///
    /// A `DependencyAuditSection` containing all dependency analysis results.
    ///
    /// # Errors
    ///
    /// Returns `AuditError` if:
    /// - The dependencies section is disabled in configuration
    /// - The dependency graph cannot be constructed
    /// - Package discovery fails
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// use sublime_pkg_tools::audit::AuditManager;
    /// use sublime_pkg_tools::config::PackageToolsConfig;
    /// use std::path::PathBuf;
    ///
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// let workspace_root = PathBuf::from(".");
    /// let config = PackageToolsConfig::default();
    ///
    /// let manager = AuditManager::new(workspace_root, config).await?;
    /// let section = manager.audit_dependencies().await?;
    ///
    /// println!("Circular dependencies: {}", section.circular_dependencies.len());
    /// println!("Version conflicts: {}", section.version_conflicts.len());
    /// println!("Issues found: {}", section.issues.len());
    /// # Ok(())
    /// # }
    /// ```
    ///
    /// ## Checking for critical issues
    ///
    /// ```rust,ignore
    /// # use sublime_pkg_tools::audit::AuditManager;
    /// # use sublime_pkg_tools::config::PackageToolsConfig;
    /// # use std::path::PathBuf;
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// # let workspace_root = PathBuf::from(".");
    /// # let config = PackageToolsConfig::default();
    /// # let manager = AuditManager::new(workspace_root, config).await?;
    /// let section = manager.audit_dependencies().await?;
    ///
    /// let critical = section.critical_issue_count();
    /// if critical > 0 {
    ///     println!("CRITICAL: {} circular dependencies found!", critical);
    ///     for issue in section.issues.iter().filter(|i| i.is_critical()) {
    ///         println!("  - {}", issue.title);
    ///     }
    /// }
    /// # Ok(())
    /// # }
    /// ```
    pub async fn audit_dependencies(&self) -> AuditResult<DependencyAuditSection> {
        // Discover all packages in the workspace
        let packages = self.discover_packages().await?;

        // Call the dependency audit implementation
        audit_dependencies_impl(&self.workspace_root, &packages, &self.config).await
    }

    /// Categorizes all dependencies in the workspace.
    ///
    /// Analyzes all packages and their dependencies, categorizing them into:
    /// - Internal packages: Workspace packages that are used by other packages
    /// - External packages: Registry packages from npm, etc.
    /// - Workspace links: Dependencies using workspace: protocol
    /// - Local links: Dependencies using file:, link:, or portal: protocols
    ///
    /// # Returns
    ///
    /// A `DependencyCategorization` containing all categorized dependencies and statistics.
    ///
    /// # Errors
    ///
    /// Returns `AuditError` if:
    /// - Package detection fails
    /// - Package.json files cannot be read or parsed
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// use sublime_pkg_tools::audit::AuditManager;
    /// use std::path::PathBuf;
    ///
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// let manager = AuditManager::new(PathBuf::from("./my-workspace")).await?;
    /// let categorization = manager.categorize_dependencies().await?;
    ///
    /// println!("Internal packages: {}", categorization.stats.internal_packages);
    /// println!("External packages: {}", categorization.stats.external_packages);
    /// println!("Workspace links: {}", categorization.stats.workspace_links);
    /// println!("Local links: {}", categorization.stats.local_links);
    ///
    /// // Find highly-used internal packages
    /// for pkg in &categorization.internal_packages {
    ///     if pkg.used_by.len() > 5 {
    ///         println!("{} is used by {} packages", pkg.name, pkg.used_by.len());
    ///     }
    /// }
    /// # Ok(())
    /// # }
    /// ```
    pub async fn categorize_dependencies(
        &self,
    ) -> AuditResult<crate::audit::sections::DependencyCategorization> {
        // Discover all packages in the workspace
        let packages = self.discover_packages().await?;

        // Call the categorization implementation
        crate::audit::sections::categorize_dependencies(&packages, &self.config).await
    }

    /// Audits version consistency of internal dependencies across packages.
    ///
    /// This method analyzes all internal dependencies across packages in the workspace
    /// and identifies cases where the same internal package is depended upon with
    /// different version specifications. This helps maintain consistency and prevents
    /// potential runtime issues.
    ///
    /// # Returns
    ///
    /// Returns a `VersionConsistencyAuditSection` containing:
    /// - List of detected version inconsistencies
    /// - Recommended version specifications for each inconsistency
    /// - Generated audit issues based on configuration
    ///
    /// # Errors
    ///
    /// Returns `AuditError` if:
    /// - Package discovery fails
    /// - The version consistency section is disabled in configuration
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// use sublime_pkg_tools::audit::AuditManager;
    /// use sublime_pkg_tools::config::PackageToolsConfig;
    /// use std::path::PathBuf;
    ///
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// let workspace_root = PathBuf::from(".");
    /// let config = PackageToolsConfig::default();
    /// let manager = AuditManager::new(workspace_root, config).await?;
    ///
    /// let section = manager.audit_version_consistency().await?;
    /// println!("Found {} inconsistencies", section.inconsistencies.len());
    ///
    /// for inconsistency in &section.inconsistencies {
    ///     println!("Package: {}", inconsistency.package_name);
    ///     println!("  Recommended: {}", inconsistency.recommended_version);
    ///     println!("  Used by {} packages", inconsistency.versions_used.len());
    /// }
    /// # Ok(())
    /// # }
    /// ```
    pub async fn audit_version_consistency(&self) -> AuditResult<VersionConsistencyAuditSection> {
        // Discover all packages in the workspace
        let packages = self.discover_packages().await?;

        // Collect internal package names
        let internal_package_names: HashSet<String> =
            packages.iter().map(|p| p.name().to_string()).collect();

        // Call the version consistency implementation
        audit_version_consistency_impl(&packages, &internal_package_names, &self.config).await
    }

    /// Discovers all packages in the workspace.
    ///
    /// Detects whether the workspace is a monorepo or single package and
    /// returns information about all packages found.
    ///
    /// # Returns
    ///
    /// A vector of `PackageInfo` containing metadata for each package.
    ///
    /// # Errors
    ///
    /// Returns `AuditError` if:
    /// - Package.json files cannot be read or parsed
    /// - The workspace structure is invalid
    async fn discover_packages(&self) -> AuditResult<Vec<PackageInfo>> {
        // Check if this is a monorepo
        let monorepo_kind =
            self.monorepo_detector.is_monorepo_root(&self.workspace_root).await.map_err(|e| {
                AuditError::WorkspaceAnalysisFailed {
                    reason: format!("Failed to detect monorepo: {}", e),
                }
            })?;

        if monorepo_kind.is_some() {
            // Detect the monorepo structure
            let monorepo =
                self.monorepo_detector.detect_monorepo(&self.workspace_root).await.map_err(
                    |e| AuditError::WorkspaceAnalysisFailed {
                        reason: format!("Failed to detect monorepo: {}", e),
                    },
                )?;

            // Get all workspace packages
            let workspace_packages = monorepo.packages();

            if workspace_packages.is_empty() {
                return Err(AuditError::PackageNotFound { package: "any package".to_string() });
            }

            // Convert workspace packages to PackageInfo
            let mut packages = Vec::with_capacity(workspace_packages.len());
            for workspace_package in workspace_packages {
                let package_json_path = workspace_package.absolute_path.join("package.json");

                // Read package.json file
                let content = self.fs.read_file_string(&package_json_path).await.map_err(|e| {
                    AuditError::FileSystemError {
                        path: package_json_path.clone(),
                        reason: format!("Failed to read file: {}", e),
                    }
                })?;

                // Parse package.json
                let package_json: package_json::PackageJson = serde_json::from_str(&content)
                    .map_err(|e| AuditError::FileSystemError {
                        path: package_json_path.clone(),
                        reason: format!("Failed to parse JSON: {}", e),
                    })?;

                packages.push(PackageInfo::new(
                    package_json,
                    Some(workspace_package.clone()),
                    workspace_package.absolute_path.clone(),
                ));
            }

            Ok(packages)
        } else {
            // Single package project
            let package_json_path = self.workspace_root.join("package.json");
            let content = self.fs.read_file_string(&package_json_path).await.map_err(|e| {
                AuditError::FileSystemError {
                    path: package_json_path.clone(),
                    reason: format!("Failed to read package.json: {}", e),
                }
            })?;

            let package_json: package_json::PackageJson =
                serde_json::from_str(&content).map_err(|e| AuditError::FileSystemError {
                    path: package_json_path.clone(),
                    reason: format!("Failed to parse package.json: {}", e),
                })?;

            Ok(vec![PackageInfo::new(package_json, None, self.workspace_root.clone())])
        }
    }

    /// Audits for potential breaking changes in the workspace.
    ///
    /// Analyzes commits, changesets, and changelogs to detect breaking changes
    /// using conventional commit markers and major version bumps.
    ///
    /// # Returns
    ///
    /// A `BreakingChangesAuditSection` containing:
    /// - Packages with detected breaking changes
    /// - Total count of breaking changes
    /// - Audit issues generated from the analysis
    ///
    /// # Errors
    ///
    /// Returns `AuditError` if:
    /// - Git operations fail
    /// - Changes analysis fails
    /// - Commit parsing fails
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// use sublime_pkg_tools::audit::AuditManager;
    ///
    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
    /// # let manager = AuditManager::new(std::path::PathBuf::from("."), Default::default()).await?;
    /// let breaking_changes = manager.audit_breaking_changes().await?;
    ///
    /// println!("Found {} breaking changes", breaking_changes.total_breaking_changes);
    /// # Ok(())
    /// # }
    /// ```
    pub async fn audit_breaking_changes(&self) -> AuditResult<BreakingChangesAuditSection> {
        use crate::audit::sections::audit_breaking_changes;

        // Get HEAD commit
        let head_commit = "HEAD";

        // Determine the base commit using an intelligent strategy:
        // 1. Try to use the last tag (compare against last release)
        // 2. Try merge-base with main/master (compare against main branch)
        // 3. Fallback to HEAD~10 (last 10 commits)
        let base_commit = self.determine_base_commit()?;

        // Load pending changesets to detect breaking changes from them
        let pending_changesets = self.changeset_manager.list_pending().await.map_err(|e| {
            AuditError::WorkspaceAnalysisFailed {
                reason: format!("Failed to load pending changesets: {}", e),
            }
        })?;

        // Use the first pending changeset if available
        // Multiple changesets will be fully integrated in a future enhancement
        let changeset = pending_changesets.first();

        // Call the breaking changes audit implementation
        audit_breaking_changes(
            &self.changes_analyzer,
            &base_commit,
            head_commit,
            changeset,
            &self.config.audit.breaking_changes,
        )
        .await
    }

    /// Determines the base commit for breaking changes analysis.
    ///
    /// Uses an intelligent strategy to find the most appropriate base commit:
    /// 1. Last Git tag (if available) - compares against last release
    /// 2. Merge-base with main or master branch - compares against main branch
    /// 3. HEAD~10 - last 10 commits as fallback
    ///
    /// # Returns
    ///
    /// The Git reference string to use as the base commit.
    ///
    /// # Errors
    ///
    /// Returns an error if Git operations fail critically.
    fn determine_base_commit(&self) -> AuditResult<String> {
        // Try to get the last tag
        if let Ok(last_tag) = self.changes_analyzer.git_repo().get_last_tag() {
            return Ok(last_tag);
        }

        // Try to get merge-base with main branch
        if let Ok(current_branch) = self.changes_analyzer.git_repo().get_current_branch() {
            // Try main first, then master
            for main_branch in &["main", "master"] {
                if let Ok(merge_base) =
                    self.changes_analyzer.git_repo().get_merge_base(&current_branch, main_branch)
                {
                    return Ok(merge_base);
                }
            }
        }

        // Fallback to last 10 commits
        Ok("HEAD~10".to_string())
    }

    // Future audit methods will be implemented in subsequent stories:
    // - Story 10.7: calculate_health_score() -> u8
    // - Story 10.8: run_audit() -> AuditReport
}
