package com.slodon.b2b2c.vo.statistics;

import com.slodon.b2b2c.statistics.pojo.base.PlatformBase;
import com.slodon.b2b2c.statistics.pojo.base.StoreBase;
import com.slodon.b2b2c.statistics.pojo.base.TerminalBase;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.math.RoundingMode;

import static com.slodon.b2b2c.vo.statistics.FlowOverviewVO.*;

/**
 *
 * 封装交易分析-交易总览Vo对象
 * @author wuxy
 */
@NoArgsConstructor
@Data
public class TradeOverviewVO {

    @ApiModelProperty("浏览量")
    private Integer viewNum = 0;

    @ApiModelProperty("较上期浏览量")
    private String previousViewNum;

    @ApiModelProperty("访客数")
    private Integer visitorNum = 0;

    @ApiModelProperty("较上期访客数")
    private String previousVisitorNum;

    @ApiModelProperty("下单金额")
    private BigDecimal orderSubmitAmount = BigDecimal.ZERO;

    @ApiModelProperty("较上期下单金额")
    private String previousOrderSubmitAmount;

    @ApiModelProperty("下单数")
    private Integer orderSubmitNum = 0;

    @ApiModelProperty("较上期下单数")
    private String previousOrderSubmitNum;

    @ApiModelProperty("下单人数")
    private Integer orderSubmitMemberNum = 0;

    @ApiModelProperty("较上期下单人数")
    private String previousOrderSubmitMemberNum;

    @ApiModelProperty("下单客单价")
    private BigDecimal orderSubmitAtv = BigDecimal.ZERO;

    @ApiModelProperty("较上期下单客单价")
    private String previousOrderSubmitAtv;

    @ApiModelProperty("支付金额")
    private BigDecimal orderPayAmount = BigDecimal.ZERO;

    @ApiModelProperty("较上期支付金额")
    private String previousOrderPayAmount;

    @ApiModelProperty("支付订单数")
    private Integer orderPayNum = 0;

    @ApiModelProperty("较上期支付订单数")
    private String previousOrderPayNum;

    @ApiModelProperty("支付人数")
    private Integer orderPayMemberNum = 0;

    @ApiModelProperty("较上期支付人数")
    private String previousOrderPayMemberNum;

    @ApiModelProperty("支付客单价")
    private BigDecimal orderPayAtv = BigDecimal.ZERO;

    @ApiModelProperty("较上期支付客单价")
    private String previousOrderPayAtv;

    @ApiModelProperty("访问-下单转化率，下单人数/访客数*100%")
    private String pvSubmitRate;

    @ApiModelProperty("访问-支付转化率，支付订单人数/访客数*100%")
    private String pvPayRate;

    @ApiModelProperty("下单-支付转化率，支付订单人数/下单人数*100%")
    private String submitPayRate;

    public TradeOverviewVO(PlatformBase platformBase, PlatformBase previousData) {
        this.viewNum = platformBase.getViewNum();
        this.visitorNum = platformBase.getVisitorNum();
        this.orderSubmitAmount = platformBase.getOrderSubmitAmount();
        this.orderSubmitNum = platformBase.getOrderSubmitNum();
        this.orderSubmitMemberNum = platformBase.getOrderSubmitMemberNum();
        BigDecimal submitAtv = dealOrderSubmitAtv(platformBase.getOrderSubmitAmount(), platformBase.getOrderSubmitMemberNum());
        this.orderSubmitAtv = submitAtv;
        this.orderPayAmount = platformBase.getOrderPayAmount();
        this.orderPayNum = platformBase.getOrderPayNum();
        this.orderPayMemberNum = platformBase.getOrderPayMemberNum();
        BigDecimal payAtv = dealOrderPayAtv(platformBase.getOrderPayAmount(), platformBase.getOrderPayMemberNum());
        this.orderPayAtv = payAtv;
        this.pvSubmitRate = dealPvSubmitRate(platformBase.getOrderSubmitMemberNum(), platformBase.getVisitorNum());
        this.pvPayRate = dealPvPayRate(platformBase.getOrderPayMemberNum(), platformBase.getVisitorNum());
        this.submitPayRate = dealSubmitPayRate(platformBase.getOrderPayMemberNum(), platformBase.getOrderSubmitMemberNum());
        if (previousData != null) {
            this.previousViewNum = dealPreviousViewNum(platformBase.getViewNum(), previousData.getViewNum());
            this.previousVisitorNum = dealPreviousVisitorNum(platformBase.getVisitorNum(), previousData.getVisitorNum());
            this.previousOrderSubmitAmount = dealPreviousOrderSubmitAmount(platformBase.getOrderSubmitAmount(), previousData.getOrderSubmitAmount());
            this.previousOrderSubmitNum = dealPreviousOrderSubmitNum(platformBase.getOrderSubmitNum(), previousData.getOrderSubmitNum());
            this.previousOrderSubmitMemberNum = dealPreviousOrderSubmitMemberNum(platformBase.getOrderSubmitMemberNum(), previousData.getOrderSubmitMemberNum());
            BigDecimal preSubmitAtv = dealOrderSubmitAtv(platformBase.getOrderSubmitAmount(), platformBase.getOrderSubmitMemberNum());
            this.previousOrderSubmitAtv = dealPreviousOrderSubmitAtv(submitAtv, preSubmitAtv);
            this.previousOrderPayAmount = dealPreviousOrderPayAmount(platformBase.getOrderPayAmount(), previousData.getOrderPayAmount());
            this.previousOrderPayNum = dealPreviousOrderPayNum(platformBase.getOrderPayNum(), previousData.getOrderPayNum());
            this.previousOrderPayMemberNum = dealPreviousOrderPayMemberNum(platformBase.getOrderPayMemberNum(), previousData.getOrderPayMemberNum());
            BigDecimal prePayAtv = dealOrderPayAtv(platformBase.getOrderPayAmount(), platformBase.getOrderPayMemberNum());
            this.previousOrderPayAtv = dealPreviousOrderPayAtv(payAtv, prePayAtv);
        }
    }

    public TradeOverviewVO(TerminalBase terminalBase, TerminalBase previousData) {
        this.viewNum = terminalBase.getViewNum();
        this.visitorNum = terminalBase.getVisitorNum();
        this.orderSubmitAmount = terminalBase.getOrderSubmitAmount();
        this.orderSubmitNum = terminalBase.getOrderSubmitNum();
        this.orderSubmitMemberNum = terminalBase.getOrderSubmitMemberNum();
        BigDecimal submitAtv = dealOrderSubmitAtv(terminalBase.getOrderSubmitAmount(), terminalBase.getOrderSubmitMemberNum());
        this.orderSubmitAtv = submitAtv;
        this.orderPayAmount = terminalBase.getOrderPayAmount();
        this.orderPayNum = terminalBase.getOrderPayNum();
        this.orderPayMemberNum = terminalBase.getOrderPayMemberNum();
        BigDecimal payAtv = dealOrderPayAtv(terminalBase.getOrderPayAmount(), terminalBase.getOrderPayMemberNum());
        this.orderPayAtv = payAtv;
        this.pvSubmitRate = dealPvSubmitRate(terminalBase.getOrderSubmitMemberNum(), terminalBase.getVisitorNum());
        this.pvPayRate = dealPvPayRate(terminalBase.getOrderPayMemberNum(), terminalBase.getVisitorNum());
        this.submitPayRate = dealSubmitPayRate(terminalBase.getOrderPayMemberNum(), terminalBase.getOrderSubmitMemberNum());
        if (previousData != null) {
            this.previousViewNum = dealPreviousViewNum(terminalBase.getViewNum(), previousData.getViewNum());
            this.previousVisitorNum = dealPreviousVisitorNum(terminalBase.getVisitorNum(), previousData.getVisitorNum());
            this.previousOrderSubmitAmount = dealPreviousOrderSubmitAmount(terminalBase.getOrderSubmitAmount(), previousData.getOrderSubmitAmount());
            this.previousOrderSubmitNum = dealPreviousOrderSubmitNum(terminalBase.getOrderSubmitNum(), previousData.getOrderSubmitNum());
            this.previousOrderSubmitMemberNum = dealPreviousOrderSubmitMemberNum(terminalBase.getOrderSubmitMemberNum(), previousData.getOrderSubmitMemberNum());
            BigDecimal preSubmitAtv = dealOrderSubmitAtv(previousData.getOrderSubmitAmount(), previousData.getOrderSubmitMemberNum());
            this.previousOrderSubmitAtv = dealPreviousOrderSubmitAtv(submitAtv, preSubmitAtv);
            this.previousOrderPayAmount = dealPreviousOrderPayAmount(terminalBase.getOrderPayAmount(), previousData.getOrderPayAmount());
            this.previousOrderPayNum = dealPreviousOrderPayNum(terminalBase.getOrderPayNum(), previousData.getOrderPayNum());
            this.previousOrderPayMemberNum = dealPreviousOrderPayMemberNum(terminalBase.getOrderPayMemberNum(), previousData.getOrderPayMemberNum());
            BigDecimal prePayAtv = dealOrderPayAtv(previousData.getOrderPayAmount(), previousData.getOrderPayMemberNum());
            this.previousOrderPayAtv = dealPreviousOrderPayAtv(payAtv, prePayAtv);
        }
    }

    public TradeOverviewVO(StoreBase storeBase, StoreBase previousData) {
        this.viewNum = storeBase.getViewNum();
        this.visitorNum = storeBase.getVisitorNum();
        this.orderSubmitAmount = storeBase.getOrderSubmitAmount();
        this.orderSubmitNum = storeBase.getOrderSubmitNum();
        this.orderSubmitMemberNum = storeBase.getOrderSubmitMemberNum();
        BigDecimal submitAtv = dealOrderSubmitAtv(storeBase.getOrderSubmitAmount(), storeBase.getOrderSubmitMemberNum());
        this.orderSubmitAtv = submitAtv;
        this.orderPayAmount = storeBase.getOrderPayAmount();
        this.orderPayNum = storeBase.getOrderPayNum();
        this.orderPayMemberNum = storeBase.getOrderPayMemberNum();
        BigDecimal payAtv = dealOrderPayAtv(storeBase.getOrderPayAmount(), storeBase.getOrderPayMemberNum());
        this.orderPayAtv = payAtv;
        this.pvSubmitRate = dealPvSubmitRate(storeBase.getOrderSubmitMemberNum(), storeBase.getVisitorNum());
        this.pvPayRate = dealPvPayRate(storeBase.getOrderPayMemberNum(), storeBase.getVisitorNum());
        this.submitPayRate = dealSubmitPayRate(storeBase.getOrderPayMemberNum(), storeBase.getOrderSubmitMemberNum());
        if (previousData != null) {
            this.previousViewNum = dealPreviousViewNum(storeBase.getViewNum(), previousData.getViewNum());
            this.previousVisitorNum = dealPreviousVisitorNum(storeBase.getVisitorNum(), previousData.getVisitorNum());
            this.previousOrderSubmitAmount = dealPreviousOrderSubmitAmount(storeBase.getOrderSubmitAmount(), previousData.getOrderSubmitAmount());
            this.previousOrderSubmitNum = dealPreviousOrderSubmitNum(storeBase.getOrderSubmitNum(), previousData.getOrderSubmitNum());
            this.previousOrderSubmitMemberNum = dealPreviousOrderSubmitMemberNum(storeBase.getOrderSubmitMemberNum(), previousData.getOrderSubmitMemberNum());
            BigDecimal preSubmitAtv = dealOrderSubmitAtv(previousData.getOrderSubmitAmount(), previousData.getOrderSubmitMemberNum());
            this.previousOrderSubmitAtv = dealPreviousOrderSubmitAtv(submitAtv, preSubmitAtv);
            this.previousOrderPayAmount = dealPreviousOrderPayAmount(storeBase.getOrderPayAmount(), previousData.getOrderPayAmount());
            this.previousOrderPayNum = dealPreviousOrderPayNum(storeBase.getOrderPayNum(), previousData.getOrderPayNum());
            this.previousOrderPayMemberNum = dealPreviousOrderPayMemberNum(storeBase.getOrderPayMemberNum(), previousData.getOrderPayMemberNum());
            BigDecimal prePayAtv = dealOrderPayAtv(previousData.getOrderPayAmount(), previousData.getOrderPayMemberNum());
            this.previousOrderPayAtv = dealPreviousOrderPayAtv(payAtv, prePayAtv);
        }
    }

    public static BigDecimal dealOrderSubmitAtv(BigDecimal orderSubmitAmount, Integer orderSubmitMemberNum) {
        if (orderSubmitMemberNum == 0) return BigDecimal.ZERO;
        return orderSubmitAmount.divide(new BigDecimal(orderSubmitMemberNum), 2, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal dealOrderPayAtv(BigDecimal orderPayAmount, Integer orderPayMemberNum) {
        if (orderPayMemberNum == 0) return BigDecimal.ZERO;
        return orderPayAmount.divide(new BigDecimal(orderPayMemberNum), 2, BigDecimal.ROUND_HALF_UP);
    }

    public static String dealPreviousViewNum(Integer viewNum, Integer previousViewNum) {
        if (previousViewNum == 0) return "0.00%";
        return new BigDecimal(viewNum).multiply(new BigDecimal(100))
                .divide(new BigDecimal(previousViewNum), 2, BigDecimal.ROUND_HALF_UP) + "%";
    }

    public static String dealPreviousVisitorNum(Integer visitorNum, Integer previousVisitorNum) {
        if (previousVisitorNum == 0) return "0.00%";
        return new BigDecimal(visitorNum).multiply(new BigDecimal(100))
                .divide(new BigDecimal(previousVisitorNum), 2, BigDecimal.ROUND_HALF_UP) + "%";
    }

    public static String dealPreviousOrderSubmitAmount(BigDecimal orderSubmitAmount, BigDecimal previousOrderSubmitAmount) {
        if (previousOrderSubmitAmount.compareTo(BigDecimal.ZERO) == 0) return "0.00%";
        return (orderSubmitAmount.subtract(previousOrderSubmitAmount)).multiply(new BigDecimal(100))
                .divide(previousOrderSubmitAmount, 2, RoundingMode.HALF_UP) + "%";
    }

    public static String dealPreviousOrderSubmitNum(Integer orderSubmitNum, Integer previousOrderSubmitNum) {
        if (previousOrderSubmitNum == 0) return "0.00%";
        return (new BigDecimal(orderSubmitNum).subtract(new BigDecimal(previousOrderSubmitNum))).multiply(new BigDecimal(100))
                .divide(new BigDecimal(previousOrderSubmitNum), 2, BigDecimal.ROUND_HALF_UP) + "%";
    }

    public static String dealPreviousOrderSubmitMemberNum(Integer orderSubmitMemberNum, Integer previousOrderSubmitMemberNum) {
        if (previousOrderSubmitMemberNum == 0) return "0.00%";
        return (new BigDecimal(orderSubmitMemberNum).subtract(new BigDecimal(previousOrderSubmitMemberNum))).multiply(new BigDecimal(100))
                .divide(new BigDecimal(previousOrderSubmitMemberNum), 2, BigDecimal.ROUND_HALF_UP) + "%";
    }

    public static String dealPreviousOrderSubmitAtv(BigDecimal orderSubmitAtv, BigDecimal previousOrderSubmitAtv) {
        if (previousOrderSubmitAtv.compareTo(BigDecimal.ZERO) == 0) return "0.00%";
        return (orderSubmitAtv.subtract(previousOrderSubmitAtv)).multiply(new BigDecimal(100))
                .divide(previousOrderSubmitAtv, 2, RoundingMode.HALF_UP) + "%";
    }

    public static String dealPreviousOrderPayAmount(BigDecimal orderPayAmount, BigDecimal previousOrderPayAmount) {
        if (previousOrderPayAmount.compareTo(BigDecimal.ZERO) == 0) return "0.00%";
        return (orderPayAmount.subtract(previousOrderPayAmount)).multiply(new BigDecimal(100))
                .divide(previousOrderPayAmount, 2, RoundingMode.HALF_UP) + "%";
    }

    public static String dealPreviousOrderPayNum(Integer orderPayNum, Integer previousOrderPayNum) {
        if (previousOrderPayNum == 0) return "0.00%";
        return (new BigDecimal(orderPayNum).subtract(new BigDecimal(previousOrderPayNum))).multiply(new BigDecimal(100))
                .divide(new BigDecimal(previousOrderPayNum), 2, BigDecimal.ROUND_HALF_UP) + "%";
    }

    public static String dealPreviousOrderPayMemberNum(Integer orderPayMemberNum, Integer previousOrderPayMemberNum) {
        if (previousOrderPayMemberNum == 0) return "0.00%";
        return (new BigDecimal(orderPayMemberNum).subtract(new BigDecimal(previousOrderPayMemberNum))).multiply(new BigDecimal(100))
                .divide(new BigDecimal(previousOrderPayMemberNum), 2, BigDecimal.ROUND_HALF_UP) + "%";
    }

    public static String dealPreviousOrderPayAtv(BigDecimal orderPayAtv, BigDecimal previousOrderPayAtv) {
        if (previousOrderPayAtv.compareTo(BigDecimal.ZERO) == 0) return "0.00%";
        return (orderPayAtv.subtract(previousOrderPayAtv)).multiply(new BigDecimal(100))
                .divide(previousOrderPayAtv, 2, RoundingMode.HALF_UP) + "%";
    }

}
