package com.ruoyi.web.modules.industryservice.research.controller;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
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;

import java.util.Collections;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.ruoyi.web.modules.industryservice.domain.dto.OpenApiPageResult;
import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCooperativeDevelopmentVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchCommonProsperityProjectVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchDisposableIncomeVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFamilyRanchVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchFarmerHouseholdVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLargeLivestockFarmerVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockOwnershipHouseholdVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchLivestockProductOutputVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchPastureVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchRuralThreeAssetsVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchTechServicePersonnelVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchThreeAssetsProblemReportVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchVaccinationDataVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchYakHerdInventoryVo;
import com.ruoyi.web.modules.industryservice.research.domain.vo.ResearchYakOutboundReportVo;
import com.ruoyi.web.modules.industryservice.research.service.IResearchOpenApiService;

@ExtendWith(MockitoExtension.class)
@DisplayName("科研开放接口 HTTP")
class ResearchOpenApiControllerApiTest
{
    @Mock
    private IResearchOpenApiService researchOpenApiService;

    @InjectMocks
    private ResearchOpenApiController controller;

    private MockMvc mockMvc;

    @BeforeEach
    void setUp()
    {
        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
    }

    @Test
    @DisplayName("POST /auth/token 成功")
    void tokenOk() throws Exception
    {
        ResearchTokenVo token = new ResearchTokenVo();
        token.setAccessToken("test-token");
        token.setTokenType("Bearer");
        token.setExpiresIn(3600);
        when(researchOpenApiService.authenticate("demo-key", "demo-secret")).thenReturn(token);

        mockMvc.perform(post("/open-api/v1/research/auth/token")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"appKey\":\"demo-key\",\"appSecret\":\"demo-secret\"}"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.accessToken").value("test-token"));
    }

    @Test
    @DisplayName("GET /pastures 成功")
    void listPastures() throws Exception
    {
        ResearchPastureVo row = new ResearchPastureVo();
        row.setPastureId(1L);
        row.setPastureName("测试牧场");
        OpenApiPageResult<ResearchPastureVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listPastures(anyInt(), anyInt(), any(), any())).thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/pastures"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].pastureName").value("测试牧场"));
    }

    @Test
    @DisplayName("GET /yak-herd-inventories 成功")
    void listYakHerdInventories() throws Exception
    {
        ResearchYakHerdInventoryVo row = new ResearchYakHerdInventoryVo();
        row.setInventoryId(1L);
        row.setStatYear(2026);
        row.setStatMonth(5);
        row.setTownName("雅安镇");
        row.setVillageName("荣嘎村");
        OpenApiPageResult<ResearchYakHerdInventoryVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listYakHerdInventories(anyInt(), anyInt(), any(), any(), any(), any()))
                .thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/yak-herd-inventories")
                .param("statYear", "2026")
                .param("statMonth", "5")
                .param("townName", "雅安")
                .param("villageName", "荣嘎"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].townName").value("雅安镇"))
                .andExpect(jsonPath("$.data.records[0].villageName").value("荣嘎村"));
    }

    @Test
    @DisplayName("GET /yak-outbound-reports 成功")
    void listYakOutboundReports() throws Exception
    {
        ResearchYakOutboundReportVo row = new ResearchYakOutboundReportVo();
        row.setOutboundId(1L);
        row.setStatYear(2026);
        row.setStatMonth(5);
        row.setTownName("雅安镇");
        row.setVillageName("荣嘎村");
        OpenApiPageResult<ResearchYakOutboundReportVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listYakOutboundReports(anyInt(), anyInt(), any(), any(), any(), any()))
                .thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/yak-outbound-reports")
                .param("statYear", "2026")
                .param("statMonth", "5")
                .param("townName", "雅安")
                .param("villageName", "荣嘎"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].townName").value("雅安镇"))
                .andExpect(jsonPath("$.data.records[0].villageName").value("荣嘎村"));
    }

    @Test
    @DisplayName("GET /cooperative-developments 成功")
    void listCooperativeDevelopments() throws Exception
    {
        ResearchCooperativeDevelopmentVo row = new ResearchCooperativeDevelopmentVo();
        row.setCooperativeId(1L);
        row.setStatYear(2026);
        row.setStatMonth(5);
        row.setTownName("雅安镇");
        row.setVillageName("荣嘎村");
        row.setCooperativeName("测试合作社");
        OpenApiPageResult<ResearchCooperativeDevelopmentVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listCooperativeDevelopments(
                anyInt(), anyInt(), any(), any(), any(), any(), any())).thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/cooperative-developments")
                .param("statYear", "2026")
                .param("statMonth", "5")
                .param("townName", "雅安")
                .param("villageName", "荣嘎")
                .param("cooperativeName", "测试"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].cooperativeName").value("测试合作社"));
    }

    @Test
    @DisplayName("GET /livestock-product-outputs 成功")
    void listLivestockProductOutputs() throws Exception
    {
        ResearchLivestockProductOutputVo row = new ResearchLivestockProductOutputVo();
        row.setOutputId(1L);
        row.setStatYear(2026);
        row.setStatMonth(5);
        row.setTownName("雅安镇");
        row.setVillageName("荣嘎村");
        OpenApiPageResult<ResearchLivestockProductOutputVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listLivestockProductOutputs(anyInt(), anyInt(), any(), any(), any(), any()))
                .thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/livestock-product-outputs")
                .param("statYear", "2026")
                .param("statMonth", "5")
                .param("townName", "雅安")
                .param("villageName", "荣嘎"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].townName").value("雅安镇"))
                .andExpect(jsonPath("$.data.records[0].villageName").value("荣嘎村"));
    }

    @Test
    @DisplayName("GET /family-ranches 成功")
    void listFamilyRanches() throws Exception
    {
        ResearchFamilyRanchVo row = new ResearchFamilyRanchVo();
        row.setRanchId(1L);
        row.setStatYear(2026);
        row.setStatMonth(5);
        row.setTownName("雅安镇");
        row.setVillageName("荣嘎村");
        row.setEnterpriseName("测试牧场");
        OpenApiPageResult<ResearchFamilyRanchVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listFamilyRanches(
                anyInt(), anyInt(), any(), any(), any(), any(), any())).thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/family-ranches")
                .param("statYear", "2026")
                .param("statMonth", "5")
                .param("townName", "雅安")
                .param("villageName", "荣嘎")
                .param("enterpriseName", "测试"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].enterpriseName").value("测试牧场"));
    }

    @Test
    @DisplayName("GET /disposable-incomes 成功")
    void listDisposableIncomes() throws Exception
    {
        ResearchDisposableIncomeVo row = new ResearchDisposableIncomeVo();
        row.setIncomeId(1L);
        row.setStatYear(2025);
        OpenApiPageResult<ResearchDisposableIncomeVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listDisposableIncomes(anyInt(), anyInt(), any())).thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/disposable-incomes")
                .param("statYear", "2025"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].statYear").value(2025));
    }

    @Test
    @DisplayName("GET /farmer-households 成功")
    void listFarmerHouseholds() throws Exception
    {
        ResearchFarmerHouseholdVo row = new ResearchFarmerHouseholdVo();
        row.setHouseholdId(1L);
        row.setStatYear(2026);
        row.setStatMonth(5);
        row.setTownName("雅安镇");
        row.setVillageName("荣嘎村");
        OpenApiPageResult<ResearchFarmerHouseholdVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listFarmerHouseholds(anyInt(), anyInt(), any(), any(), any(), any()))
                .thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/farmer-households")
                .param("statYear", "2026")
                .param("statMonth", "5")
                .param("townName", "雅安")
                .param("villageName", "荣嘎"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].townName").value("雅安镇"))
                .andExpect(jsonPath("$.data.records[0].villageName").value("荣嘎村"));
    }

    @Test
    @DisplayName("GET /common-prosperity-projects 成功")
    void listCommonProsperityProjects() throws Exception
    {
        ResearchCommonProsperityProjectVo row = new ResearchCommonProsperityProjectVo();
        row.setProjectId(1L);
        row.setProjectName("和美乡村示范项目");
        row.setProjectType(1);
        row.setImplYear(2025);
        OpenApiPageResult<ResearchCommonProsperityProjectVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listCommonProsperityProjects(anyInt(), anyInt(), any(), any(), any()))
                .thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/common-prosperity-projects")
                .param("projectName", "和美")
                .param("projectType", "1")
                .param("implYear", "2025"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].projectName").value("和美乡村示范项目"))
                .andExpect(jsonPath("$.data.records[0].implYear").value(2025));
    }

    @Test
    @DisplayName("GET /large-livestock-farmers 成功")
    void listLargeLivestockFarmers() throws Exception
    {
        ResearchLargeLivestockFarmerVo row = new ResearchLargeLivestockFarmerVo();
        row.setFarmerId(1L);
        row.setStatYear(2026);
        row.setStatMonth(5);
        row.setTownName("雅安镇");
        row.setVillageName("荣嘎村");
        row.setEnterpriseName("测试养殖大户");
        OpenApiPageResult<ResearchLargeLivestockFarmerVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listLargeLivestockFarmers(
                anyInt(), anyInt(), any(), any(), any(), any(), any())).thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/large-livestock-farmers")
                .param("statYear", "2026")
                .param("statMonth", "5")
                .param("townName", "雅安")
                .param("villageName", "荣嘎")
                .param("enterpriseName", "测试"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].enterpriseName").value("测试养殖大户"));
    }

    @Test
    @DisplayName("GET /vaccination-data 成功")
    void listVaccinationData() throws Exception
    {
        ResearchVaccinationDataVo row = new ResearchVaccinationDataVo();
        row.setVaccinationId(1L);
        row.setStatYear(2026);
        row.setStatMonth(5);
        row.setTownName("雅安镇");
        row.setVillageName("荣嘎村");
        OpenApiPageResult<ResearchVaccinationDataVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listVaccinationData(anyInt(), anyInt(), any(), any(), any(), any()))
                .thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/vaccination-data")
                .param("statYear", "2026")
                .param("statMonth", "5")
                .param("townName", "雅安")
                .param("villageName", "荣嘎"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].townName").value("雅安镇"))
                .andExpect(jsonPath("$.data.records[0].villageName").value("荣嘎村"));
    }

    @Test
    @DisplayName("GET /livestock-ownership-households 成功")
    void listLivestockOwnershipHouseholds() throws Exception
    {
        ResearchLivestockOwnershipHouseholdVo row = new ResearchLivestockOwnershipHouseholdVo();
        row.setOwnershipId(1L);
        row.setStatYear(2026);
        row.setStatMonth(5);
        row.setTownName("雅安镇");
        row.setVillageName("荣嘎村");
        OpenApiPageResult<ResearchLivestockOwnershipHouseholdVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listLivestockOwnershipHouseholds(anyInt(), anyInt(), any(), any(), any(), any()))
                .thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/livestock-ownership-households")
                .param("statYear", "2026")
                .param("statMonth", "5")
                .param("townName", "雅安")
                .param("villageName", "荣嘎"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].townName").value("雅安镇"))
                .andExpect(jsonPath("$.data.records[0].villageName").value("荣嘎村"));
    }

    @Test
    @DisplayName("GET /rural-three-assets 成功")
    void listRuralThreeAssets() throws Exception
    {
        ResearchRuralThreeAssetsVo row = new ResearchRuralThreeAssetsVo();
        row.setAssetsId(1L);
        row.setTownName("雅安镇");
        row.setVillageName("荣嘎村");
        OpenApiPageResult<ResearchRuralThreeAssetsVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listRuralThreeAssets(anyInt(), anyInt(), any(), any())).thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/rural-three-assets")
                .param("townName", "雅安")
                .param("villageName", "荣嘎"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].townName").value("雅安镇"))
                .andExpect(jsonPath("$.data.records[0].villageName").value("荣嘎村"));
    }

    @Test
    @DisplayName("GET /three-assets-problem-reports 成功")
    void listThreeAssetsProblemReports() throws Exception
    {
        ResearchThreeAssetsProblemReportVo row = new ResearchThreeAssetsProblemReportVo();
        row.setProblemId(1L);
        row.setTownName("雅安镇");
        row.setVillageName("荣嘎村");
        row.setProblemLevel("general");
        OpenApiPageResult<ResearchThreeAssetsProblemReportVo> page = new OpenApiPageResult<>();
        page.setPageNum(1);
        page.setPageSize(20);
        page.setTotal(1L);
        page.setRecords(Collections.singletonList(row));
        when(researchOpenApiService.listThreeAssetsProblemReports(
                anyInt(), anyInt(), any(), any(), any(), any())).thenReturn(page);

        mockMvc.perform(get("/open-api/v1/research/three-assets-problem-reports")
                .param("townName", "雅安")
                .param("villageName", "荣嘎")
                .param("beginReportTime", "2026-01-01")
                .param("endReportTime", "2026-12-31"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.records[0].problemLevel").value("general"))
                .andExpect(jsonPath("$.data.records[0].townName").value("雅安镇"));
    }

    @Test
    @DisplayName("GET /tech-service-personnel 成功")
    void getTechServicePersonnel() throws Exception
    {
        ResearchTechServicePersonnelVo row = new ResearchTechServicePersonnelVo();
        row.setEnvoyMaleCount(10);
        row.setEnvoyFemaleCount(8);
        row.setEnvoyTotalCount(18);
        when(researchOpenApiService.getTechServicePersonnel()).thenReturn(row);

        mockMvc.perform(get("/open-api/v1/research/tech-service-personnel"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200))
                .andExpect(jsonPath("$.data.envoyTotalCount").value(18))
                .andExpect(jsonPath("$.data.envoyMaleCount").value(10));
    }
}
