package com.cf.imes.module.system.controller.admin.funds.delay;

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.funds.delay.vo.ProductDelayPageReqVO;
import com.cf.imes.module.system.controller.admin.funds.delay.vo.ProductDelayRespVO;
import com.cf.imes.module.system.controller.admin.funds.delay.vo.ProductDelaySaveReqVO;
import com.cf.imes.module.system.enums.pay.DurationUnitEnum;
import com.cf.imes.module.system.service.funds.delay.ProductDelayService;
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.time.LocalDate;
import java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
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.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

/**
 * 延期管理controller单元测试
 *
 * @author Gqr
 * @since 2025/12/9 14:10
 */
@WebMvcTest(controllers = ProductDelayController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
class ProductDelayControllerTest extends BaseWebUnitTest {

    @Autowired
    private MockMvc mockMvc;

    @MockitoBean
    private ProductDelayService productDelayService;

    @Autowired
    private ObjectMapper objectMapper;

    @Test
    void testCreateProductDelay() throws Exception {
        ProductDelaySaveReqVO vo = new ProductDelaySaveReqVO();
        vo.setOrganId(1L);
        vo.setPurchaseId(2L);
        vo.setDelayDuration(3);
        vo.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());

        // mock Service 返回
        when(productDelayService.createProductDelay(any())).thenReturn(100L);

        mockMvc.perform(post("/system/product/delay")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(vo)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data").value(100));

        // 验证 Service 调用
        verify(productDelayService, times(1)).createProductDelay(any());
    }

    @Test
    void testGetProductDelayPage() throws Exception {
        ProductDelayPageReqVO reqVO = new ProductDelayPageReqVO();
        reqVO.setOrganName("测试组织");
        reqVO.setProductName("测试产品");
        reqVO.setDelayDuration(3);
        
        PageResult<ProductDelayRespVO> mockPage = new PageResult<>();
        mockPage.setTotal(1L);
        mockPage.setList(List.of(new ProductDelayRespVO().setId(1L).setOrganName("测试组织")));
        when(productDelayService.getPage(any())).thenReturn(mockPage);

        mockMvc.perform(get("/system/product/delay/page")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(reqVO)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data.list[0].id").value(1L))
                .andExpect(jsonPath("$.data.list[0].organName").value("测试组织"));

        verify(productDelayService, times(1)).getPage(any());
    }

    @Test
    void testExportProductDelay() throws Exception {
        ProductDelayPageReqVO reqVO = new ProductDelayPageReqVO();
        reqVO.setOrganName("测试组织");
        
        PageResult<ProductDelayRespVO> mockPage = new PageResult<>();
        mockPage.setTotal(1L);
        ProductDelayRespVO respVO = new ProductDelayRespVO();
        respVO.setId(1L);
        respVO.setOrganName("测试组织");
        respVO.setProductName("测试产品");
        respVO.setDelayDuration(3);
        respVO.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());
        respVO.setEndTime(LocalDate.now());
        respVO.setDelayTime(LocalDate.now().plusMonths(3));
        mockPage.setList(List.of(respVO));
        when(productDelayService.getPage(any())).thenReturn(mockPage);

        mockMvc.perform(get("/system/product/delay/export")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(reqVO)))
                .andExpect(status().isOk());

        verify(productDelayService, times(1)).getPage(any());
    }
}