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 com.jeequan.jeepay.core.utils.SeqKit;
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;
//
//    /**
//     * 所属渠道
//     */
//    private String isvNo;

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

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

    /**
     * 分账值 分账比例为 比例值 分账金额为分账金额值
     */
    private BigDecimal divisionValue;

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

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

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

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

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

    /**
     * 分账说明函
     */
    private String url;


    @TableField(exist = false)
    private String mchName;

    @TableField(exist = false)
    private String ifName;

    @TableField(exist = false)
    private String isvName;

    /**
     * 分账分出方
     */
    @TableField(exist = false)
    private List<String> divisionList;

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

    /**
     * 参数校验
     */
    public void preCheck() {
        if(StringUtils.isEmpty(this.getTaskId())){
            this.setTaskId(SeqKit.genFlowNo("TA"));
        }
        Assert.hasLength(this.getName(),"分账任务名称不能为空");
//        Assert.hasLength(this.getIsvNo(),"所属通道不能空");
//        Assert.hasLength(this.getMchNo(),"所属用户不能为空");
        Assert.hasLength(this.getIfCode(),"所属通道不能为空");
        Assert.notNull(this.getDivisionMode(),"分账模式不能为空");
        Assert.notNull(this.getDivisionType(),"分账类型不能为空");
        Assert.hasLength(this.getUrl(),"分账场景说明函不能为空");
        Assert.notNull(this.getIsAuto(),"是否自动分账不能为空");
        Assert.notNull(this.getDivisionList(),"分账分出方不能为空");
        Assert.notNull(this.getReceiveList(),"分账接收方不能为空");
        if(this.getReceiveList().size() > 9){
            throw new BizException("分账接收方不允许超过9个");
        }
        this.getReceiveList().forEach(item -> {
            if(item.getDivisionValue() == null){
                throw new BizException("分账接收方详情中分账属性值不能为空");
            }
            if(item.getIsCharge() == null){
                throw new BizException("分账接收方详情中是否收取手续费不能为空");
            }
            if(item.getDivisionNo() == null){
                throw new BizException("分账接收方详情中分账收款方账户号不能为空");
            }
        });
    }

    /**
     * 校验配置信息
     */
    public void preSubjectCheck() {
        Assert.notNull(this.getTaskId(),"分账任务id不能为空");
        Assert.notEmpty(this.getReceiveList(),"分账接收方不能为空");
        this.getReceiveList().forEach(item -> {
            if(StringUtils.isEmpty(item.getDivisionNo())){
                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%");
        }
    }

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