package com.ruoyi.web.modules.trading.support;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.web.modules.trading.domain.BizSupplier;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

@DisplayName("SupplierValidation")
class SupplierValidationTest
{
    private static final String VALID_ID_CARD = "11010519491231002X";

    private static final String VALID_USCC = "91110000MA01234567";

    private static final String VALID_PHONE = "13800138000";

    @Test
    @DisplayName("供应商名称长度")
    void supplierName()
    {
        assertThrows(ServiceException.class, () -> SupplierValidation.validateSupplierName(""));
        assertDoesNotThrow(() -> SupplierValidation.validateSupplierName("扎西供应商"));
    }

    @Test
    @DisplayName("个体户身份证")
    void individualIdCard()
    {
        assertDoesNotThrow(() -> SupplierValidation.validateIdentityNo(VALID_ID_CARD, SupplierRules.TYPE_INDIVIDUAL));
        assertThrows(ServiceException.class,
                () -> SupplierValidation.validateIdentityNo("123", SupplierRules.TYPE_INDIVIDUAL));
    }

    @Test
    @DisplayName("企业统一社会信用代码")
    void enterpriseUscc()
    {
        assertDoesNotThrow(() -> SupplierValidation.validateIdentityNo(VALID_USCC, SupplierRules.TYPE_ENTERPRISE));
        assertThrows(ServiceException.class,
                () -> SupplierValidation.validateIdentityNo("123", SupplierRules.TYPE_ENTERPRISE));
    }

    @Test
    @DisplayName("按户计费清空费率")
    void feePerAccount()
    {
        BizSupplier row = sampleRow();
        row.setFeeMethod(SupplierRules.FEE_METHOD_PER_ACCOUNT);
        row.setFeeStandard(new BigDecimal("10"));
        row.setTransactionFeeRate(new BigDecimal("1"));
        row.setManagementFeeRate(new BigDecimal("2"));
        SupplierValidation.applyFeeFieldsByMethod(row);
        assertNull(row.getFeeStandard());
        assertNull(row.getTransactionFeeRate());
        assertNull(row.getManagementFeeRate());
    }

    @Test
    @DisplayName("按头计费须收费标准")
    void feePerHead()
    {
        BizSupplier row = sampleRow();
        row.setFeeMethod(SupplierRules.FEE_METHOD_PER_HEAD);
        row.setFeeStandard(null);
        assertThrows(ServiceException.class, () -> SupplierValidation.applyFeeFieldsByMethod(row));
        row.setFeeStandard(new BigDecimal("15.5"));
        assertDoesNotThrow(() -> SupplierValidation.applyFeeFieldsByMethod(row));
    }

    @Test
    @DisplayName("按额计费须两费率")
    void feePerAmount()
    {
        BizSupplier row = sampleRow();
        row.setFeeMethod(SupplierRules.FEE_METHOD_PER_AMOUNT);
        row.setTransactionFeeRate(new BigDecimal("2"));
        row.setManagementFeeRate(new BigDecimal("1"));
        assertDoesNotThrow(() -> SupplierValidation.applyFeeFieldsByMethod(row));
        row.setManagementFeeRate(new BigDecimal("101"));
        assertThrows(ServiceException.class, () -> SupplierValidation.applyFeeFieldsByMethod(row));
    }

    @Test
    @DisplayName("车辆号牌")
    void vehiclePlates()
    {
        assertDoesNotThrow(() -> SupplierValidation.validateVehiclePlates(Collections.singletonList("藏A12345")));
        assertThrows(ServiceException.class,
                () -> SupplierValidation.validateVehiclePlates(Collections.singletonList("INVALID")));
    }

    @Test
    @DisplayName("车辆号牌 JSON 互转")
    void platesJson()
    {
        String json = SupplierVehiclePlatesHelper.toJson(Arrays.asList("藏A12345", "藏B67890"));
        assertEquals(2, SupplierVehiclePlatesHelper.fromJson(json).size());
    }

    private static BizSupplier sampleRow()
    {
        BizSupplier r = new BizSupplier();
        r.setSupplierName("扎西供应商");
        r.setSupplierType(SupplierRules.TYPE_INDIVIDUAL);
        r.setIdentityNo(VALID_ID_CARD);
        r.setContactPhone(VALID_PHONE);
        r.setFeeMethod(SupplierRules.FEE_METHOD_PER_ACCOUNT);
        return r;
    }
}
