use std::path::Path;
use crate::types::{PackageManager, Result};
use crate::utils::read_package_json;

pub fn detect_package_manager() -> Result<PackageManager> {
    // 1. 优先检查 package.json 中的 packageManager 字段
    if let Ok(package_json) = read_package_json() {
        if let Some(package_manager_field) = &package_json.package_manager {
            if let Some(manager) = PackageManager::from_package_manager_field(package_manager_field) {
                return Ok(manager);
            }
        }
    }

    // 2. 检查当前目录的锁文件
    if Path::new("pnpm-lock.yaml").exists() {
        return Ok(PackageManager::Pnpm);
    }
    if Path::new("yarn.lock").exists() {
        return Ok(PackageManager::Yarn);
    }
    if Path::new("package-lock.json").exists() {
        return Ok(PackageManager::Npm);
    }

    // 3. 在 monorepo 中，向上查找锁文件
    let mut current_dir = std::env::current_dir()?;
    loop {
        // Rush 检测：如果发现 rush.json，认为是 Rush 项目
        if current_dir.join("rush.json").exists() {
            return Ok(PackageManager::Rush);
        }

        if current_dir.join("pnpm-lock.yaml").exists() {
            return Ok(PackageManager::Pnpm);
        }
        if current_dir.join("yarn.lock").exists() {
            return Ok(PackageManager::Yarn);
        }
        if current_dir.join("package-lock.json").exists() {
            return Ok(PackageManager::Npm);
        }

        // 检查是否到达了文件系统根目录
        if let Some(parent) = current_dir.parent() {
            current_dir = parent.to_path_buf();
        } else {
            break;
        }
    }

    // 4. 默认使用 npm
    Ok(PackageManager::Npm)
}

pub fn is_pnpm_workspace_root() -> bool {
    std::path::Path::new("pnpm-workspace.yaml").exists()
}

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

    #[test]
    fn test_package_manager_from_field() {
        assert!(matches!(
            PackageManager::from_package_manager_field("pnpm@8.6.0"),
            Some(PackageManager::Pnpm)
        ));
        assert!(matches!(
            PackageManager::from_package_manager_field("yarn@1.22.19"),
            Some(PackageManager::Yarn)
        ));
        assert!(matches!(
            PackageManager::from_package_manager_field("npm@9.0.0"),
            Some(PackageManager::Npm)
        ));
        assert!(PackageManager::from_package_manager_field("unknown@1.0.0").is_none());
    }

    #[test]
    fn test_package_manager_from_field_edge_cases() {
        // 测试只有包管理器名称，没有版本号的情况
        assert!(matches!(
            PackageManager::from_package_manager_field("pnpm"),
            Some(PackageManager::Pnpm)
        ));
        assert!(matches!(
            PackageManager::from_package_manager_field("yarn"),
            Some(PackageManager::Yarn)
        ));
        assert!(matches!(
            PackageManager::from_package_manager_field("npm"),
            Some(PackageManager::Npm)
        ));
        
        // 测试空字符串
        assert!(PackageManager::from_package_manager_field("").is_none());
        
        // 测试未知包管理器
        assert!(PackageManager::from_package_manager_field("bun@1.0.0").is_none());
    }
}
