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.mapper.MartialScheduleParticipantMapper;
import org.springblade.modules.martial.pojo.entity.MartialScheduleParticipant;

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

@ExtendWith(MockitoExtension.class)
@DisplayName("ScheduleStatusService Unit Tests")
class ScheduleStatusServiceImplTest {

    @Mock
    private MartialScheduleParticipantMapper scheduleParticipantMapper;

    @InjectMocks
    private ScheduleStatusServiceImpl scheduleStatusService;

    @Test
    @DisplayName("Should update participant check-in status successfully")
    void shouldUpdateParticipantCheckInStatus() {
        Long participantId = 1L;
        String status = "已签到";
        MartialScheduleParticipant participant = new MartialScheduleParticipant();
        participant.setId(participantId);
        
        when(scheduleParticipantMapper.selectById(participantId)).thenReturn(participant);
        when(scheduleParticipantMapper.updateById(any(MartialScheduleParticipant.class))).thenReturn(1);

        boolean result = scheduleStatusService.updateParticipantCheckInStatus(participantId, status);

        assertTrue(result);
        verify(scheduleParticipantMapper).selectById(participantId);
        verify(scheduleParticipantMapper).updateById(any(MartialScheduleParticipant.class));
    }

    @Test
    @DisplayName("Should return false when participant not found")
    void shouldReturnFalseWhenParticipantNotFound() {
        Long participantId = 999L;
        String status = "已签到";
        
        when(scheduleParticipantMapper.selectById(participantId)).thenReturn(null);

        boolean result = scheduleStatusService.updateParticipantCheckInStatus(participantId, status);

        assertFalse(result);
        verify(scheduleParticipantMapper).selectById(participantId);
        verify(scheduleParticipantMapper, never()).updateById(any());
    }

    @Test
    @DisplayName("Should return false when update fails")
    void shouldReturnFalseWhenUpdateFails() {
        Long participantId = 1L;
        String status = "已签到";
        MartialScheduleParticipant participant = new MartialScheduleParticipant();
        participant.setId(participantId);
        
        when(scheduleParticipantMapper.selectById(participantId)).thenReturn(participant);
        when(scheduleParticipantMapper.updateById(any(MartialScheduleParticipant.class))).thenReturn(0);

        boolean result = scheduleStatusService.updateParticipantCheckInStatus(participantId, status);

        assertFalse(result);
        verify(scheduleParticipantMapper).updateById(any(MartialScheduleParticipant.class));
    }

    @Test
    @DisplayName("Should handle different status values")
    void shouldHandleDifferentStatusValues() {
        Long participantId = 1L;
        MartialScheduleParticipant participant = new MartialScheduleParticipant();
        participant.setId(participantId);
        
        when(scheduleParticipantMapper.selectById(participantId)).thenReturn(participant);
        when(scheduleParticipantMapper.updateById(any(MartialScheduleParticipant.class))).thenReturn(1);

        assertTrue(scheduleStatusService.updateParticipantCheckInStatus(participantId, "已签到"));
        assertTrue(scheduleStatusService.updateParticipantCheckInStatus(participantId, "未签到"));
        assertTrue(scheduleStatusService.updateParticipantCheckInStatus(participantId, "已完成"));
    }

    @Test
    @DisplayName("Should return false when status is null")
    void shouldReturnFalseWhenStatusIsNull() {
        Long participantId = 1L;

        boolean result = scheduleStatusService.updateParticipantCheckInStatus(participantId, null);

        assertFalse(result);
        verify(scheduleParticipantMapper, never()).selectById(any());
    }
}
