package com.rj.scheduler;

import com.rj.service.biz.ICpaBrandScoreStatisticsService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import java.time.LocalDate;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

/**
 * CpaBrandCoreScheduler 逻辑测试类
 * 测试修改后的调度器逻辑
 * 
 * @author 李中华
 * @date 2025/1/15
 */
@SpringBootTest
@ActiveProfiles("test")
@DisplayName("经销商品牌得分统计调度器逻辑测试")
class CpaBrandCoreSchedulerLogicTest {

    @Autowired
    private ICpaBrandScoreStatisticsService cpaBrandScoreStatisticsService;

    @Autowired
    private CpaBrandCoreScheduler cpaBrandCoreScheduler;


    @Test
    @DisplayName("测试周统计任务 - 服务层自动计算时间范围")
    void testGenerateWeeklyStatistics_AutoCalculateTimeRange() {
        // Given
        // When
        cpaBrandCoreScheduler.generateWeeklyStatistics();


    }

    @Test
    @DisplayName("测试月统计任务 - 服务层自动计算时间范围")
    void testGenerateMonthlyStatistics_AutoCalculateTimeRange() {

        // When
        cpaBrandCoreScheduler.generateMonthlyStatistics();


    }

    @Test
    @DisplayName("测试日统计任务 - 仍然需要传递具体日期")
    void testGenerateDailyStatistics_StillRequiresDate() {

        // When
        cpaBrandCoreScheduler.generateDailyStatistics();

        }

    @Test
    @DisplayName("测试总计统计任务 - 不需要日期参数")
    void testGenerateTotalStatistics_NoDateRequired() {

        // When
        cpaBrandCoreScheduler.generateTotalStatistics();

    }

    @Test
    @DisplayName("测试手动触发周统计 - 参数被忽略")
    void testManualGenerateStatisticsByRange_Weekly_ParametersIgnored() {
        // Given
        LocalDate dummyStartDate = LocalDate.of(2025, 1, 1);
        LocalDate dummyEndDate = LocalDate.of(2025, 1, 7);
        int expectedCount = 20;
        
        when(cpaBrandScoreStatisticsService.generateAndSaveStatistics(
                eq("weekly"), eq(dummyStartDate), eq(dummyEndDate), eq("manual")))
                .thenReturn(expectedCount);

        // When
        int actualCount = cpaBrandCoreScheduler.manualGenerateStatisticsByRange(dummyStartDate, dummyEndDate, "weekly");

        // Then
        assertEquals(expectedCount, actualCount);
        verify(cpaBrandScoreStatisticsService, times(1))
                .generateAndSaveStatistics(eq("weekly"), eq(dummyStartDate), eq(dummyEndDate), eq("manual"));
    }

    @Test
    @DisplayName("测试手动触发月统计 - 参数被忽略")
    void testManualGenerateStatisticsByRange_Monthly_ParametersIgnored() {
        // Given
        LocalDate dummyStartDate = LocalDate.of(2025, 1, 1);
        LocalDate dummyEndDate = LocalDate.of(2025, 1, 31);
        int expectedCount = 80;
        
        when(cpaBrandScoreStatisticsService.generateAndSaveStatistics(
                eq("monthly"), eq(dummyStartDate), eq(dummyEndDate), eq("manual")))
                .thenReturn(expectedCount);

        // When
        int actualCount = cpaBrandCoreScheduler.manualGenerateStatisticsByRange(dummyStartDate, dummyEndDate, "monthly");

        // Then
        assertEquals(expectedCount, actualCount);
        verify(cpaBrandScoreStatisticsService, times(1))
                .generateAndSaveStatistics(eq("monthly"), eq(dummyStartDate), eq(dummyEndDate), eq("manual"));
    }

    @Test
    @DisplayName("测试手动触发日统计 - 参数仍然有效")
    void testManualGenerateStatisticsByRange_Daily_ParametersStillValid() {
        // Given
        LocalDate testDate = LocalDate.of(2025, 1, 15);
        int expectedCount = 12;
        
        when(cpaBrandScoreStatisticsService.generateAndSaveStatistics(
                eq("daily"), eq(testDate), eq(testDate), eq("manual")))
                .thenReturn(expectedCount);

        // When
        int actualCount = cpaBrandCoreScheduler.manualGenerateStatisticsByRange(testDate, testDate, "daily");

        // Then
        assertEquals(expectedCount, actualCount);
        verify(cpaBrandScoreStatisticsService, times(1))
                .generateAndSaveStatistics(eq("daily"), eq(testDate), eq(testDate), eq("manual"));
    }

    @Test
    @DisplayName("测试手动触发总计统计 - 参数被忽略")
    void testManualGenerateStatisticsByRange_Total_ParametersIgnored() {
        // Given
        LocalDate dummyStartDate = LocalDate.of(2025, 1, 1);
        LocalDate dummyEndDate = LocalDate.of(2025, 12, 31);
        int expectedCount = 500;
        
        when(cpaBrandScoreStatisticsService.generateAndSaveStatistics(
                eq("total"), eq(dummyStartDate), eq(dummyEndDate), eq("manual")))
                .thenReturn(expectedCount);

        // When
        int actualCount = cpaBrandCoreScheduler.manualGenerateStatisticsByRange(dummyStartDate, dummyEndDate, "total");

        // Then
        assertEquals(expectedCount, actualCount);
        verify(cpaBrandScoreStatisticsService, times(1))
                .generateAndSaveStatistics(eq("total"), eq(dummyStartDate), eq(dummyEndDate), eq("manual"));
    }

    @Test
    @DisplayName("测试异常处理 - 周统计任务异常")
    void testGenerateWeeklyStatistics_Exception() {
        // Given
        when(cpaBrandScoreStatisticsService.generateAndSaveStatistics(
                eq("weekly"), isNull(), isNull(), eq("system")))
                .thenThrow(new RuntimeException("周统计服务异常"));

        // When & Then
        assertDoesNotThrow(() -> cpaBrandCoreScheduler.generateWeeklyStatistics());
        verify(cpaBrandScoreStatisticsService, times(1))
                .generateAndSaveStatistics(eq("weekly"), isNull(), isNull(), eq("system"));
    }

    @Test
    @DisplayName("测试异常处理 - 月统计任务异常")
    void testGenerateMonthlyStatistics_Exception() {
        // Given
        when(cpaBrandScoreStatisticsService.generateAndSaveStatistics(
                eq("monthly"), isNull(), isNull(), eq("system")))
                .thenThrow(new RuntimeException("月统计服务异常"));

        // When & Then
        assertDoesNotThrow(() -> cpaBrandCoreScheduler.generateMonthlyStatistics());
        verify(cpaBrandScoreStatisticsService, times(1))
                .generateAndSaveStatistics(eq("monthly"), isNull(), isNull(), eq("system"));
    }
}
