package com.mosquito.project.job;

import com.mosquito.project.domain.Activity;
import com.mosquito.project.domain.DailyActivityStats;
import com.mosquito.project.persistence.repository.DailyActivityStatsRepository;
import com.mosquito.project.persistence.repository.LinkClickRepository;
import com.mosquito.project.persistence.repository.UserInviteRepository;
import com.mosquito.project.persistence.repository.UserRewardRepository;
import com.mosquito.project.service.ActivityService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.List;

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

@ExtendWith(MockitoExtension.class)
class StatisticsAggregationJobTest {

    @Mock
    private ActivityService activityService;

    @Mock
    private DailyActivityStatsRepository dailyActivityStatsRepository;

    @Mock
    private LinkClickRepository linkClickRepository;

    @Mock
    private UserInviteRepository userInviteRepository;

    @Mock
    private UserRewardRepository userRewardRepository;

    @InjectMocks
    private StatisticsAggregationJob statisticsAggregationJob;

    @BeforeEach
    void setUp() {
        // Setup default mock behavior for real aggregation
        when(linkClickRepository.countViewsByActivityIdAndDateRange(any(), any(), any())).thenReturn(0L);
        when(linkClickRepository.countUniqueVisitorsByActivityIdAndDateRange(any(), any(), any())).thenReturn(0L);
        when(linkClickRepository.countSharesByActivityIdAndDateRange(any(), any(), any())).thenReturn(0L);
        when(userInviteRepository.findByActivityId(any())).thenReturn(Collections.emptyList());
        when(userRewardRepository.findByActivityId(any())).thenReturn(Collections.emptyList());
    }

    @Test
    void whenAggregateStatsForActivity_thenCreatesStats() {
        // Arrange
        Activity activity = new Activity();
        activity.setId(1L);
        activity.setName("Test Activity");
        activity.setStartTime(ZonedDateTime.now());
        activity.setEndTime(ZonedDateTime.now().plusDays(1));

        LocalDate testDate = LocalDate.now();

        // Act
        DailyActivityStats stats = statisticsAggregationJob.aggregateStatsForActivity(activity, testDate);

        // Assert - now uses real aggregation, values are 0 from mocks
        assertNotNull(stats);
        assertEquals(activity.getId(), stats.getActivityId());
        assertEquals(testDate, stats.getStatDate());
        // Values are from real aggregation (0 in this test with mocks)
        assertEquals(0, stats.getViews());
    }
}
