package org.springblade.modules.martial.service.impl;

import org.junit.jupiter.api.DisplayName;
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 org.springblade.modules.martial.excel.ScheduleExportExcel;
import org.springblade.modules.martial.excel.ScheduleExportExcel2;
import org.springblade.modules.martial.mapper.MartialScheduleGroupMapper;
import org.springblade.modules.martial.pojo.vo.ScheduleGroupDetailVO;
import org.springblade.modules.martial.service.IMartialProjectService;

import java.util.ArrayList;
import java.util.List;

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

@ExtendWith(MockitoExtension.class)
@DisplayName("ScheduleExportService Unit Tests")
class ScheduleExportServiceImplTest {

    @Mock
    private MartialScheduleGroupMapper scheduleGroupMapper;

    @Mock
    private IMartialProjectService projectService;

    @InjectMocks
    private ScheduleExportServiceImpl scheduleExportService;

    @Test
    @DisplayName("Should return empty list when no schedule details")
    void shouldReturnEmptyListWhenNoDetails() {
        Long competitionId = 1L;
        when(scheduleGroupMapper.selectScheduleGroupDetails(competitionId)).thenReturn(new ArrayList<>());

        List<ScheduleExportExcel> result = scheduleExportService.exportSchedule(competitionId);

        assertNotNull(result);
        assertTrue(result.isEmpty());
        verify(scheduleGroupMapper).selectScheduleGroupDetails(competitionId);
    }

    @Test
    @DisplayName("Should export schedule with participants")
    void shouldExportScheduleWithParticipants() {
        Long competitionId = 1L;
        List<ScheduleGroupDetailVO> details = createMockScheduleDetails();
        
        when(scheduleGroupMapper.selectScheduleGroupDetails(competitionId)).thenReturn(details);

        List<ScheduleExportExcel> result = scheduleExportService.exportSchedule(competitionId);

        assertNotNull(result);
        assertFalse(result.isEmpty());
        verify(scheduleGroupMapper).selectScheduleGroupDetails(competitionId);
    }

    @Test
    @DisplayName("Should return empty list for template2 when no details")
    void shouldReturnEmptyListForTemplate2WhenNoDetails() {
        Long competitionId = 1L;
        when(scheduleGroupMapper.selectScheduleGroupDetails(competitionId)).thenReturn(new ArrayList<>());

        List<ScheduleExportExcel2> result = scheduleExportService.exportScheduleTemplate2(competitionId, null);

        assertNotNull(result);
        assertTrue(result.isEmpty());
        verify(scheduleGroupMapper).selectScheduleGroupDetails(competitionId);
    }

    @Test
    @DisplayName("Should export template2 with venue filter")
    void shouldExportTemplate2WithVenueFilter() {
        Long competitionId = 1L;
        Long venueId = 10L;
        List<ScheduleGroupDetailVO> details = createMockScheduleDetails();
        
        when(scheduleGroupMapper.selectScheduleGroupDetails(competitionId)).thenReturn(details);

        List<ScheduleExportExcel2> result = scheduleExportService.exportScheduleTemplate2(competitionId, venueId);

        assertNotNull(result);
        verify(scheduleGroupMapper).selectScheduleGroupDetails(competitionId);
    }

    @Test
    @DisplayName("Should export template2 without venue filter")
    void shouldExportTemplate2WithoutVenueFilter() {
        Long competitionId = 1L;
        List<ScheduleGroupDetailVO> details = createMockScheduleDetails();
        
        when(scheduleGroupMapper.selectScheduleGroupDetails(competitionId)).thenReturn(details);

        List<ScheduleExportExcel2> result = scheduleExportService.exportScheduleTemplate2(competitionId, null);

        assertNotNull(result);
        verify(scheduleGroupMapper).selectScheduleGroupDetails(competitionId);
    }

    @Test
    @DisplayName("Should handle null competition ID gracefully")
    void shouldHandleNullCompetitionId() {
        when(scheduleGroupMapper.selectScheduleGroupDetails(null)).thenReturn(new ArrayList<>());

        List<ScheduleExportExcel> result = scheduleExportService.exportSchedule(null);

        assertNotNull(result);
        assertTrue(result.isEmpty());
    }

    private List<ScheduleGroupDetailVO> createMockScheduleDetails() {
        List<ScheduleGroupDetailVO> details = new ArrayList<>();
        ScheduleGroupDetailVO detail = new ScheduleGroupDetailVO();
        detail.setGroupId(1L);
        detail.setGroupName("Test Group");
        detail.setVenueId(10L);
        detail.setVenueName("Test Venue");
        detail.setParticipantId(100L);
        detail.setPlayerName("Test Player");
        detail.setOrganization("Test Org");
        detail.setDisplayOrder(1);
        details.add(detail);
        return details;
    }
}
