package com.jeequan.jeepay.db.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 分账任务表
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2024-04-02
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(value = "t_division_task",autoResultMap = true)
public class DivisionTask extends BaseModel {

    public static final LambdaQueryWrapper<DivisionTask> gw(DivisionTask entity){
        return new LambdaQueryWrapper<>(entity);
    }

    public static final LambdaQueryWrapper<DivisionTask> gw(){
        return new LambdaQueryWrapper<>();
    }

    private static final long serialVersionUID=1L;

    /**
     * 默认最大分账比例
     */
    public static final BigDecimal DEFAULT_MAX_RATIO = BigDecimal.valueOf(0.3);

    /**
     * 比例
     */
    public static final byte DIV_MODE_RATIO = 0;

    /**
     * 金额
     */
    public static final byte DIV_MODE_AMOUNT = 1;

    /**
     * 实时分账
     */
    public static final byte DIV_TYPE_SS = 0;

    /**
     * 延时分账
     */
    public static final byte DIV_TYPE_YS = 1;

    /**
     * 秒到分账
     */
    public static final byte DIV_TYPE_MD = 2;

    /**
     * 任务ID
     */
    @TableId(value = "task_id", type = IdType.INPUT)
    private String taskId;

    /**
     * 任务名称
     */
    private String name;

    /**
     * 用户号
     */
    private String mchNo;

    /**
     * 所属渠道
     */
    private String ifCode;

    /**
     * 分账模式 0：比例分账  1：金额分账
     */
    private Byte divisionMode;

    /**
     * 分账类型 0：实时分账  1：延时分账 2：秒到分账
     */
    private Byte divisionType;

    /**
     * 分账金额 按照金额分账的时候需要传该值
     */
    private Long divisionAmount;

    /**
     * 最小金额 当交易金额大于当前值的时候会触发后台的分账模板的分账
     */
    private Long minAmount;

    /**
     * 状态 0：禁用 1：启用
     */
    private Byte state;

    /**
     * 是否自动分账 0：否 1：是
     */
    private Byte isAuto;

    /**
     * 创建时间
     */
    private Date createdAt;

    /**
     * 更新时间
     */
    private Date updatedAt;


    @TableField(exist = false)
    private String mchName;

    @TableField(exist = false)
    private String ifName;


    /**
     * 分账接收方
     */
    @TableField(exist = false)
    private List<DivisionSubject> receiveList;

    /**
     * 分账支出方
     */
    @TableField(exist = false)
    private List<DivisionSubject> expendList;

    /**
     * 参数校验
     */
    public void preCheck() {
        Assert.hasLength(this.getName(),"名称不能为空");
        Assert.hasLength(this.getMchNo(),"所属用户不能为空");
        Assert.hasLength(this.getIfCode(),"所属渠道不能为空");
        Assert.notNull(this.getDivisionMode(),"分账模式不能为空");
        Assert.notNull(this.getDivisionType(),"分账类型不能为空");
        if(this.getDivisionMode() == DIV_MODE_AMOUNT){
            Assert.notNull(this.getDivisionAmount(),"分账模式为金额的时候，分账固定金额不能为空");
            Assert.notNull(this.getMinAmount(),"分账模式为金额的时候，最小发起分账的交易金额的限制不能为空");
            Long calcMinAmount = new BigDecimal(this.getDivisionAmount()).divide(DEFAULT_MAX_RATIO, 0, RoundingMode.HALF_UP).longValue();
            if(this.getMinAmount() < calcMinAmount){
                throw new IllegalArgumentException("分账模式为金额的时候，设置的最小发起分账金额的限制必须大于或等于分账金额乘以分账的默认比例");
            }
        }
    }

    /**
     * 校验配置信息
     */
    public void preConfigCheck() {
        Assert.notNull(this.getTaskId(),"模板id不能为空");
        Assert.notEmpty(this.getExpendList(),"分账分出方不能为空");
        Assert.notEmpty(this.getReceiveList(),"分账接收方不能为空");
        List<String> expend = this.getExpendList().stream().map(DivisionSubject::getDivisionNo).collect(Collectors.toList());
        List<String> receive = this.getReceiveList().stream().map(DivisionSubject::getDivisionNo).collect(Collectors.toList());
        int expendSize = expend.size();
        expend.removeAll(receive);
        if(expendSize != expend.size()){
            throw new BizException("分账分出方和分账接收方不能存在交集");
        }
        this.getExpendList().forEach(item -> {
            if(item.getUserType() == null){
                throw new BizException("分账分出方数据中包含用户类型为空的数据");
            }
            if(StringUtils.isEmpty(item.getDivisionNo())){
                throw new BizException("分账分出方数据中包含手机号/商户号为空的数据");
            }
            if(StringUtils.isEmpty(item.getName())){
                throw new BizException("分账分出方数据中包含个人名称/商户名称为空的数据");
            }
        });

        this.getReceiveList().forEach(item -> {
            if(item.getUserType() == null){
                throw new BizException("分账接收方数据中包含用户类型为空的数据");
            }
            if(StringUtils.isEmpty(item.getDivisionNo())){
                throw new BizException("分账接收方数据中包含手机号/商户号为空的数据");
            }
            if(StringUtils.isEmpty(item.getName())){
                throw new BizException("分账接收方数据中包含个人名称/商户名称为空的数据");
            }
            if(item.getIsCharge() == null){
                throw new BizException("分账接收方数据中包含是否收取手续为空的数据");
            }
            if(item.getInfo() == null){
                throw new BizException("分账接收方数据中包含分账金额或比例为空的数据");
            }
        });
    }

    /**
     * 校验分账比例
     */
    public void checkDivisionRationValue(DivisionTask ext) {
        BigDecimal totalRatio = BigDecimal.ZERO;
//        for (DivisionSubject templateConfig:this.getReceiveList()) {
//            totalRatio = totalRatio.add(templateConfig.getDivisionValue());
//        }
        if(totalRatio.compareTo(DEFAULT_MAX_RATIO) > 0){
            throw new BizException("分账接收方所有分账比例不能超过30%");
        }
    }

    public void checkDivisionAmountValue(DivisionTask ext) {
        BigDecimal totalAmt = BigDecimal.ZERO;
//        for (DivisionSubject templateConfig:this.getReceiveList()) {
//            totalAmt = totalAmt.add(templateConfig.getDivisionValue());
//        }
        totalAmt = totalAmt.multiply(BigDecimal.valueOf(100));
        if(totalAmt.longValue() > ext.getDivisionAmount()){
            throw new BizException("分账接收分账金额之后不能超过所设置的分账金额");
        }
    }
}
