package com.ruoyi.ccdi.project.controller;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import com.ruoyi.ccdi.project.domain.dto.CcdiBankTagRebuildDTO;
import com.ruoyi.ccdi.project.service.ICcdiBankTagService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.SecurityUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;
import org.slf4j.LoggerFactory;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class CcdiBankTagControllerTest {

    @InjectMocks
    private CcdiBankTagController controller;

    @Mock
    private ICcdiBankTagService bankTagService;

    @Test
    void rebuild_shouldDelegateProjectAndModelCode() {
        CcdiBankTagRebuildDTO dto = new CcdiBankTagRebuildDTO();
        dto.setProjectId(40L);
        dto.setModelCode("LARGE_TRANSACTION");

        when(bankTagService.submitRebuild(dto, "admin")).thenReturn("标签重算任务已提交");

        try (MockedStatic<SecurityUtils> mocked = mockStatic(SecurityUtils.class)) {
            mocked.when(SecurityUtils::getUsername).thenReturn("admin");

            AjaxResult result = controller.rebuild(dto);

            assertEquals(200, result.get("code"));
            verify(bankTagService).submitRebuild(dto, "admin");
        }
    }

    @Test
    void rebuild_shouldLogManualRebuildRequest() {
        CcdiBankTagRebuildDTO dto = new CcdiBankTagRebuildDTO();
        dto.setProjectId(40L);
        dto.setModelCode("LARGE_TRANSACTION");

        Logger logger = (Logger) LoggerFactory.getLogger(CcdiBankTagController.class);
        ListAppender<ILoggingEvent> appender = new ListAppender<>();
        appender.start();
        logger.addAppender(appender);

        when(bankTagService.submitRebuild(dto, "admin")).thenReturn("标签重算任务已提交");

        try (MockedStatic<SecurityUtils> mocked = mockStatic(SecurityUtils.class)) {
            mocked.when(SecurityUtils::getUsername).thenReturn("admin");

            controller.rebuild(dto);

            assertTrue(appender.list.stream().map(ILoggingEvent::getFormattedMessage)
                .anyMatch(message -> message.contains("收到手动重算请求")
                    && message.contains("projectId=40")
                    && message.contains("modelCode=LARGE_TRANSACTION")
                    && message.contains("operator=admin")));
        } finally {
            logger.detachAppender(appender);
        }
    }
}
