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

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.industryservice.support.PastureValidation;
import com.ruoyi.web.modules.trading.domain.BizSupplier;

/**
 * 供应商入参校验与收费字段清洗。
 */
public final class SupplierValidation
{
    private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");

    private static final Pattern ID_CARD_PATTERN = Pattern.compile(
            "^[1-9]\\d{5}(19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$");

    private static final Pattern USCC_PATTERN = Pattern.compile("^[0-9A-Z]{18}$");

    private static final Pattern PLATE_PATTERN = Pattern.compile(
            "^[\\u4e00-\\u9fa5][A-Z][A-Z0-9]{5,6}$");

    private SupplierValidation()
    {
    }

    public static void trimFieldsForSave(BizSupplier row)
    {
        if (row == null)
        {
            return;
        }
        if (row.getSupplierName() != null)
        {
            row.setSupplierName(row.getSupplierName().trim());
        }
        if (row.getIdentityNo() != null)
        {
            row.setIdentityNo(row.getIdentityNo().trim().toUpperCase());
        }
        if (row.getContactPhone() != null)
        {
            row.setContactPhone(row.getContactPhone().trim());
        }
        if (row.getBusinessLocation() != null)
        {
            String loc = row.getBusinessLocation().trim();
            row.setBusinessLocation(loc.isEmpty() ? null : loc);
        }
        if (row.getRemark() != null)
        {
            String remark = row.getRemark().trim();
            row.setRemark(remark.isEmpty() ? null : remark);
        }
        row.setVehiclePlates(normalizePlates(row.getVehiclePlates()));
    }

    public static List<String> normalizePlates(List<String> plates)
    {
        if (plates == null || plates.isEmpty())
        {
            return null;
        }
        List<String> out = new ArrayList<>();
        for (String p : plates)
        {
            if (StringUtils.isEmpty(p))
            {
                continue;
            }
            String t = p.trim().toUpperCase();
            if (!t.isEmpty())
            {
                out.add(t);
            }
        }
        return out.isEmpty() ? null : out;
    }

    public static void validateSupplierName(String supplierName)
    {
        if (StringUtils.isEmpty(supplierName) || supplierName.length() < 1 || supplierName.length() > 20)
        {
            throw new ServiceException("供应商名称须为1～20个字符");
        }
    }

    public static void validateSupplierType(Integer supplierType)
    {
        if (supplierType == null
                || (supplierType != SupplierRules.TYPE_INDIVIDUAL && supplierType != SupplierRules.TYPE_ENTERPRISE))
        {
            throw new ServiceException("供应商类型须为1～2（1个体户2企业）");
        }
    }

    public static void validateIdentityNo(String identityNo, Integer supplierType)
    {
        if (StringUtils.isEmpty(identityNo))
        {
            throw new ServiceException("身份识别号不能为空");
        }
        validateSupplierType(supplierType);
        String normalized = identityNo.trim().toUpperCase();
        if (supplierType == SupplierRules.TYPE_INDIVIDUAL)
        {
            if (!ID_CARD_PATTERN.matcher(normalized).matches()
                    || !PastureValidation.isIdCardChecksumValid(normalized))
            {
                throw new ServiceException("请输入正确的身份证号");
            }
        }
        else
        {
            if (!USCC_PATTERN.matcher(normalized).matches())
            {
                throw new ServiceException("请输入正确的主体识别号");
            }
        }
    }

    public static void validateContactPhone(String phone)
    {
        if (StringUtils.isEmpty(phone) || !PHONE_PATTERN.matcher(phone.trim()).matches())
        {
            throw new ServiceException("请输入正确的手机号码");
        }
    }

    public static void validateBusinessLocation(String businessLocation)
    {
        if (businessLocation != null && businessLocation.length() > 50)
        {
            throw new ServiceException("经营地点不能超过50个字符");
        }
    }

    public static void validateFeeMethod(Integer feeMethod)
    {
        if (feeMethod == null || feeMethod < SupplierRules.FEE_METHOD_PER_ACCOUNT
                || feeMethod > SupplierRules.FEE_METHOD_PER_AMOUNT)
        {
            throw new ServiceException("收费方式须为1～3（1按户2按头3按额）");
        }
    }

    public static void validateVehiclePlates(List<String> plates)
    {
        if (plates == null || plates.isEmpty())
        {
            return;
        }
        if (plates.size() > SupplierRules.MAX_VEHICLE_PLATES)
        {
            throw new ServiceException("车辆号牌最多登记10个");
        }
        for (String plate : plates)
        {
            if (StringUtils.isEmpty(plate) || plate.length() < 7 || plate.length() > 8
                    || !PLATE_PATTERN.matcher(plate).matches())
            {
                throw new ServiceException("请输入正确的车辆号码");
            }
        }
    }

    public static void applyFeeFieldsByMethod(BizSupplier row)
    {
        validateFeeMethod(row.getFeeMethod());
        switch (row.getFeeMethod())
        {
            case SupplierRules.FEE_METHOD_PER_ACCOUNT:
                row.setFeeStandard(null);
                row.setTransactionFeeRate(null);
                row.setManagementFeeRate(null);
                break;
            case SupplierRules.FEE_METHOD_PER_HEAD:
                row.setTransactionFeeRate(null);
                row.setManagementFeeRate(null);
                if (row.getFeeStandard() == null || row.getFeeStandard().compareTo(BigDecimal.ZERO) <= 0)
                {
                    throw new ServiceException("请填写收费标准（元/头）");
                }
                break;
            case SupplierRules.FEE_METHOD_PER_AMOUNT:
                row.setFeeStandard(null);
                validateRate(row.getTransactionFeeRate(), "交易费率");
                validateRate(row.getManagementFeeRate(), "管理费率");
                break;
            default:
                throw new ServiceException("收费方式须为1～3（1按户2按头3按额）");
        }
    }

    private static void validateRate(BigDecimal rate, String label)
    {
        if (rate == null)
        {
            throw new ServiceException("请填写" + label);
        }
        if (rate.compareTo(BigDecimal.ZERO) < 0 || rate.compareTo(new BigDecimal("100")) > 0)
        {
            throw new ServiceException("费率须在 0～100% 之间");
        }
    }

    public static void validateRowForSave(BizSupplier row)
    {
        trimFieldsForSave(row);
        validateSupplierName(row.getSupplierName());
        validateSupplierType(row.getSupplierType());
        validateIdentityNo(row.getIdentityNo(), row.getSupplierType());
        validateContactPhone(row.getContactPhone());
        validateBusinessLocation(row.getBusinessLocation());
        validateVehiclePlates(row.getVehiclePlates());
        applyFeeFieldsByMethod(row);
        row.setVehiclePlatesJson(SupplierVehiclePlatesHelper.toJson(row.getVehiclePlates()));
    }

    public static void validateForAssignAccount(BizSupplier db)
    {
        if (db == null)
        {
            throw new ServiceException("记录不存在或已删除");
        }
        if (db.getAccountAssigned() != null
                && db.getAccountAssigned() == TradePartnerAccountRules.ACCOUNT_ASSIGNED_YES)
        {
            throw new ServiceException(TradePartnerAccountRules.MSG_ALREADY_ASSIGNED_SUPPLIER);
        }
    }
}
