package cn.pluss.platform.entity;

import cn.jiguang.common.utils.StringUtils;
import cn.pluss.platform.constants.Constant;
import cn.pluss.platform.entitiy.SettleTypeEnum;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.util.StringUtil;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

/**
 *
 * ALTER TABLE `shouyinbei`.`tb_pluss_merchant_order`
 * ADD COLUMN `rate` int(11) NULL COMMENT '商户费率，无则代表0.38%' AFTER `updateTime`;
 */
@Data
@TableName
@Accessors(chain = true)
public class MerchantOrder {

    public static final String UPGRADE_ORDER_PREFIX = "SJ000";


    public static final Double MARKET_MAX_TRANS_AMT= 1000.0d;

    /**
     * @description:小微单笔最大交易额度
     * @date: 2021/8/23 18:07
     */
    public static final Double MICRO_MAX_TRANS_AMT = 10000.0d;

    /**
     * @description:银联大额
     * @date: 2021/8/23 18:12
     */
    public static final Double BANK_LARGE_AMT = 1000.0d;

    @TableId(type = IdType.AUTO)
    private Long id;
    private String orderNumber;
    private String userImg;
    private String nickName;

    /**
     * 2、3、9、10，属于要输入密码的
     * 1、反扫收款；2、收款码；3、会员充值；4、POS；5、反扫会员充值；6、扫码王、QR68机具收款 7：H5 8：升级收费 9小程序 10表示小程序线上店订单 11:表示缴费通 99 插件
     * 20、会员消费，这里只做标记，数据库不存储会员消费记录
     */
    private String orderType;

    private String merchantCode;
    private String merchantName;
    private String payTypeCode;
    private String payTypeName;

    private String storeId;
    private String storeName;
    private Double consumeFee;

    /**
     * @description:
     * @date: 2021/8/5 粉丝分润
     */
    private Double fansShareMoney;
    /**
     * @description:
     * @date: 2021/8/5 推广分润
     */
    private Double profitShareMoney;

    private String transNo;
    private String memberCode;
    @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
    private Date createDt;
    @JsonFormat(shape=JsonFormat.Shape.STRING,pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
    private Date transDt;
    private String staffCode;
    private String staffName;
    /**
     * 交易状态 0:交易失败 1:交易成功 2：退款成功 3：退款失败 4：退款中 5:待付款  6部分退款 7:待确认
     */
    private String status;

    public void setCreateDt(Date date) {
        this.createDt = date;
        this.updateTime = date;
    }

    public void setTransDt(Date date) {
        this.transDt = date;
        this.updateTime = date;
    }



    /**
     * 支付方的订单号，支付宝/微信/银联等
     */
    private String thirdTransNo;

    private Double enterFee;
    /**
     * 支付通道 0 支付宝微信官方通道 1乐刷通道
     */
    private String aisleSwitch;

    private String remark;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;

    private BigDecimal rate;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @TableField(insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
    private LocalDate createDate;

    /**
     * 老板名称
     */
    @TableField(exist = false)
    private String userName;
    /**
     * 老板手机号
     */
    @TableField(exist = false)
    private String phone;
    /**
     * 查询条件
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(exist = false, condition = "createTime &gt;= #{%s}")
    private Date startTime;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(exist = false, condition = "createTime &lt;= #{%s}")
    private Date endTime;
    @TableField(exist = false)
    private Integer size;
    @TableField(exist = false)
    private Integer page;
    @TableField(exist = false)
    private String logo;

    /**
     * 订单类型，文字说明
     */
    @TableField(exist = false)
    private String orderTypeDesc;

    /**
     * 商家简称
     */
    @TableField(exist = false)
    private String alias;
    /**
     * 营销活动补贴金额
     */
    private BigDecimal marketAmt;

    @TableField(exist = false)
    private Integer userId;

    private String mercOrderNo;

    private String mercNotifyUrl;

    private String mercUserId;

    private String mercNotifyStatus;

    private String mercRemark;

    /**
     * 是否会员充值订单
     */
    private String isRecharge;

    /**
     * 关联马牌编号
     */
    private String snNo;

    /**
     * 关联的收银点id
     */
    private String cashPlaceId;

    /**
     * 0：D0结算 1：D1结算 参考枚举值
     * {@link cn.pluss.platform.entitiy.SettleTypeEnum}
     */
    private Integer settlementType;

    /**
     * 借贷标识
     * 1: 借记卡 2：贷记卡 3：其他
     */
    private String drType;

    /**
     * @description:通道成本费率
     * @date: 2021/8/25 11:03
     */
    private BigDecimal channelRate;

    /**
     * @description:通道手续费
     * @date: 2021/8/25 11:04
     */
    private BigDecimal channelFee;

    /**
     * @description:商户手续费
     * @date: 2021/8/25 11:04
     */
    private BigDecimal mercFee;

    /**
     * 节约金额
     */
    @TableField(exist = false)
    private BigDecimal saveAmt;

    /**
     * @description:退款金额
     * @date: 2021/11/22 14:16
     */
    private BigDecimal refundAmt;

    /**
     * @description:退款类型 1：全额退款 2：部分退款
     * @date: 2021/11/22 14:19
     */
    @TableField(exist = false)
    private Integer refundType;

    /**
     * @description:已退款金额
     * @date: 2021/11/22 14:16
     */
    @TableField(exist = false)
    private BigDecimal useRefundAmt;

    @TableField(exist = false)
    private String token;

    /**
     * 订单备注
     */
    @TableField(exist = false)
    private String subject;

    @TableField(exist = false)
    private String province;

    @TableField(exist = false)
    private String city;

    /**
     * 自定义查询条件
     */
    @TableField(exist = false)
    private Map<String,Object> params;

    /**
     * @description:ip
     * @date: 2021/9/30 10:34
     */
    private String ip;

    /**
     * @description:ip对应的地址
     * @date: 2021/9/30 10:34
     */
    private String ipAddress;

    /**
     * @description:返回地址
     * @date: 2021/9/30 18:11
     */
    private String mercReturnUrl;

    /**
     * @description:预授权订单状态 1：预授权中 2:预授权撤销 3：预授权完成 4：预授权完成撤销 5：冲正 6：退货
     * @date: 2021/10/28 16:39
     */
    private String preAuthStatus;

    /**
     * 渠道返回支付数据
     * @date: 2021/12/29 15:27
     */
    private String payData;

    /**
     * 提现手续费
     */
    private BigDecimal cashFee;

    /**
     * 扫码类型 01：扫码 2：其他
     * @date: 2021/12/22 17:00
     */
    @TableField(exist = false)
    private String scanType;

    /**
     * 优惠金额
     */
    @TableField(exist = false)
    private Double discount;

    /**
     * 扩展参数
     */
    @TableField(exist = false)
    private String extendParam;


    public static void updateOrderTypeDesc(MerchantOrder order) {
        if (order == null) {
            return;
        }

        if ("2".equals(order.getStatus())) {
            order.setOrderTypeDesc("退款");
        }

        switch (order.getOrderType()) {
            case "1":
                order.setOrderTypeDesc("反扫收款");
                break;
            case "2":
                order.setOrderTypeDesc("收款码");
                break;
            case "3":
                order.setOrderTypeDesc("会员充值");
                break;
            case "4":
                order.setOrderTypeDesc("POS刷卡");
                break;
            case "5":
                order.setOrderTypeDesc("反扫会员充值");
                break;
            case "6":
                order.setOrderTypeDesc("扫码王");
                break;
            case "7":
                order.setOrderTypeDesc("H5");
                break;
            case "9":
                order.setOrderTypeDesc("收款码");
                break;
            case "10":
                order.setOrderTypeDesc("线上店");
                break;
            default:
                order.setOrderTypeDesc("未知订单类型");
                break;
        }
    }

    public static void updateStaffName(MerchantOrder merchantOrder, String merchantCode, IdCard idCard) {
        if (!merchantOrder.getMerchantCode().equals(merchantCode)) {
            return;
        }

        switch (merchantOrder.getOrderType()) {
            case "1":
                if (idCard != null && Objects.equals(merchantOrder.getStaffCode(), idCard.getUserId() + "")) {
                    // 说明是主商户的主扫
                    merchantOrder.setStaffName(idCard.getCertName());
                }
                break;
            case "10":
                merchantOrder.setStaffName("线上店");
                break;
            default:
                if (StringUtils.isEmpty(merchantOrder.getStaffName())) {
                    merchantOrder.setStaffName("收款码");
                }

                break;
        }
    }

    public static boolean isVipRecharge(MerchantOrder merchantOrder) {
        return "3".equals(merchantOrder.getOrderType()) || "5".equals(merchantOrder.getOrderType());
    }

    public RealFans convertRealFans(){
        RealFans realFans = new RealFans();
        realFans.setSoleId(mercUserId);
        realFans.setEnableMerchantCode(merchantCode);
        realFans.setLogo(logo);
        realFans.setNickName(nickName);
        realFans.setPhone(phone);
        realFans.setEnableTime(new Date());
        return realFans;
    }
    /**
     * @description:
     * @date: 2021/8/24 10:37 
 * @param merchant:
     */
    public void isAllowBankLarge(MerchantBaseInfo merchant) {
        if(this.getConsumeFee() > MICRO_MAX_TRANS_AMT && "1".equals(merchant.getMerchantType())){
            MsgException.throwException("单笔金额超限！");
        }
        if(Constant.PAY_TYPE_YSFPAY.equals(this.getPayTypeCode()) || "sxfPay2".equals(this.getPayTypeCode())){

            if(!"1".equals(merchant.getIsUnionPay())){
                if("4".equals(this.getAisleSwitch())){
                    MsgException.throwException("实时到账通道暂不支持银联支付，请修改次日到账交易");
                }else{
                    MsgException.throwException("当前商户银联支付未开启,请联系客服");
                }
            }
            if(this.getConsumeFee() > BANK_LARGE_AMT){
                if(this.getOrderNumber().startsWith("SXF")){
                    MsgException.throwException("当前通道不支持"+BANK_LARGE_AMT+"以上的银联云闪付付款，请在APP中切换通道或跟换支付方式交易！");
                }
                //TODO 关闭银联1000以上的付款
                MsgException.throwException("暂不支持银联云闪付"+BANK_LARGE_AMT+"以上的交易！");
                if(!"1".equals(merchant.getAllowBankLarge())){
                    MsgException.throwException("未开启银联云闪付"+BANK_LARGE_AMT+"以上的交易，如需要请手动在APP中开启！");
                }
            }
        }
    }

    /**
     * @description:计算当前订单手续费以及实际到账金额
     * @date: 2021/8/25 13:45
     */
    public void calcRateAndFee(BigDecimal rate) {
        BigDecimal calcRate = rate.divide(new BigDecimal(10000));
        BigDecimal mercFee = new BigDecimal(this.getConsumeFee()).multiply(calcRate).setScale(2, RoundingMode.HALF_UP);
        BigDecimal fee = BigDecimal.ZERO;
        if(this.getOrderNumber().startsWith("YS") && fee.doubleValue() <= 0.1d
                && SettleTypeEnum.D0.getValue().equals(this.getSettlementType())){
            fee = fee.add(new BigDecimal("0.1"));
        }
        this.setMercFee(mercFee);
        this.setEnterFee(StringUtil.bigDecimal(this.getConsumeFee() - mercFee.doubleValue() - fee.doubleValue()));
        this.setRate(rate);
    }

    /**
     * 参数转换
     * @param orderNew
     * @param refundAmt
     */
    public void convert(MercOrderNew orderNew, BigDecimal refundAmt,Integer settlementType,String refundReason) {
        if(refundAmt == null){
            this.consumeFee = orderNew.getOrderAmt().doubleValue();
        }else{
            this.consumeFee = refundAmt.doubleValue();
        }
        this.orderNumber = orderNew.getOrderNo();
        this.settlementType = settlementType;
        this.transNo = orderNew.getTransNo();
        this.remark = refundReason;
    }

    /**
     * 新版设备订单表参数转换
     * @param order
     */
    public void convert(MercOrderNew order,MerchantStore store) {
        this.setOrderNumber(order.getOrderNo());
        this.setOrderType("9");
        this.setMerchantCode(order.getMerchantCode());
        this.setMerchantName(order.getMerchantName());
        this.setPayTypeCode(order.getPayType());
        this.setPayTypeName(Constant.PAY_TYPE_ALIPAY.equals(order.getPayType()) ? Constant.PAY_TYPE_NAME_ALIPAY :
                Constant.PAY_TYPE_WECHAT.equals(order.getPayType()) ?
                        Constant.PAY_TYPE_NAME_WECHAT : Constant.PAY_TYPE_NAME_YSFPAY);
        this.setThirdTransNo(order.getThirdTransNo());
        if(store != null){
            this.setStoreId(store.getStoreId());
            this.setStoreName(store.getStoreName());
        }
        this.setConsumeFee(order.getActualAmt().doubleValue());
        this.setTransNo(order.getTransNo());
        this.setCreateDt(order.getCreateTime());
        this.setTransDt(order.getTransDt());
        this.setStatus("1");
        BigDecimal mercFee = Constant.MIX_SETTLE_RATE.divide(BigDecimal.valueOf(10000)).multiply(order.getActualAmt()).setScale(2,BigDecimal.ROUND_HALF_DOWN);
        this.setEnterFee(order.getActualAmt().subtract(mercFee).doubleValue());
        this.setMercFee(mercFee);
        this.setChannelRate(Constant.MIX_SETTLE_RATE);
        this.setChannelFee(mercFee);
        this.setMercUserId(order.getPayUserId());
        this.setRate(Constant.MIX_SETTLE_RATE);
        this.setSettlementType(SettleTypeEnum.D1.getValue());
    }

    /**
     * 缴费通订单表转化成订单表数据
     * @param order
     */
    public void convert(JftReceiptOrder order) {
        this.setOrderNumber(order.getOrderNumber());
        this.setOrderType("11");
        this.setMerchantCode(order.getMerchantCode());
        this.setMerchantName(order.getMerchantName());
        this.setPayTypeCode(order.getPayType());
        this.setPayTypeName(Constant.PAY_TYPE_ALIPAY.equals(order.getPayType()) ? Constant.PAY_TYPE_NAME_ALIPAY :
                Constant.PAY_TYPE_WECHAT.equals(order.getPayType()) ?
                        Constant.PAY_TYPE_NAME_WECHAT : Constant.PAY_TYPE_NAME_YSFPAY);
        this.setThirdTransNo(order.getChannelTransNo());
        this.setConsumeFee(order.getAmount().doubleValue());
        this.setTransNo(order.getTransNo());
        this.setCreateDt(order.getCreateTime());
        this.setTransDt(order.getTransTime());
        this.setStatus("1");
        this.setEnterFee(order.getAmount().subtract(order.getMercFee()).doubleValue());
        this.setMercFee(order.getMercFee());
        this.setChannelRate(Constant.DEFAULT_JFT_COST_RATE);
        this.setChannelFee(order.getChannelFee());
        this.setMercUserId(order.getPayUserId());
        this.setRate(BigDecimal.valueOf(order.getRate()));
        this.setSettlementType(SettleTypeEnum.D0.getValue());
        this.setUserId(Integer.valueOf(order.getUserId().toString()));
        this.setMercNotifyUrl(order.getMercNotifyUrl());
        this.setMercOrderNo(order.getMercOrderNo());
    }
}