package com.ruoyi.app.flashdelivery.task;

import com.ruoyi.app.flashdelivery.service.FlashDeliveryApplicationService;
import com.ruoyi.system.domain.flash.FlashDeliveryOrder;
import org.junit.jupiter.api.Test;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.doThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

class FlashDeliveryAutoCompleteTaskTest {
    @Test
    void usesQuartzInvocableBeanInsteadOfLocalScheduledTrigger() throws Exception {
        Component component = FlashDeliveryAutoCompleteTask.class.getAnnotation(Component.class);

        assertEquals("flashDeliveryAutoCompleteTask", component.value());
        assertNull(FlashDeliveryAutoCompleteTask.class.getMethod("completeDeliveredOrders")
                .getAnnotation(Scheduled.class));
    }

    @Test
    void completesEveryDueOrderThroughConditionalServiceOperation() {
        FlashDeliveryApplicationService service = mock(FlashDeliveryApplicationService.class);
        FlashDeliveryOrder first = new FlashDeliveryOrder(); first.setId(1L);
        FlashDeliveryOrder second = new FlashDeliveryOrder(); second.setId(2L);
        when(service.autoCompleteCandidates(any(Date.class), anyInt())).thenReturn(List.of(first, second));

        new FlashDeliveryAutoCompleteTask(service).completeDeliveredOrders();

        verify(service).complete(null, "SYSTEM", 1L);
        verify(service).complete(null, "SYSTEM", 2L);
    }

    @Test
    void oneFailedOrderDoesNotStopTheRemainingBatch() {
        FlashDeliveryApplicationService service = mock(FlashDeliveryApplicationService.class);
        FlashDeliveryOrder first = new FlashDeliveryOrder(); first.setId(1L);
        FlashDeliveryOrder second = new FlashDeliveryOrder(); second.setId(2L);
        when(service.autoCompleteCandidates(any(Date.class), anyInt())).thenReturn(List.of(first, second));
        doThrow(new IllegalStateException("one bad row")).when(service).complete(null, "SYSTEM", 1L);

        ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger)
                org.slf4j.LoggerFactory.getLogger(FlashDeliveryAutoCompleteTask.class);
        ch.qos.logback.classic.Level previous = logger.getLevel();
        logger.setLevel(ch.qos.logback.classic.Level.OFF);
        try {
            new FlashDeliveryAutoCompleteTask(service).completeDeliveredOrders();
        } finally {
            logger.setLevel(previous);
        }

        verify(service).complete(null, "SYSTEM", 2L);
    }
}
