package cn.pluss.platform.api;

import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;

/**
 * TODO
 * 商户分账接口请求参数封装操作
 * @author crystal
 * @date 2022/6/29 15:54
 */
@Data
public class SplitReq {

    /**
     * 请求日志id
     */
    private String logId;

    /**
     * 请求方法名称
     */
    @Getter
    @AllArgsConstructor
    public enum Method{

        /**
         * 分账设置
         */
        MERC_ACCEPT("syb.split.merc.accept","分账设置"),
        ORDER_ACCEPT("syb.split.order.accept","订单分账"),
        SPLIT_QUERY("syb.split.merc.query","分账查询"),
        REFUND_QUERY("syb.split.refund.query","退款查询"),
        MERC_REFUND("syb.split.order.refund","分账退款");
        private String code;

        private String name;

        public static boolean vailMethod(String method){
            if(StringUtil.isEmpty(method)){
                return false;
            }
            for (Method m:Method.values()){
                if(m.getCode().equals(method)){
                    return true;
                }
            }
            return false;
        }

        public static Method getVal(String method){
            for (Method m:Method.values()){
                if(m.getCode().equals(method)){
                    return m;
                }
            }
            return null;
        }
    }

    @Getter
    @AllArgsConstructor
    public enum DivisionMode{

        /**
         * 分账类型比例
         */
        SCALE("01","比例"),

        /**
         * 分账类型金额
         */
        AMT("02","金额");

        private String value;

        private String name;

        public static boolean vailMode(String mode){
            if(StringUtil.isEmpty(mode)){
                return false;
            }
            if(mode.equals(AMT.getValue())){
                MsgException.throwException("分账类型为金额暂不可用");
            }
            for (DivisionMode m:DivisionMode.values()){
                if(m.getValue().equals(mode)){
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * 商户编号
     */
    private String merchantCode;


    private String method;

    /**
     * 分账模式 01：比例 02：金额
     */
    private String divisionMode;

    /**
     * 是否重新分账Y：是，N：否
     */
    private String isAgainDivision;

    /**
     * 原订单是否参与分账01：是，02否
     */
    private String isDivistion;

    /**
     * 签名
     */
    private String sign;

    /**
     * 商户订单号
     */
    private String mercOrderNo;

    /**
     * 退款金额
     */
    private String refundAmt;

    /**
     * 退款原因
     */
    private String refundReason;

    /**
     * 商户退款单号
     */
    private String mercRefundNo;

    /**
     * 异步通知地址
     */
    private String notifyUrl;

    /**
     * 原订单交易金额
     */
    private String orderAmt;

    private List<MercSubSplitAccount> divList;

    private List<SplitRefund> refundList;

    public Method checkParams() {
        MsgException.checkBlank(this.getMerchantCode(),"收款方商户号不能为空");
        MsgException.checkBlank(this.getLogId(),"请求日志id不能为空");
        MsgException.checkBlank(this.getMethod(),"请求方法method参数不能为空");
        MsgException.checkBlank(this.getSign(),"签名不能为空！");
        boolean flag = Method.vailMethod(this.getMethod());
        MsgException.check(!flag,"请求method参数有误！");
        Method val = Method.getVal(this.getMethod());
        switch (val){
            case MERC_ACCEPT:
                MsgException.checkBlank(this.getNotifyUrl(),"异步通知地址不能为空");
                MsgException.checkBlank(this.getDivisionMode(),"分账类型不能为空");
                MsgException.check(!DivisionMode.vailMode(this.getDivisionMode()),"分账类型参数有误");
                MsgException.checkBlank(this.getDivList(),"分账商户数据不能为空");
                for (MercSubSplitAccount sub:this.getDivList()) {
                    MsgException.checkBlank(sub.getMerchantCode(),"分账商户号不能为空");
                }
                break;
            case ORDER_ACCEPT:
                MsgException.checkBlank(this.getMercOrderNo(),"原商户订单号不能为空");
                MsgException.checkBlank(this.getNotifyUrl(),"异步通知地址不能为空");
                MsgException.checkBlank(this.getDivisionMode(),"分账类型不能为空");
                MsgException.check(!DivisionMode.vailMode(this.getDivisionMode()),"分账类型参数有误");
                MsgException.checkBlank(this.getDivList(),"分账详情数据不能为空");
                break;
            case SPLIT_QUERY:
                MsgException.checkBlank(this.getMercOrderNo(),"原交易单号不能为空！");
                break;
            case REFUND_QUERY:
                MsgException.checkBlank(this.getMercOrderNo(),"原商户交易单号不能为空！");
                MsgException.checkBlank(this.getMercRefundNo(),"商户退款单号不能为空！");
                break;
            case MERC_REFUND:
                MsgException.checkBlank(this.getMercOrderNo(),"原商户交易单号不能为空！");
                MsgException.checkNull(this.getRefundAmt(),"退款金额不能为空！");
                MsgException.check(!StringUtil.isNumber(this.getRefundAmt()),"退款金额格式有误，单位(元)保留两位小数!");
                MsgException.checkBlank(this.getRefundReason(),"退款原因不能为空！");
                MsgException.checkBlank(this.getNotifyUrl(),"异步回调地址不能为空！");
                MsgException.checkBlank(this.getMercRefundNo(),"商户退款单号不能为空！");
                MsgException.checkNull(this.getRefundList(),"分账商户退款信息不能为空！");
                MsgException.check(this.getRefundList().isEmpty(),"分账商户的退款参数不能为空！");
                break;
            default:
                MsgException.throwException("请求方法method参数有误！");
        }
        return val;
    }
}
