package com.jeequan.jeepay.db.entity;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.RandomUtil;
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.constants.CS;
import com.jeequan.jeepay.core.model.BaseModel;
import com.jeequan.jeepay.db.typehandler.EncryptTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Locale;

/**
 * <p>
 *
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2023-12-06
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(value = "t_settle_info",autoResultMap = true)
@NoArgsConstructor
public class SettleInfo extends BaseModel {

    private static final long serialVersionUID=1L;

    public static final String TRANS_SCOPE_DATE_SPLIT = "~";

    /**
     * 结算状态 -1：付款失败 0：待付款 1：付款中  2：付款成功，3：暂缓 4：冻结 5：退票 98:待查看(针对部分通道没有结算记录的情况下，使用该状态让客户核实银行卡的到账流水) 99：其他
     */
    public static final byte FAIL = -1;
    public static final byte WAIT = 0;
    public static final byte PROGRESS = 1;
    public static final byte SUCCESS = 2;
    public static final byte SUSPEND = 3;
    public static final byte FREEZE = 4;
    public static final byte TICKET = 5;
    public static final byte CONFIRM = 98;
    public static final byte OTHER = 99;



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

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

    public static String SETTLE_NO_PRIFEX = "ST";

    /**
     * 结算编号
     */
    @TableId
    private String settleNo;

    /**
     * 通道结算账单号
     */
    private String billNo;

    /**
     * 应用ID
     */
    private String appid;

    /**
     * 用户号(原先的商户号)
     */
    private String mchNo;

    /**
     * 商户号 也就是申请单编号 现在改成商户号了
     */
    private String mchExtNo;

    /**
     * 服务商号
     */
    private String isvNo;

    /**
     * 服务商号
     */
    private String agentNo;

    /**
     * 商户名称
     */
    private String mchName;

    /**
     * 通道商户编号
     */
    private String channelMchNo;

    /**
     * D0 D1 T1
     */
    private String settleType;


    /**
     * 预付金额 单位分
     */
    private Long planAmt;

    /**
     * 结算金额 单位分
     */
    private Long settleAmt;

    /**
     * 手续费 分
     */
    private Long fee;

    /**
     * 结算状态 -1：付款失败 0：待付款 1：付款中  2：付款成功，3：暂缓 4：冻结 5：退票 98:待查看(针对部分通道没有结算记录的情况下，使用该状态让客户核实银行卡的到账流水) 99：其他
     */
    private Byte state;

    /**
     * 结算账户号
     */
    @TableField(typeHandler = EncryptTypeHandler.class)
    private String accountNo;

    /**
     * 结算账户名
     */
    @TableField(typeHandler = EncryptTypeHandler.class)
    private String accountName;

    /**
     * 结算日期
     */
    private String settleDate;

    /**
     * 扩展流水号
     */
    private String extFlowNo;

    /**
     * 通道错误码
     */
    private String channelCode;

    /**
     * 备注 一般用于存储通道相关的返回信息
     */
    private String remark;

    /**
     * 扩展json参数
     */
    private String extra;

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

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

    /**
     * 通道类型
     */
    private String ifCode;


    private String bankName;

    /**
     * 交易金额（订单表里的实付金额）
     */
    private Long transactionAmount;

    /**
     * 交易数量
     */
    private Integer transactionNumber;

    /**
     * 通道返回的结算状态
     */
    private String channelState;


    @TableField(exist = false)
    private String ifName;

    @TableField(exist = false)
    private Date settleTime;

    /**
     * 渠道简称
     */
    @TableField(exist = false)
    private String isvShortName;

    @TableField(exist = false)
    private String isvName;

    @TableField(exist = false)
    private String appName;

    @TableField(exist = false)
    private String nameAndNo;

    @TableField(exist = false)
    private String agentName;

    @TableField(exist = false)
    private String agentContactTel;

    @TableField(exist = false)
    private String mchUserName;

    @TableField(exist = false)
    private String mchUserPhone;

    private Long cashFee;

    /**
     * 交易日期范围
     */
    private String transDateScope;

    /**
     * 结算数据构造方法
     * @param order
     * @param totalRefundAmount
     * @param stateTransDate
     * @param endTransDate
     */
    public SettleInfo(PayOrder order,Long totalRefundAmount,Date stateTransDate,Date endTransDate) {
        //生成一个系统结算单号
        this.settleNo = SETTLE_NO_PRIFEX + DateUtil.format(new DateTime(), DatePattern.PURE_DATETIME_MS_FORMAT) + RandomUtil.randomString(RandomUtil.BASE_CHAR,1).toUpperCase(Locale.ROOT);
        this.mchNo = order.getMchNo();
        this.mchExtNo = order.getMchExtNo();
        this.isvNo = order.getIsvNo();
        this.agentNo = order.getAgentNo();
        this.mchName = order.getMchName();
        this.channelMchNo = order.getChannelMchNo();
        this.settleType = order.getSettleType();
        this.planAmt = order.getFindAmt() - totalRefundAmount - order.getMchFeeAmount() - order.getCashFee();
        this.ifCode = order.getIfCode();
        this.settleDate = DateUtil.formatDate(new DateTime());
        this.appid = order.getAppId();
        this.cashFee = order.getCashFee();
        this.extFlowNo = order.getPayOrderId();
        this.remark = "数据初始化";
        this.transactionNumber = order.getNumber();
        this.transactionAmount = order.getFindAmt() - totalRefundAmount;
        this.transDateScope = DateUtil.format(stateTransDate,DatePattern.NORM_DATE_PATTERN) + TRANS_SCOPE_DATE_SPLIT +  DateUtil.format(endTransDate,DatePattern.NORM_DATE_PATTERN);
        this.fee = order.getMchFeeAmount();
        //TODO 如果是拉卡拉 除了支付宝和微信 金额小与10元 则D1结算
        if(CS.IF_CODE.LKLSPAY.equals(order.getIfCode())){
            if(!CS.PAY_WAY_CODE_TYPE.WECHAT.equals(order.getWayCodeType()) && !CS.PAY_WAY_CODE_TYPE.ALIPAY.equals(order.getWayCodeType())){
                this.settleType = CS.SETTLEMENT_TYPE.D1;
                this.setRemark(this.remark + "(拉卡拉通道银联云闪付交易或单笔超限交易均转为D1次日到账)");
            }
            if(order.getFindAmt().longValue() <= 100){
                this.settleType = CS.SETTLEMENT_TYPE.D1;
                this.setRemark(this.remark + "(拉卡拉通道单笔结算金额低于10元将会转为次日到账)");
            }
        }

        //如果是D0 则设置结算金额 DO 交易 直接变成待确认
        if(CS.SETTLEMENT_TYPE.D0.equals(this.getSettleType())){
            this.settleAmt = BigDecimal.valueOf(order.getFindAmt()).subtract(BigDecimal.valueOf(order.getMchFeeAmount())).subtract(BigDecimal.valueOf(order.getCashFee())).longValue();
            this.state = CONFIRM;
            this.remark = "请登录对应的银行app，核实银行卡的到账流水";
        }
    }

    public String getAccountNo() {
        if(StringUtils.isEmpty(this.accountNo)){
            return null;
        }
        if(this.accountNo.contains("*")){
            return this.accountNo;
        }
        return DesensitizedUtil.bankCard(this.accountNo);
    }

    public String getAccountName() {
        if(StringUtils.isEmpty(this.accountName)){
            return null;
        }
        if(this.accountName.contains("*")){
            return this.accountName;
        }
        return DesensitizedUtil.chineseName(this.accountName);
    }
}
