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

import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.security.test.WithMockLoginUser;
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
import com.cf.imes.module.system.common.WithMockLoginUserExtension;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseRecordPageReqVO;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseRecordRespVO;
import com.cf.imes.module.system.service.funds.purchase.PurchaseService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
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 java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
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.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

/**
 * 购买记录 controller 单元测试
 *
 * @author Gqr
 * @since 2026/1/7 10:16
 */
@WebMvcTest(
        controllers = PurchaseController.class,
        excludeAutoConfiguration = SecurityAutoConfiguration.class
)
@ExtendWith(WithMockLoginUserExtension.class)
class PurchaseControllerTest extends BaseWebUnitTest {
    @Autowired
    private MockMvc mockMvc;

    @MockitoBean
    private PurchaseService purchaseService;

    /**
     * 非管理端：获取购买记录分页
     */
    @Test
    @WithMockLoginUser(organId = 1L)
    void testGetPurchaseRecord_nonManage() throws Exception {
            // mock service 返回
            PurchaseRecordRespVO respVO = new PurchaseRecordRespVO();
            respVO.setId(1L);
            respVO.setOrganId(1L);

            PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
            pageResult.setTotal(1L);
            pageResult.setList(List.of(respVO));

            when(purchaseService.getPurchaseRecord(any()))
                    .thenReturn(pageResult);

            // 发起请求
            mockMvc.perform(get("/system/purchase")
                            .contentType(MediaType.APPLICATION_JSON))
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$.data.total").value(1))
                    .andExpect(jsonPath("$.data.list[0].id").value(1L));

            // 校验 organId 被强制设置
            ArgumentCaptor<PurchaseRecordPageReqVO> captor =
                    ArgumentCaptor.forClass(PurchaseRecordPageReqVO.class);

            verify(purchaseService, times(1))
                    .getPurchaseRecord(captor.capture());

            assertEquals(1L, captor.getValue().getOrganId());

    }

    /**
     * 管理端：获取购买记录分页
     */
    @Test
    @WithMockLoginUser(userType = 2)
    void testGetPurchaseRecord_manage() throws Exception {
            PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
            pageResult.setTotal(0L);
            pageResult.setList(Collections.emptyList());

            when(purchaseService.getPurchaseRecord(any()))
                    .thenReturn(pageResult);

            mockMvc.perform(get("/system/purchase")
                            .contentType(MediaType.APPLICATION_JSON))
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$.data.total").value(0));

            verify(purchaseService, times(1))
                    .getPurchaseRecord(any());
    }

    /**
     * 非管理端：导出购买记录
     */
    @Test
    @WithMockLoginUser(organId = 1L)
    void testExportPurchaseRecord_nonManage() throws Exception {
        PurchaseRecordRespVO respVO = new PurchaseRecordRespVO();
        respVO.setId(1L);
        respVO.setOrganId(1L);

        PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
        pageResult.setTotal(1L);
        pageResult.setList(List.of(respVO));

        when(purchaseService.getPurchaseRecord(any()))
                .thenReturn(pageResult);

        mockMvc.perform(get("/system/purchase/export")
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk());

        verify(purchaseService, times(1))
                .getPurchaseRecord(any());
    }

    /**
     * 管理端：导出购买记录
     */
    @Test
    @WithMockLoginUser(userType = 2)
    void testExportPurchaseRecord_manage() throws Exception {
        PurchaseRecordRespVO respVO = new PurchaseRecordRespVO();
        respVO.setId(1L);

        PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
        pageResult.setTotal(1L);
        pageResult.setList(List.of(respVO));

        when(purchaseService.getPurchaseRecord(any()))
                .thenReturn(pageResult);

        mockMvc.perform(get("/system/purchase/export")
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk());

        verify(purchaseService, times(1))
                .getPurchaseRecord(any());
    }
}
