namespace NavisworksTransport.UnitTests.Utils
{
    /// <summary>
    /// UnitsConverter工具类的纯逻辑测试
    /// 测试单位转换计算功能，不依赖Navisworks环境
    /// </summary>
    [TestClass]
    public class UnitsConverterTests
    {
        private const double TOLERANCE = 0.000001; // 浮点数比较精度

        #region 基础单位转换为米测试

        [TestMethod]
        public void GetUnitsToMetersConversionFactor_Millimeters_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetUnitsToMetersConversionFactor(Units.Millimeters);

            // Assert
            Assert.AreEqual(0.001, result, TOLERANCE, "毫米到米的转换系数应该是0.001");
        }

        [TestMethod]
        public void GetUnitsToMetersConversionFactor_Centimeters_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetUnitsToMetersConversionFactor(Units.Centimeters);

            // Assert
            Assert.AreEqual(0.01, result, TOLERANCE, "厘米到米的转换系数应该是0.01");
        }

        [TestMethod]
        public void GetUnitsToMetersConversionFactor_Meters_ReturnsOne()
        {
            // Arrange & Act
            double result = UnitsConverter.GetUnitsToMetersConversionFactor(Units.Meters);

            // Assert
            Assert.AreEqual(1.0, result, TOLERANCE, "米到米的转换系数应该是1.0");
        }

        [TestMethod]
        public void GetUnitsToMetersConversionFactor_Inches_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetUnitsToMetersConversionFactor(Units.Inches);

            // Assert
            Assert.AreEqual(0.0254, result, TOLERANCE, "英寸到米的转换系数应该是0.0254");
        }

        [TestMethod]
        public void GetUnitsToMetersConversionFactor_Feet_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetUnitsToMetersConversionFactor(Units.Feet);

            // Assert
            Assert.AreEqual(0.3048, result, TOLERANCE, "英尺到米的转换系数应该是0.3048");
        }

        [TestMethod]
        public void GetUnitsToMetersConversionFactor_Kilometers_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetUnitsToMetersConversionFactor(Units.Kilometers);

            // Assert
            Assert.AreEqual(1000.0, result, TOLERANCE, "公里到米的转换系数应该是1000.0");
        }

        [TestMethod]
        public void GetUnitsToMetersConversionFactor_Micrometers_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetUnitsToMetersConversionFactor(Units.Micrometers);

            // Assert
            Assert.AreEqual(0.000001, result, TOLERANCE, "微米到米的转换系数应该是0.000001");
        }

        [TestMethod]
        public void GetUnitsToMetersConversionFactor_Yards_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetUnitsToMetersConversionFactor(Units.Yards);

            // Assert
            Assert.AreEqual(0.9144, result, TOLERANCE, "码到米的转换系数应该是0.9144");
        }

        [TestMethod]
        public void GetUnitsToMetersConversionFactor_Miles_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetUnitsToMetersConversionFactor(Units.Miles);

            // Assert
            Assert.AreEqual(1609.43, result, TOLERANCE, "英里到米的转换系数应该是1609.43");
        }

        #endregion

        #region 米转换为各单位测试

        [TestMethod]
        public void GetMetersToUnitsConversionFactor_Millimeters_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetMetersToUnitsConversionFactor(Units.Millimeters);

            // Assert
            Assert.AreEqual(1000.0, result, TOLERANCE, "米到毫米的转换系数应该是1000.0");
        }

        [TestMethod]
        public void GetMetersToUnitsConversionFactor_Centimeters_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetMetersToUnitsConversionFactor(Units.Centimeters);

            // Assert
            Assert.AreEqual(100.0, result, TOLERANCE, "米到厘米的转换系数应该是100.0");
        }

        [TestMethod]
        public void GetMetersToUnitsConversionFactor_Meters_ReturnsOne()
        {
            // Arrange & Act
            double result = UnitsConverter.GetMetersToUnitsConversionFactor(Units.Meters);

            // Assert
            Assert.AreEqual(1.0, result, TOLERANCE, "米到米的转换系数应该是1.0");
        }

        [TestMethod]
        public void GetMetersToUnitsConversionFactor_Inches_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetMetersToUnitsConversionFactor(Units.Inches);

            // Assert
            Assert.AreEqual(39.37, result, TOLERANCE, "米到英寸的转换系数应该是39.37");
        }

        [TestMethod]
        public void GetMetersToUnitsConversionFactor_Feet_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetMetersToUnitsConversionFactor(Units.Feet);

            // Assert
            Assert.AreEqual(3.281, result, TOLERANCE, "米到英尺的转换系数应该是3.281");
        }

        [TestMethod]
        public void GetMetersToUnitsConversionFactor_Kilometers_ReturnsCorrectFactor()
        {
            // Arrange & Act
            double result = UnitsConverter.GetMetersToUnitsConversionFactor(Units.Kilometers);

            // Assert
            Assert.AreEqual(0.001, result, TOLERANCE, "米到公里的转换系数应该是0.001");
        }

        #endregion

        #region 转换系数一致性测试

        [TestMethod]
        public void ConversionFactors_ShouldBeInverse()
        {
            // 测试各种单位的正向和反向转换系数是否互为倒数
            Units[] testUnits = 
            {
                Units.Millimeters, Units.Centimeters, Units.Meters,
                Units.Inches, Units.Feet, Units.Kilometers,
                Units.Micrometers, Units.Yards, Units.Miles
            };

            foreach (var unit in testUnits)
            {
                // Arrange & Act
                double toMeters = UnitsConverter.GetUnitsToMetersConversionFactor(unit);
                double fromMeters = UnitsConverter.GetMetersToUnitsConversionFactor(unit);

                // Assert
                double product = toMeters * fromMeters;
                Assert.AreEqual(1.0, product, TOLERANCE, 
                    $"{unit}的正向和反向转换系数应该互为倒数，但得到: {toMeters} * {fromMeters} = {product}");
            }
        }

        #endregion

        #region 边界值和异常情况测试

        [TestMethod]
        public void GetUnitsToMetersConversionFactor_InvalidUnit_ReturnsDefaultValue()
        {
            // Arrange
            var invalidUnit = (Units)999; // 不存在的单位值

            // Act
            double result = UnitsConverter.GetUnitsToMetersConversionFactor(invalidUnit);

            // Assert
            Assert.AreEqual(1.0, result, TOLERANCE, "无效单位应该返回默认值1.0");
        }

        [TestMethod]
        public void GetMetersToUnitsConversionFactor_InvalidUnit_ReturnsDefaultValue()
        {
            // Arrange
            var invalidUnit = (Units)999; // 不存在的单位值

            // Act
            double result = UnitsConverter.GetMetersToUnitsConversionFactor(invalidUnit);

            // Assert
            Assert.AreEqual(1.0, result, TOLERANCE, "无效单位应该返回默认值1.0");
        }

        #endregion

        #region 实际转换计算测试

        [TestMethod]
        public void ActualConversion_Millimeters_CalculatesCorrectly()
        {
            // 测试实际的距离转换计算
            // 1000毫米应该等于1米

            // Arrange
            double millimeters = 1000.0;
            double expectedMeters = 1.0;

            // Act
            double actualMeters = millimeters * UnitsConverter.GetUnitsToMetersConversionFactor(Units.Millimeters);

            // Assert
            Assert.AreEqual(expectedMeters, actualMeters, TOLERANCE, 
                "1000毫米应该转换为1米");
        }

        [TestMethod]
        public void ActualConversion_Feet_CalculatesCorrectly()
        {
            // 测试实际的距离转换计算
            // 1英尺应该约等于0.3048米

            // Arrange
            double feet = 1.0;
            double expectedMeters = 0.3048;

            // Act
            double actualMeters = feet * UnitsConverter.GetUnitsToMetersConversionFactor(Units.Feet);

            // Assert
            Assert.AreEqual(expectedMeters, actualMeters, TOLERANCE, 
                "1英尺应该转换为0.3048米");
        }

        [TestMethod]
        public void ActualConversion_MetersToFeet_CalculatesCorrectly()
        {
            // 测试实际的距离转换计算
            // 1米应该约等于3.281英尺

            // Arrange
            double meters = 1.0;
            double expectedFeet = 3.281;

            // Act
            double actualFeet = meters * UnitsConverter.GetMetersToUnitsConversionFactor(Units.Feet);

            // Assert
            Assert.AreEqual(expectedFeet, actualFeet, TOLERANCE, 
                "1米应该转换为3.281英尺");
        }

        [TestMethod]
        public void RoundTripConversion_PreservesOriginalValue()
        {
            // 测试往返转换是否保持原始值
            Units[] testUnits = 
            {
                Units.Millimeters, Units.Centimeters, Units.Meters,
                Units.Inches, Units.Feet, Units.Kilometers
            };

            double[] testValues = { 0.0, 1.0, 10.5, 100.0, 1000.0, 0.001 };

            foreach (var unit in testUnits)
            {
                foreach (var originalValue in testValues)
                {
                    // Arrange & Act
                    double toMeters = UnitsConverter.GetUnitsToMetersConversionFactor(unit);
                    double fromMeters = UnitsConverter.GetMetersToUnitsConversionFactor(unit);
                    
                    double meters = originalValue * toMeters;
                    double backToOriginal = meters * fromMeters;

                    // Assert
                    Assert.AreEqual(originalValue, backToOriginal, TOLERANCE, 
                        $"往返转换应该保持原始值 {originalValue} ({unit})，但得到 {backToOriginal}");
                }
            }
        }

        #endregion

        #region 性能和精度测试

        [TestMethod]
        public void ConversionFactors_ShouldBeConsistent()
        {
            // 测试转换系数的一致性和精度
            
            // 已知的精确转换关系
            Assert.AreEqual(1000.0, 
                UnitsConverter.GetUnitsToMetersConversionFactor(Units.Kilometers), 
                TOLERANCE, "公里到米的转换应该精确");

            Assert.AreEqual(0.001, 
                UnitsConverter.GetUnitsToMetersConversionFactor(Units.Millimeters), 
                TOLERANCE, "毫米到米的转换应该精确");

            // 测试英制单位的标准换算
            Assert.AreEqual(0.0254, 
                UnitsConverter.GetUnitsToMetersConversionFactor(Units.Inches), 
                TOLERANCE, "英寸到米的转换应该使用标准换算");

            Assert.AreEqual(0.3048, 
                UnitsConverter.GetUnitsToMetersConversionFactor(Units.Feet), 
                TOLERANCE, "英尺到米的转换应该使用标准换算");
        }

        [TestMethod]
        public void ZeroDistance_ConversionsHandleCorrectly()
        {
            // 测试零距离的转换
            Units[] testUnits = 
            {
                Units.Millimeters, Units.Centimeters, Units.Meters,
                Units.Inches, Units.Feet, Units.Kilometers
            };

            foreach (var unit in testUnits)
            {
                // Arrange & Act
                double zeroInMeters = 0.0 * UnitsConverter.GetUnitsToMetersConversionFactor(unit);
                double zeroFromMeters = 0.0 * UnitsConverter.GetMetersToUnitsConversionFactor(unit);

                // Assert
                Assert.AreEqual(0.0, zeroInMeters, TOLERANCE, 
                    $"零距离转换为米应该保持为零 ({unit})");
                Assert.AreEqual(0.0, zeroFromMeters, TOLERANCE, 
                    $"零米转换为{unit}应该保持为零");
            }
        }

        #endregion
    }
}