package com.cf.imes.module.system.controller.admin.tokenconfig;

import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
import com.cf.imes.module.system.controller.admin.tokenconfig.vo.TokenConfigRespVO;
import com.cf.imes.module.system.controller.admin.tokenconfig.vo.TokenConfigSaveReqVO;
import com.cf.imes.module.system.dal.dataobject.tokenconfig.TokenConfigDO;
import com.cf.imes.module.system.service.tokenconfig.TokenConfigService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;

import java.util.Collections;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

/**
 *
 *
 * @author Gqr
 * @since 2026/1/7 14:30
 */
@WebMvcTest(
        controllers = TokenConfigController.class,
        excludeAutoConfiguration = SecurityAutoConfiguration.class
)
class TokenConfigControllerTest extends BaseWebUnitTest {
    @Autowired
    private MockMvc mockMvc;

    @MockitoBean
    private TokenConfigService tokenConfigService;

    @Autowired
    private ObjectMapper objectMapper;

    @Test
    void getTokenConfigPage_success() throws Exception {
        TokenConfigRespVO respVO = new TokenConfigRespVO();
        respVO.setId(1L);

        PageResult<TokenConfigRespVO> pageResult =
                new PageResult<>(Collections.singletonList(respVO), 1L);

        when(tokenConfigService.getTokenConfigPage(any()))
                .thenReturn(pageResult);

        mockMvc.perform(get("/system/token")
                        .param("pageNo", "1")
                        .param("pageSize", "10"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(0))
                .andExpect(jsonPath("$.data.total").value(1))
                .andExpect(jsonPath("$.data.list[0].id").value(1L));

        verify(tokenConfigService).getTokenConfigPage(any());
    }

    @Test
    void getTokenConfigById_success() throws Exception {
        TokenConfigDO tokenConfigDO = new TokenConfigDO();
        tokenConfigDO.setId(100L);

        when(tokenConfigService.getTokenConConfig(100L))
                .thenReturn(tokenConfigDO);

        mockMvc.perform(get("/system/token/{id}", 100L))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(0))
                .andExpect(jsonPath("$.data.id").value(100L));

        verify(tokenConfigService).getTokenConConfig(100L);
    }

    @Test
    void insertTokenConfig_success() throws Exception {
        TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();

        mockMvc.perform(post("/system/token")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(reqVO)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data").value(true));

        verify(tokenConfigService).insertTokenConfig(any());
    }

    @Test
    void testUpdateTokenConfig_success() throws Exception {
        TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
        reqVO.setId(1L);

        mockMvc.perform(put("/system/token")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(reqVO)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data").value(true));

        verify(tokenConfigService).updateTokenConfig(any());
    }

    @Test
    void testDeleteTokenConfig_success() throws Exception {
        mockMvc.perform(delete("/system/token/{id}", 5L))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data").value(true));

        verify(tokenConfigService).deleteTokenConfig(5L);
    }

    @Test
    void testCheckTokenConfig_success() throws Exception {
        when(tokenConfigService.checkTokenConfig("abc"))
                .thenReturn(100L);

        mockMvc.perform(get("/system/token/check")
                        .param("token", "abc"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data").value(100L));
    }

    @Test
    void testTokenConfigCopy_success() throws Exception {
        when(tokenConfigService.tokenConfigCopy(1L))
                .thenReturn("PREFIX_xxx");

        mockMvc.perform(get("/system/token/copy")
                        .param("id", "1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data").value("PREFIX_xxx"));
    }

    @Test
    void testExportTokenConfigExcel_success() throws Exception {
        PageResult<TokenConfigRespVO> pageResult =
                new PageResult<>(Collections.emptyList(), 0L);

        when(tokenConfigService.getTokenConfigPage(any()))
                .thenReturn(pageResult);

        mockMvc.perform(get("/system/token/export"))
                .andExpect(status().isOk());
    }
}
