package com.ruoyi.ccdi.project.domain.entity;

import com.ruoyi.lsfx.domain.response.GetBankStatementResponse.BankStatementItem;
import org.junit.jupiter.api.Test;

import java.math.BigDecimal;

import static org.junit.jupiter.api.Assertions.*;

/**
 * 银行流水实体类测试
 *
 * @author ruoyi
 * @date 2026-03-04
 */
class CcdiBankStatementTest {

    @Test
    void testFromResponse_Success() {
        // 准备测试数据
        BankStatementItem item = new BankStatementItem();
        item.setBankStatementId(123456L);
        item.setLeId(100);
        item.setAccountId(200L);
        item.setLeName("测试企业");
        item.setAccountNo("6222023300001234");
        item.setDrAmount(new BigDecimal("1000.00"));
        item.setCrAmount(new BigDecimal("500.00"));
        item.setBalanceAmount(new BigDecimal("5000.00"));
        item.setTrxDate("2026-03-04");
        item.setCustomerAccountNo("6228483300005678");

        // 执行转换
        CcdiBankStatement entity = CcdiBankStatement.fromResponse(item);

        // 验证结果
        assertNotNull(entity, "转换结果不应为null");
        assertEquals(123456L, entity.getBankStatementId(), "流水ID应该匹配");
        assertEquals(100, entity.getLeId(), "企业ID应该匹配");
        assertEquals(200L, entity.getAccountId(), "账号ID应该匹配");
        assertEquals("测试企业", entity.getLeAccountName(), "企业名称应该匹配");

        // 验证手动映射的字段
        assertEquals("6222023300001234", entity.getLeAccountNo(), "企业账号应该从 accountNo 映射");
        assertEquals("6228483300005678", entity.getCustomerAccountNo(), "对手方账号应该从 customerAccountNo 映射");

        // 验证金额字段
        assertEquals(new BigDecimal("1000.00"), entity.getAmountDr(), "付款金额应该匹配");
        assertEquals(new BigDecimal("500.00"), entity.getAmountCr(), "收款金额应该匹配");
        assertEquals(new BigDecimal("5000.00"), entity.getAmountBalance(), "余额应该匹配");

        // 验证特殊字段
        assertNull(entity.getMetaJson(), "metaJson 应该强制为 null");
        assertNull(entity.getProjectId(), "projectId 应该为 null（需要 Service 层设置）");
    }

    @Test
    void testFromResponse_Null() {
        // 测试空值处理
        CcdiBankStatement entity = CcdiBankStatement.fromResponse(null);

        // 验证返回 null
        assertNull(entity, "传入 null 应该返回 null");
    }

    @Test
    void testFromResponse_EmptyObject() {
        // 测试空对象转换
        BankStatementItem item = new BankStatementItem();

        // 执行转换
        CcdiBankStatement entity = CcdiBankStatement.fromResponse(item);

        // 验证不会抛出异常
        assertNotNull(entity, "空对象转换结果不应为 null");
        assertNull(entity.getMetaJson(), "metaJson 应该为 null");
    }

    @Test
    void testFromResponse_FieldTypeCompatibility() {
        // 测试字段类型兼容性
        BankStatementItem item = new BankStatementItem();
        item.setInternalFlag(1);  // Integer 类型
        item.setTransTypeId(100);  // Integer 类型

        // 执行转换
        CcdiBankStatement entity = CcdiBankStatement.fromResponse(item);

        // 验证类型转换正确
        assertNotNull(entity, "转换结果不应为 null");
        assertEquals(1, entity.getInternalFlag(), "Integer 类型应该正确复制");
        assertEquals(100, entity.getTrxType(), "Integer 类型应该正确复制");
    }

    @Test
    void testFromResponse_ShouldMapCounterpartyIdentityFields() {
        BankStatementItem item = new BankStatementItem();
        item.setCustomerCertNo("330101199001011234");
        item.setCustomerSocialCreditCode("91330100123456789X");

        CcdiBankStatement entity = CcdiBankStatement.fromResponse(item);

        assertNotNull(entity, "转换结果不应为 null");
        assertEquals("330101199001011234", entity.getCustomerCertNo());
        assertEquals("91330100123456789X", entity.getCustomerSocialCreditCode());
    }

    @Test
    void testFromResponse_ShouldNormalizeCretNoBeforeDash() {
        BankStatementItem item = new BankStatementItem();
        item.setCretNo(" 330100198801010033 - 测试人员 ");

        CcdiBankStatement entity = CcdiBankStatement.fromResponse(item);

        assertNotNull(entity);
        assertEquals("330100198801010033", entity.getCretNo());
    }

    @Test
    void testFromResponse_ShouldNormalizeCretNoWithChineseDash() {
        BankStatementItem item = new BankStatementItem();
        item.setCretNo("330100198801010033－测试人员");

        CcdiBankStatement entity = CcdiBankStatement.fromResponse(item);

        assertNotNull(entity);
        assertEquals("330100198801010033", entity.getCretNo());
    }
}
