use crate::errors::KamError;
use crate::types::kam_toml::KamToml;

use super::args::VersionArgs;

// 处理版本命令
// 可以显示当前版本，也可以bump版本号
/// AUTO-GENERATED BY Kam/scripts/add_missing_docs.py: placeholder documentation for public function 'run'. Replace with real documentation. (2025-12-30T22:23:21Z)
///
/// # Errors
/// Returns `KamError` if kam.toml cannot be loaded, version format is invalid, or file cannot be written.
pub fn run(args: VersionArgs) -> Result<(), KamError> {
    let current_dir = std::env::current_dir()?;
    let mut kam_toml = KamToml::load_from_dir(&current_dir)?;

    if let Some(v) = args.version {
        // 有版本参数，就更新版本
        let new_version = match v.as_str() {
            "major" => bump_version(&kam_toml.prop.version, 0)?, // 主版本号+1
            "minor" => bump_version(&kam_toml.prop.version, 1)?, // 次版本号+1
            "patch" => bump_version(&kam_toml.prop.version, 2)?, // 补丁版本号+1
            _ => {
                // 自定义版本号，先验证格式并规范化为以 v 开头
                validate_version(&v)?;
                if v.starts_with('v') || v.starts_with('V') {
                    v
                } else {
                    format!("v{v}")
                }
            }
        };

        let old_display =
            if kam_toml.prop.version.starts_with('v') || kam_toml.prop.version.starts_with('V') {
                kam_toml.prop.version.clone()
            } else {
                format!("v{}", kam_toml.prop.version)
            };

        if new_version == old_display {
            println!("{}", trf!("Version unchanged: {}", &old_display));
        } else {
            let msg = trf!("Bumped version: {} -> {}", &old_display, &new_version);
            println!("{msg}");
            kam_toml.prop.version = new_version;
        }

        // 更新版本时总是更新versionCode（用当前时间戳）
        // 这样每次发布都有唯一的versionCode
        let old_code = kam_toml.prop.versionCode;
        let new_code = chrono::Utc::now().timestamp_millis();
        println!(
            "{}",
            trf!(
                "Updated versionCode: {} -> {}",
                &old_code.to_string(),
                &new_code.to_string()
            )
        );
        kam_toml.prop.versionCode = new_code;

        // 写回文件
        kam_toml.write_to_dir(&current_dir)?;
    } else {
        // 没有版本参数，就显示当前版本（以 v 开头显示）
        let display_version =
            if kam_toml.prop.version.starts_with('v') || kam_toml.prop.version.starts_with('V') {
                kam_toml.prop.version.clone()
            } else {
                format!("v{}", kam_toml.prop.version)
            };
        println!("{}", trf!("Current version: {}", &display_version));
        println!(
            "{}",
            trf!(
                "Current versionCode: {}",
                &kam_toml.prop.versionCode.to_string()
            )
        );
    }

    Ok(())
}

// 验证版本号格式
// 支持语义化版本（如1.0.0）和预发布版本（如1.0.0-beta1）
fn validate_version(version: &str) -> Result<(), KamError> {
    let s = version.trim();
    if s.is_empty() {
        return Err(KamError::InvalidConfig(crate::i18n::tr(
            "Version cannot be empty",
        )));
    }

    // 不允许多重 v 前缀（例如 vv1.2.3）
    if s.starts_with("vv") || s.starts_with("VV") {
        return Err(KamError::InvalidConfig(trf!(
            "Invalid version '{}': leading 'vv' is not allowed",
            version
        )));
    }

    // 允许单个可选的前缀 'v'（大小写不敏感），解析时去掉前缀
    let naked = if s.starts_with('v') || s.starts_with('V') {
        &s[1..]
    } else {
        s
    };
    match semver::Version::parse(naked) {
        Ok(_) => Ok(()),
        Err(e) => Err(KamError::InvalidConfig(trf!(
            "Invalid version '{}': {}",
            version,
            e
        ))),
    }
}

// Bump版本号
// index: 0=major, 1=minor, 2=patch
// bump后会重置后面的版本号（比如1.2.3 bump minor变成1.3.0）
fn bump_version(current: &str, index: usize) -> Result<String, KamError> {
    // 支持以 v 开头或不带 v 的版本字符串
    let s = current.trim();
    let naked = if s.starts_with('v') || s.starts_with('V') {
        &s[1..]
    } else {
        s
    };

    let mut ver = semver::Version::parse(naked)
        .map_err(|e| KamError::InvalidConfig(trf!("Invalid version '{}': {}", current, e)))?;

    match index {
        0 => {
            ver.major += 1;
            ver.minor = 0;
            ver.patch = 0;
        }
        1 => {
            ver.minor += 1;
            ver.patch = 0;
        }
        2 => {
            ver.patch += 1;
        }
        _ => {
            return Err(KamError::InvalidConfig(crate::i18n::tr(
                "Invalid version format for bumping",
            )));
        }
    }

    // 移除预发布和 build metadata（bump 时清除）
    ver.pre = semver::Prerelease::EMPTY;
    ver.build = semver::BuildMetadata::EMPTY;

    Ok(format!("v{ver}"))
}
