package cn.iocoder.yudao.module.asset.service.customer;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerPageReqVO;
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerSaveReqVO;
import cn.iocoder.yudao.module.asset.dal.dataobject.customer.CustomerDO;
import cn.iocoder.yudao.module.asset.dal.mysql.customer.CustomerMapper;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;

import jakarta.annotation.Resource;
import java.math.BigDecimal;

import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static cn.iocoder.yudao.module.asset.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;
import static org.junit.jupiter.api.Assertions.*;

/**
 * 客户管理 Service 测试类
 *
 * @author 芋道源码
 */
@Import(CustomerServiceImpl.class)
public class CustomerServiceImplTest extends BaseDbUnitTest {

    @Resource
    private CustomerServiceImpl customerService;

    @Resource
    private CustomerMapper customerMapper;

    @Test
    public void testCreateCustomer_success() {
        // 准备参数
        CustomerSaveReqVO createReqVO = randomPojo(CustomerSaveReqVO.class, o -> {
            o.setCustomerName("测试客户");
            o.setCustomerType(0);
            o.setContactPhone("13800138000");
            o.setContactEmail("test@example.com");
            o.setIdCardNo("310101199001011234");
            o.setCreditLevel(1);
            o.setDepositAmount(new BigDecimal("5000.00"));
            o.setStatus(0);
        });

        // 调用
        Long customerId = customerService.createCustomer(createReqVO);

        // 断言
        assertNotNull(customerId);
        CustomerDO customer = customerMapper.selectById(customerId);
        assertNotNull(customer);
        assertEquals("测试客户", customer.getCustomerName());
        assertEquals(0, customer.getCustomerType());
        assertEquals("13800138000", customer.getContactPhone());
        assertNotNull(customer.getCustomerNo());
        assertTrue(customer.getCustomerNo().startsWith("CUST"));
    }

    @Test
    public void testUpdateCustomer_success() {
        // mock 数据
        CustomerDO dbCustomer = new CustomerDO();
        dbCustomer.setCustomerNo("CUST000001");
        dbCustomer.setCustomerName("原客户名");
        dbCustomer.setCustomerType(0);
        dbCustomer.setContactPhone("13800138000");
        dbCustomer.setCreditLevel(1);
        dbCustomer.setDepositAmount(new BigDecimal("5000.00"));
        dbCustomer.setStatus(0);
        customerMapper.insert(dbCustomer);

        // 准备参数
        CustomerSaveReqVO updateReqVO = new CustomerSaveReqVO();
        updateReqVO.setId(dbCustomer.getId());
        updateReqVO.setCustomerName("新客户名");
        updateReqVO.setCustomerType(0);
        updateReqVO.setContactPhone("13900139000");
        updateReqVO.setCreditLevel(2);
        updateReqVO.setDepositAmount(new BigDecimal("8000.00"));
        updateReqVO.setStatus(0);

        // 调用
        customerService.updateCustomer(updateReqVO);

        // 断言
        CustomerDO customer = customerMapper.selectById(updateReqVO.getId());
        assertEquals("新客户名", customer.getCustomerName());
        assertEquals("13900139000", customer.getContactPhone());
        assertEquals(2, customer.getCreditLevel());
    }

    @Test
    public void testUpdateCustomer_notExists() {
        // 准备参数
        CustomerSaveReqVO updateReqVO = randomPojo(CustomerSaveReqVO.class, o -> {
            o.setId(999999L);
            o.setCustomerName("不存在的客户");
            o.setCustomerType(0);
            o.setStatus(0);
        });

        // 调用并断言异常
        assertServiceException(() -> customerService.updateCustomer(updateReqVO), CUSTOMER_NOT_EXISTS);
    }

    @Test
    public void testDeleteCustomer_success() {
        // mock 数据
        CustomerDO dbCustomer = new CustomerDO();
        dbCustomer.setCustomerNo("CUST000001");
        dbCustomer.setCustomerName("测试客户");
        dbCustomer.setCustomerType(0);
        dbCustomer.setCreditLevel(1);
        dbCustomer.setDepositAmount(new BigDecimal("5000.00"));
        dbCustomer.setStatus(0);
        customerMapper.insert(dbCustomer);

        // 调用
        customerService.deleteCustomer(dbCustomer.getId());

        // 断言
        assertNull(customerMapper.selectById(dbCustomer.getId()));
    }

    @Test
    public void testDeleteCustomer_notExists() {
        // 调用并断言异常
        assertServiceException(() -> customerService.deleteCustomer(999999L), CUSTOMER_NOT_EXISTS);
    }

    @Test
    public void testGetCustomer() {
        // mock 数据
        CustomerDO dbCustomer = new CustomerDO();
        dbCustomer.setCustomerNo("CUST000001");
        dbCustomer.setCustomerName("测试客户");
        dbCustomer.setCustomerType(0);
        dbCustomer.setCreditLevel(1);
        dbCustomer.setDepositAmount(new BigDecimal("5000.00"));
        dbCustomer.setStatus(0);
        customerMapper.insert(dbCustomer);

        // 调用
        CustomerDO customer = customerService.getCustomer(dbCustomer.getId());

        // 断言
        assertNotNull(customer);
        assertEquals("测试客户", customer.getCustomerName());
    }

    @Test
    public void testGetCustomerPage() {
        // mock 数据
        CustomerDO dbCustomer1 = new CustomerDO();
        dbCustomer1.setCustomerNo("CUST000001");
        dbCustomer1.setCustomerName("张三");
        dbCustomer1.setCustomerType(0);
        dbCustomer1.setContactPhone("13800138001");
        dbCustomer1.setCreditLevel(1);
        dbCustomer1.setDepositAmount(new BigDecimal("5000.00"));
        dbCustomer1.setStatus(0);
        customerMapper.insert(dbCustomer1);

        CustomerDO dbCustomer2 = new CustomerDO();
        dbCustomer2.setCustomerNo("CUST000002");
        dbCustomer2.setCustomerName("李四");
        dbCustomer2.setCustomerType(1);
        dbCustomer2.setContactPhone("13800138002");
        dbCustomer2.setCreditLevel(1);
        dbCustomer2.setDepositAmount(new BigDecimal("5000.00"));
        dbCustomer2.setStatus(0);
        customerMapper.insert(dbCustomer2);

        CustomerDO dbCustomer3 = new CustomerDO();
        dbCustomer3.setCustomerNo("CUST000003");
        dbCustomer3.setCustomerName("王五");
        dbCustomer3.setCustomerType(0);
        dbCustomer3.setContactPhone("13800138003");
        dbCustomer3.setCreditLevel(1);
        dbCustomer3.setDepositAmount(new BigDecimal("5000.00"));
        dbCustomer3.setStatus(1);
        customerMapper.insert(dbCustomer3);

        // 测试 customerName 模糊查询
        CustomerPageReqVO reqVO = new CustomerPageReqVO();
        reqVO.setCustomerName("张");
        reqVO.setPageNo(1);
        reqVO.setPageSize(10);

        PageResult<CustomerDO> pageResult = customerService.getCustomerPage(reqVO);
        assertEquals(1, pageResult.getTotal());
        assertEquals("张三", pageResult.getList().get(0).getCustomerName());

        // 测试 customerType 筛选
        reqVO = new CustomerPageReqVO();
        reqVO.setCustomerType(1);
        reqVO.setPageNo(1);
        reqVO.setPageSize(10);

        pageResult = customerService.getCustomerPage(reqVO);
        assertEquals(1, pageResult.getTotal());
        assertEquals("李四", pageResult.getList().get(0).getCustomerName());

        // 测试 status 筛选
        reqVO = new CustomerPageReqVO();
        reqVO.setStatus(1);
        reqVO.setPageNo(1);
        reqVO.setPageSize(10);

        pageResult = customerService.getCustomerPage(reqVO);
        assertEquals(1, pageResult.getTotal());
        assertEquals("王五", pageResult.getList().get(0).getCustomerName());

        // 测试 contactPhone 模糊查询
        reqVO = new CustomerPageReqVO();
        reqVO.setContactPhone("138001");
        reqVO.setPageNo(1);
        reqVO.setPageSize(10);

        pageResult = customerService.getCustomerPage(reqVO);
        assertEquals(3, pageResult.getTotal());
    }

}
