package com.rj.controller;

import com.rj.controller.biz.CustomerProfileAnalysisController;
import com.rj.entity.CustomerProfileAnalysis;
import com.rj.service.biz.ICustomerProfileAnalysisService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

import java.time.LocalDateTime;

import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

/**
 * CustomerProfileAnalysisController 测试类
 * 
 * @author 李中华
 * @date 2025/1/15
 */
@WebMvcTest(CustomerProfileAnalysisController.class)
@DisplayName("客户画像分析控制器测试")
class CustomerProfileAnalysisControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockitoBean
    private ICustomerProfileAnalysisService customerProfileAnalysisService;

    private CustomerProfileAnalysis testAnalysis;

    @BeforeEach
    void setUp() {
        testAnalysis = new CustomerProfileAnalysis();
        testAnalysis.setId("test-id-123");
        testAnalysis.setProfileAnalysisRecordId("profile-record-001");
        testAnalysis.setAnalysisSceneType(1);
        testAnalysis.setInteractionDate(LocalDateTime.now());
        testAnalysis.setRelatedBusinessId("business-123");
        testAnalysis.setDealerCode("DEALER001");
        testAnalysis.setDealerName("测试经销商");
        testAnalysis.setBigArea("华北区");
        testAnalysis.setClientName("张三");
        testAnalysis.setClientPhone("13800138000");
        testAnalysis.setCreatedAt(LocalDateTime.now());
        testAnalysis.setUpdatedAt(LocalDateTime.now());
        testAnalysis.setRecordVersion(0);
        testAnalysis.setIsDeleted(0);
    }

    @Test
    @DisplayName("测试根据ID查询客户画像分析")
    void testGetAnalysisById() throws Exception {
        // Given
        when(customerProfileAnalysisService.getById("test-id-123")).thenReturn(testAnalysis);

        // When & Then
        mockMvc.perform(get("/api/customer-profile-analysis/test-id-123"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.success").value(true))
                .andExpect(jsonPath("$.message").value("查询成功"))
                .andExpect(jsonPath("$.data.id").value("test-id-123"))
                .andExpect(jsonPath("$.data.dealerName").value("测试经销商"));

        verify(customerProfileAnalysisService, times(1)).getById("test-id-123");
    }

    @Test
    @DisplayName("测试根据分析记录ID查询客户画像分析")
    void testGetAnalysisByRecordId() throws Exception {
        // Given
        when(customerProfileAnalysisService.getByProfileAnalysisRecordId("profile-record-001"))
                .thenReturn(testAnalysis);

        // When & Then
        mockMvc.perform(get("/api/customer-profile-analysis/by-record-id/profile-record-001"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.success").value(true))
                .andExpect(jsonPath("$.message").value("查询成功"))
                .andExpect(jsonPath("$.data.profileAnalysisRecordId").value("profile-record-001"));

        verify(customerProfileAnalysisService, times(1))
                .getByProfileAnalysisRecordId("profile-record-001");
    }

    @Test
    @DisplayName("测试根据业务ID查询客户画像分析")
    void testGetAnalysisByBusinessId() throws Exception {
        // Given
        when(customerProfileAnalysisService.getByBusinessId("business-123"))
                .thenReturn(testAnalysis);

        // When & Then
        mockMvc.perform(get("/api/customer-profile-analysis/by-business-id/business-123"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.success").value(true))
                .andExpect(jsonPath("$.message").value("查询成功"))
                .andExpect(jsonPath("$.data.relatedBusinessId").value("business-123"));

        verify(customerProfileAnalysisService, times(1))
                .getByBusinessId("business-123");
    }

    @Test
    @DisplayName("测试新增客户画像分析")
    void testAddAnalysis() throws Exception {
        // Given
        when(customerProfileAnalysisService.saveCustomerProfileAnalysis(any(CustomerProfileAnalysis.class)))
                .thenReturn(true);

        String requestJson = """
                {
                    "profileAnalysisRecordId": "profile-record-002",
                    "analysisSceneType": 1,
                    "relatedBusinessId": "business-456",
                    "dealerCode": "DEALER002",
                    "dealerName": "测试经销商2",
                    "bigArea": "华东区",
                    "clientName": "李四",
                    "clientPhone": "13900139000"
                }
                """;

        // When & Then
        mockMvc.perform(post("/api/customer-profile-analysis/add")
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestJson))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.success").value(true))
                .andExpect(jsonPath("$.message").value("客户画像分析添加成功"));

        verify(customerProfileAnalysisService, times(1))
                .saveCustomerProfileAnalysis(any(CustomerProfileAnalysis.class));
    }

    @Test
    @DisplayName("测试修改客户画像分析")
    void testUpdateAnalysis() throws Exception {
        // Given
        when(customerProfileAnalysisService.getById("test-id-123")).thenReturn(testAnalysis);
        when(customerProfileAnalysisService.updateById(any(CustomerProfileAnalysis.class)))
                .thenReturn(true);

        String requestJson = """
                {
                    "id": "test-id-123",
                    "profileAnalysisRecordId": "profile-record-001",
                    "analysisSceneType": 1,
                    "relatedBusinessId": "business-123",
                    "dealerCode": "DEALER001",
                    "dealerName": "测试经销商（修改）",
                    "bigArea": "华北区",
                    "clientName": "张三（修改）",
                    "clientPhone": "13800138000"
                }
                """;

        // When & Then
        mockMvc.perform(put("/api/customer-profile-analysis/update")
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestJson))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.success").value(true))
                .andExpect(jsonPath("$.message").value("客户画像分析修改成功"));

        verify(customerProfileAnalysisService, times(1)).getById("test-id-123");
        verify(customerProfileAnalysisService, times(1))
                .updateById(any(CustomerProfileAnalysis.class));
    }

    @Test
    @DisplayName("测试删除客户画像分析")
    void testDeleteAnalysis() throws Exception {
        // Given
        when(customerProfileAnalysisService.getById("test-id-123")).thenReturn(testAnalysis);
        when(customerProfileAnalysisService.updateById(any(CustomerProfileAnalysis.class)))
                .thenReturn(true);

        // When & Then
        mockMvc.perform(delete("/api/customer-profile-analysis/delete/test-id-123"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.success").value(true))
                .andExpect(jsonPath("$.message").value("客户画像分析删除成功"));

        verify(customerProfileAnalysisService, times(1)).getById("test-id-123");
        verify(customerProfileAnalysisService, times(1))
                .updateById(any(CustomerProfileAnalysis.class));
    }

    @Test
    @DisplayName("测试批量删除客户画像分析")
    void testBatchDeleteAnalysis() throws Exception {
        // Given
        when(customerProfileAnalysisService.getById(anyString())).thenReturn(testAnalysis);
        when(customerProfileAnalysisService.updateById(any(CustomerProfileAnalysis.class)))
                .thenReturn(true);

        String requestJson = """
                ["test-id-123", "test-id-456"]
                """;

        // When & Then
        mockMvc.perform(delete("/api/customer-profile-analysis/batch-delete")
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestJson))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.success").value(true))
                .andExpect(jsonPath("$.message").value("批量删除完成，成功：2，失败：0"));

        verify(customerProfileAnalysisService, times(2)).getById(anyString());
        verify(customerProfileAnalysisService, times(2))
                .updateById(any(CustomerProfileAnalysis.class));
    }

    @Test
    @DisplayName("测试查询不存在的记录")
    void testGetNonExistentAnalysis() throws Exception {
        // Given
        when(customerProfileAnalysisService.getById("non-existent-id")).thenReturn(null);

        // When & Then
        mockMvc.perform(get("/api/customer-profile-analysis/non-existent-id"))
                .andExpect(status().isNotFound())
                .andExpect(jsonPath("$.success").value(false))
                .andExpect(jsonPath("$.message").value("客户画像分析不存在或已删除"));

        verify(customerProfileAnalysisService, times(1)).getById("non-existent-id");
    }

    @Test
    @DisplayName("测试新增客户画像分析失败")
    void testAddAnalysisFailure() throws Exception {
        // Given
        when(customerProfileAnalysisService.saveCustomerProfileAnalysis(any(CustomerProfileAnalysis.class)))
                .thenReturn(false);

        String requestJson = """
                {
                    "profileAnalysisRecordId": "profile-record-003",
                    "analysisSceneType": 1,
                    "relatedBusinessId": "business-789"
                }
                """;

        // When & Then
        mockMvc.perform(post("/api/customer-profile-analysis/add")
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestJson))
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.success").value(false))
                .andExpect(jsonPath("$.message").value("客户画像分析添加失败"));

        verify(customerProfileAnalysisService, times(1))
                .saveCustomerProfileAnalysis(any(CustomerProfileAnalysis.class));
    }

    @Test
    @DisplayName("测试修改客户画像分析 - ID为空")
    void testUpdateAnalysisWithEmptyId() throws Exception {
        // Given
        String requestJson = """
                {
                    "id": "",
                    "profileAnalysisRecordId": "profile-record-001",
                    "analysisSceneType": 1
                }
                """;

        // When & Then
        mockMvc.perform(put("/api/customer-profile-analysis/update")
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestJson))
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.success").value(false))
                .andExpect(jsonPath("$.message").value("ID不能为空"));

        verify(customerProfileAnalysisService, never()).getById(anyString());
        verify(customerProfileAnalysisService, never()).updateById(any(CustomerProfileAnalysis.class));
    }

    @Test
    @DisplayName("测试批量删除客户画像分析 - 空ID列表")
    void testBatchDeleteAnalysisWithEmptyList() throws Exception {
        // Given
        String requestJson = "[]";

        // When & Then
        mockMvc.perform(delete("/api/customer-profile-analysis/batch-delete")
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestJson))
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.success").value(false))
                .andExpect(jsonPath("$.message").value("ID列表不能为空"));

        verify(customerProfileAnalysisService, never()).getById(anyString());
        verify(customerProfileAnalysisService, never()).updateById(any(CustomerProfileAnalysis.class));
    }
}
