using System;
using System.Collections.Generic;
using Xunit;
using Haoliang.Models.Production;
using Haoliang.Models.Device;

namespace Haoliang.Tests
{
    public class ProductionCalculatorTests
    {
        [Fact]
        public void CalculateProduction_WithSameProgramAndIncrementingCounts_ReturnsDifference()
        {
            // Arrange
            var lastStatus = new DeviceCurrentStatus
            {
                NCProgram = "O0001",
                CumulativeCount = 100
            };

            var currentStatus = new DeviceCurrentStatus
            {
                NCProgram = "O0001",
                CumulativeCount = 120
            };

            // Act
            var production = ProductionCalculator.CalculateProduction(currentStatus, lastStatus);

            // Assert
            Assert.Equal(20, production);
        }

        [Fact]
        public void CalculateProduction_WithSameProgramAndDecreasingCounts_ReturnsZero()
        {
            // Arrange
            var lastStatus = new DeviceCurrentStatus
            {
                NCProgram = "O0001",
                CumulativeCount = 120
            };

            var currentStatus = new DeviceCurrentStatus
            {
                NCProgram = "O0001",
                CumulativeCount = 100
            };

            // Act
            var production = ProductionCalculator.CalculateProduction(currentStatus, lastStatus);

            // Assert
            Assert.Equal(0, production); // 异常值保护，避免负数
        }

        [Fact]
        public void CalculateProduction_WithProgramSwitch_ReturnsCurrentCount()
        {
            // Arrange
            var lastStatus = new DeviceCurrentStatus
            {
                NCProgram = "O0001",
                CumulativeCount = 100
            };

            var currentStatus = new DeviceCurrentStatus
            {
                NCProgram = "O0002", // 程序切换
                CumulativeCount = 50
            };

            // Act
            var production = ProductionCalculator.CalculateProduction(currentStatus, lastStatus);

            // Assert
            Assert.Equal(50, production); // 新程序以当前累计数为起点
        }

        [Fact]
        public void CalculateProduction_WithReturnToPreviousProgram_ReturnsZero()
        {
            // Arrange
            var lastStatus = new DeviceCurrentStatus
            {
                NCProgram = "O0001",
                CumulativeCount = 100
            };

            var currentStatus = new DeviceCurrentStatus
            {
                NCProgram = "O0002", // 先切换到新程序
                CumulativeCount = 150
            };

            var secondStatus = new DeviceCurrentStatus
            {
                NCProgram = "O0001", // 切回历史程序
                CumulativeCount = 200
            };

            // Act
            var production = ProductionCalculator.CalculateProduction(secondStatus, lastStatus);

            // Assert (从O0001直接跳到O0001，视为重新开始，所以应该返回0)
            Assert.Equal(0, production); // 切回历史程序，视为重新开始
        }

        [Fact]
        public void IsNewProgram_WithDifferentPrograms_ReturnsTrue()
        {
            // Arrange
            var currentProgram = "O0002";
            var lastProgram = "O0001";

            // Act
            var isNew = ProductionCalculator.IsNewProgram(currentProgram, lastProgram);

            // Assert
            Assert.True(isNew);
        }

        [Fact]
        public void IsNewProgram_WithSameProgram_ReturnsFalse()
        {
            // Arrange
            var currentProgram = "O0001";
            var lastProgram = "O0001";

            // Act
            var isNew = ProductionCalculator.IsNewProgram(currentProgram, lastProgram);

            // Assert
            Assert.False(isNew);
        }

        [Fact]
        public void CrossDayReset_WithDifferentDates_ShouldHandleCrossDay()
        {
            // Arrange
            var lastStatus = new DeviceCurrentStatus
            {
                RecordTime = new DateTime(2024, 1, 1, 23, 59, 59)
            };

            var currentStatus = new DeviceCurrentStatus
            {
                RecordTime = new DateTime(2024, 1, 2, 0, 0, 1) // 跨天
            };

            // Act
            ProductionCalculator.CrossDayReset(currentStatus, lastStatus);

            // Assert (这里只是验证不会抛出异常)
            Assert.True(true);
        }

        [Fact]
        public void CrossDayReset_WithSameDate_ShouldNotReset()
        {
            // Arrange
            var lastStatus = new DeviceCurrentStatus
            {
                RecordTime = new DateTime(2024, 1, 1, 10, 0, 0)
            };

            var currentStatus = new DeviceCurrentStatus
            {
                RecordTime = new DateTime(2024, 1, 1, 10, 30, 0) // 同一天
            };

            // Act
            ProductionCalculator.CrossDayReset(currentStatus, lastStatus);

            // Assert (这里只是验证不会抛出异常)
            Assert.True(true);
        }

        [Fact]
        public void ProductionCalculator_WithLargeProductionNumber_HandlesCorrectly()
        {
            // Arrange
            var lastStatus = new DeviceCurrentStatus
            {
                NCProgram = "O0001",
                CumulativeCount = 1000000
            };

            var currentStatus = new DeviceCurrentStatus
            {
                NCProgram = "O0001",
                CumulativeCount = 1005000
            };

            // Act
            var production = ProductionCalculator.CalculateProduction(currentStatus, lastStatus);

            // Assert
            Assert.Equal(5000, production);
        }
    }
}