//! # 版本管理模块
//!
//! 提供统一的版本号解析、比较和管理功能，支持：
//! - 四段式版本号格式 (major.minor.patch.build)
//! - 版本比较和排序
//! - 基础版本提取
//! - 补丁适用性检查
//! - 版本格式验证

use anyhow::Result;
use serde::{Deserialize, Deserializer, Serialize};
use tracing::error;
use winnow::Parser;
use winnow::ascii::digit1;
use winnow::combinator::{alt, opt, preceded, seq};
use winnow::error::{ContextError, ErrMode};
use winnow::prelude::*;

use std::fmt::{self, Display};
use std::str::FromStr;

/// 版本号结构体，支持四段式版本号 (major.minor.patch.build)
///
/// # 示例
/// - `0.0.13.0` - 基础版本 0.0.13，build level 0
/// - `0.0.13.5` - 基础版本 0.0.13，build level 5 (应用了5个补丁)
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Default)]
pub struct Version {
    /// 主版本号
    pub major: u32,
    /// 次版本号
    pub minor: u32,
    /// 修订版本号
    pub patch: u32,
    /// 构建号/补丁级别
    pub build: u32,
}

/// 从字符串解析版本号
///
/// 支持的格式：
/// - "1.2.3" -> Version { major: 1, minor: 2, patch: 3, build: 0 }
/// - "1.2.3.4" -> Version { major: 1, minor: 2, patch: 3, build: 4 }
///
/// # 示例
/// ```
/// use client_core::version::Version;
///
/// let v1 = Version::from_str("0.0.13.5").unwrap();
/// assert_eq!(v1.major, 0);
/// assert_eq!(v1.minor, 0);
/// assert_eq!(v1.patch, 13);
/// assert_eq!(v1.build, 5);
/// ```
impl FromStr for Version {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> Result<Self> {
        if s.is_empty() {
            return Err(anyhow::anyhow!("Version string cannot be empty"));
        }
        let version =
            Version::parse_version(s).map_err(|e| anyhow::anyhow!("Failed to parse version: {}", e))?;
        Ok(version)
    }
}

impl Version {
    /// 创建新的版本号
    pub fn new(major: u32, minor: u32, patch: u32, build: Option<u32>) -> Self {
        match build {
            Some(build) => Self {
                major,
                minor,
                patch,
                build,
            },
            None => Self::new_without_build(major, minor, patch),
        }
    }
    pub fn new_without_build(major: u32, minor: u32, patch: u32) -> Self {
        Self {
            major,
            minor,
            patch,
            ..Default::default()
        }
    }

    /// 解析版本号,比如"v0.0.13.5"，"v0.1.2"
    fn parse_version(input: &str) -> ModalResult<Version> {
        let mut input_slice = input;

        let (_, major, minor, patch, build) = seq!(
            opt(alt(("v", "V"))),
            digit1.parse_to::<u32>(),
            preceded('.', digit1.parse_to::<u32>()),
            preceded('.', digit1.parse_to::<u32>()),
            opt(preceded('.', digit1.parse_to::<u32>())),
        )
        .parse_next(&mut input_slice)?;

        // 检查是否完全消耗输入
        if !input_slice.is_empty() {
            // 创建一个简单的错误，包含额外的字符信息
            let error_msg = format!(
                "Invalid version format: extra characters '{}' found after '{}'",
                input_slice,
                &input[..input.len() - input_slice.len()]
            );
            error!("{}", error_msg);
            return Err(ErrMode::Cut(ContextError::default()));
        }

        Ok(Version::new(major, minor, patch, build))
    }

    /// 获取基础版本（不包含build级别）
    ///
    /// # 示例
    /// ```
    /// use client_core::version::Version;
    ///
    /// let v = Version::from_str("0.0.13.5").unwrap();
    /// let base = v.base_version();
    /// assert_eq!(base.to_string(), "0.0.13.0");
    /// ```
    pub fn base_version(&self) -> Version {
        Version::new_without_build(self.major, self.minor, self.patch)
    }

    /// 检查是否可以在当前版本上应用指定的补丁
    ///
    /// 补丁只能应用在相同的基础版本上
    ///
    /// # 示例
    /// ```
    /// use client_core::version::Version;
    ///
    /// let current = Version::from_str("0.0.13.2").unwrap();
    /// let patch_target = Version::from_str("0.0.13.0").unwrap();
    /// assert!(current.can_apply_patch(&patch_target));
    ///
    /// let different_base = Version::from_str("0.0.14.0").unwrap();
    /// assert!(!current.can_apply_patch(&different_base));
    /// ```
    pub fn can_apply_patch(&self, patch_base_version: &Version) -> bool {
        self.base_version() == patch_base_version.base_version()
    }

    /// 检查当前版本是否兼容指定的补丁版本
    ///
    /// 当前版本的基础版本必须与补丁版本的基础版本相同，
    /// 且当前的build级别不能超过补丁版本
    pub fn is_compatible_with_patch(&self, patch_version: &Version) -> bool {
        self.base_version() == patch_version.base_version() && self.build <= patch_version.build
    }

    /// 获取版本字符串的简短表示（不包含build为0的情况）
    ///
    /// # 示例
    /// - Version(0, 0, 13, 0) -> "0.0.13"
    /// - Version(0, 0, 13, 5) -> "0.0.13.5"
    pub fn to_short_string(&self) -> String {
        if self.build == 0 {
            format!("{}.{}.{}", self.major, self.minor, self.patch)
        } else {
            self.to_string()
        }
    }

    /// 获取基础版本字符串
    pub fn base_version_string(&self) -> String {
        format!("{}.{}.{}", self.major, self.minor, self.patch)
    }

    /// 验证版本号格式的有效性
    pub fn validate(&self) -> Result<()> {
        // 通常版本号各部分都应该在合理范围内
        if self.major > 999 || self.minor > 999 || self.patch > 999 || self.build > 9999 {
            return Err(anyhow::anyhow!(
                "Version number values are too large and may be invalid"
            ));
        }

        Ok(())
    }
}

impl Display for Version {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{}.{}.{}.{}",
            self.major, self.minor, self.patch, self.build
        )
    }
}

/// 版本号 serde 反序列化
pub fn version_from_str<'de, D>(deserializer: D) -> std::result::Result<Version, D::Error>
where
    D: Deserializer<'de>,
{
    let s = String::deserialize(deserializer)?;
    Version::from_str(&s).map_err(serde::de::Error::custom)
}

/// 版本比较结果
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum VersionComparison {
    /// 版本相同
    Equal,
    /// 当前版本更新
    Newer,
    /// 可以应用补丁升级（同基础版本，更高build级别）
    PatchUpgradeable,
    /// 需要全量升级（不同基础版本）
    FullUpgradeRequired,
}

impl Version {
    /// 与另一个版本进行详细比较
    ///
    /// # 示例
    /// ```
    /// use client_core::version::{Version, VersionComparison};
    ///
    /// let current = Version::from_str("0.0.13.2").unwrap();
    /// let target = Version::from_str("0.0.13.5").unwrap();
    ///
    /// match current.compare_detailed(&target) {
    ///     VersionComparison::PatchUpgradeable => println!("可以通过补丁升级"),
    ///     VersionComparison::FullUpgradeRequired => println!("需要全量升级"),
    ///     _ => {}
    /// }
    /// ```
    pub fn compare_detailed(&self, server_version: &Version) -> VersionComparison {
        if self == server_version {
            return VersionComparison::Equal;
        }

        // 比较基础版本
        if self.can_apply_patch(server_version) {
            // 相同基础版本，比较build级别
            if self.build < server_version.build {
                VersionComparison::PatchUpgradeable
            } else {
                VersionComparison::Newer
            }
        } else {
            // 不同基础版本
            let self_base = self.base_version();
            let server_base = server_version.base_version();
            if self_base < server_base {
                VersionComparison::FullUpgradeRequired
            } else {
                VersionComparison::Newer
            }
        }
    }
}

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

    #[test]
    fn test_version_parsing() {
        // 测试四段式版本号解析
        let v1 = Version::from_str("0.0.13.5").unwrap();
        assert_eq!(v1.major, 0);
        assert_eq!(v1.minor, 0);
        assert_eq!(v1.patch, 13);
        assert_eq!(v1.build, 5);

        // 测试三段式版本号解析（build默认为0）
        let v2 = Version::from_str("1.2.3").unwrap();
        assert_eq!(v2.major, 1);
        assert_eq!(v2.minor, 2);
        assert_eq!(v2.patch, 3);
        assert_eq!(v2.build, 0);

        // 测试无效格式
        assert!(Version::from_str("1.2").is_err());
        assert!(Version::from_str("1.2.3.4.5").is_err());
        assert!(Version::from_str("").is_err());
        assert!(Version::from_str("a.b.c").is_err());
    }

    #[test]
    fn test_version_comparison() {
        let v1 = Version::from_str("0.0.13.5").unwrap();
        let v2 = Version::from_str("0.0.13.2").unwrap();
        let v3 = Version::from_str("0.0.14.0").unwrap();

        // 测试版本比较
        assert!(v1 > v2);
        assert!(v2 < v1);
        assert!(v3 > v1);
        assert!(v3 > v2);

        // 测试相等
        let v4 = Version::from_str("0.0.13.5").unwrap();
        assert_eq!(v1, v4);
    }

    #[test]
    fn test_base_version() {
        let v1 = Version::from_str("0.0.13.5").unwrap();
        let base = v1.base_version();

        assert_eq!(base.major, 0);
        assert_eq!(base.minor, 0);
        assert_eq!(base.patch, 13);
        assert_eq!(base.build, 0);
        assert_eq!(base.to_string(), "0.0.13.0");
    }

    #[test]
    fn test_can_apply_patch() {
        let current = Version::from_str("0.0.13.2").unwrap();
        let patch_target = Version::from_str("0.0.13.0").unwrap();
        let different_base = Version::from_str("0.0.14.0").unwrap();

        assert!(current.can_apply_patch(&patch_target));
        assert!(!current.can_apply_patch(&different_base));
    }

    #[test]
    fn test_version_display() {
        let v = Version::from_str("0.0.13.5").unwrap();
        assert_eq!(v.to_string(), "0.0.13.5");

        let v_short = Version::from_str("0.0.13.0").unwrap();
        assert_eq!(v_short.to_short_string(), "0.0.13");
        assert_eq!(v.to_short_string(), "0.0.13.5");
    }

    #[test]
    fn test_detailed_comparison() {
        let current = Version::from_str("0.0.13.2").unwrap();

        // 相同版本
        let same = Version::from_str("0.0.13.2").unwrap();
        assert_eq!(current.compare_detailed(&same), VersionComparison::Equal);

        // 可以补丁升级
        let patch_upgrade = Version::from_str("0.0.13.5").unwrap();
        assert_eq!(
            current.compare_detailed(&patch_upgrade),
            VersionComparison::PatchUpgradeable
        );

        // 需要全量升级
        let full_upgrade = Version::from_str("0.0.14.0").unwrap();
        assert_eq!(
            current.compare_detailed(&full_upgrade),
            VersionComparison::FullUpgradeRequired
        );

        // 当前版本更新
        let older = Version::from_str("0.0.12.0").unwrap();
        assert_eq!(current.compare_detailed(&older), VersionComparison::Newer);
    }

    #[test]
    fn test_compatibility() {
        let current = Version::from_str("0.0.13.2").unwrap();
        let patch_v1 = Version::from_str("0.0.13.5").unwrap();
        let patch_v2 = Version::from_str("0.0.13.1").unwrap();
        let different_base = Version::from_str("0.0.14.0").unwrap();

        assert!(current.is_compatible_with_patch(&patch_v1));
        assert!(!current.is_compatible_with_patch(&patch_v2)); // build级别更低
        assert!(!current.is_compatible_with_patch(&different_base));
    }

    #[test]
    fn test_validation() {
        let valid_v = Version::from_str("0.0.13.5").unwrap();
        assert!(valid_v.validate().is_ok());

        let invalid_v = Version::new(1000, 1000, 1000, Some(10000));
        assert!(invalid_v.validate().is_err());
    }

    // Task 1.2 验收标准测试
    #[test]
    fn test_task_1_2_acceptance_criteria() {
        // 验收标准：支持四段式版本号解析
        let v1 = Version::from_str("0.0.13.5").expect("应该能解析四段式版本号");
        let v2 = Version::from_str("0.0.13.2").expect("应该能解析四段式版本号");

        // 验收标准：版本比较逻辑正常工作
        assert!(v1 > v2, "版本比较应该正常工作");

        // 验收标准：基础版本提取功能正常
        assert_eq!(v1.base_version(), v2.base_version(), "基础版本应该相同");

        // 验收标准：补丁适用性检查功能正常
        assert!(v1.can_apply_patch(&v2), "补丁适用性检查应该正常工作");

        println!("✅ Task 1.2: 版本管理系统重构 - 验收标准测试通过");
        println!("   - ✅ 四段式版本号解析功能正常");
        println!("   - ✅ 版本比较逻辑正常工作");
        println!("   - ✅ 基础版本提取功能正常");
        println!("   - ✅ 补丁适用性检查功能正常");
        println!("   - ✅ 版本格式验证功能正常");
    }
}
