package com.bonus.canteen.core.order.common.model;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.annotation.TableName;
import com.bonus.common.houqin.constant.LeConstants;
import com.bonus.canteen.core.menu.constant.MenuSalesTypeEnum;
import com.bonus.canteen.core.order.common.constants.DetailStateEnum;
import com.bonus.canteen.core.order.common.constants.DetailTypeEnum;
import com.bonus.canteen.core.order.common.vo.OrderDetailWithImage;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;

@TableName("order_detail")
public class OrderDetail implements OrderDetailWithImage {
   private Long detailId;
   @DateTimeFormat(
      pattern = "yyyy-MM-dd"
   )
   @JsonFormat(
      pattern = "yyyy-MM-dd"
   )
   private LocalDate orderDate;
   private Long orderId;
   private String submitKey;
   private String machineSn;
   private Long goodsDishesId;
   private String goodsDishesName;
   private String goodsDishesImgUrl;
   private Long menuDetailId;
   private String macDetailId;
   private String macGoodsDishesId;
   private BigDecimal salePrice;
   private BigDecimal prefPrice;
   private BigDecimal price;
   private Integer weightUnit;
   private Integer quantity;
   private Integer totalWeight;
   private String unitName;
   private BigDecimal totalAmount;
   private BigDecimal calcTotalAmount;
   private BigDecimal realAmount;
   private BigDecimal refundAmount;
   private Integer salesMode;
   private Integer detailType;
   private String tasteName;
   private Integer detailState;
   private Integer goodsGetNum;
   private Integer goodsRefundNum;
   private String inventoryId;
   private JsonNode extParam;
   private String crby;
   @DateTimeFormat(
      pattern = "yyyy-MM-dd HH:mm:ss"
   )
   @JsonFormat(
      pattern = "yyyy-MM-dd HH:mm:ss"
   )
   private LocalDateTime crtime;
   private String upby;
   @DateTimeFormat(
      pattern = "yyyy-MM-dd HH:mm:ss"
   )
   @JsonFormat(
      pattern = "yyyy-MM-dd HH:mm:ss"
   )
   private LocalDateTime uptime;

   public boolean supportMergeDetail(OrderDetail additionalDetail) {
      return ObjectUtil.equal(this.goodsDishesId, additionalDetail.getGoodsDishesId()) && ObjectUtil.equal(this.goodsDishesName, additionalDetail.getGoodsDishesName()) && ObjectUtil.equal(this.menuDetailId, additionalDetail.getMenuDetailId()) && ObjectUtil.equal(this.price, additionalDetail.getPrice()) && ObjectUtil.equal(this.weightUnit, additionalDetail.getWeightUnit()) && ObjectUtil.equal(this.salesMode, additionalDetail.getSalesMode()) && ObjectUtil.equal(this.detailType, additionalDetail.getDetailType()) && ObjectUtil.equal(this.detailState, additionalDetail.getDetailState()) && ObjectUtil.equal(this.inventoryId, additionalDetail.getInventoryId());
   }

   public void mergeDetail(OrderDetail additionalDetail) {
      this.quantity = NumberUtil.add(this.quantity, additionalDetail.getQuantity()).intValue();
      this.totalWeight = NumberUtil.add(this.totalWeight, additionalDetail.getTotalWeight()).intValue();
      this.totalAmount = NumberUtil.add(this.totalAmount, additionalDetail.getTotalAmount());
      this.calcTotalAmount = NumberUtil.add(this.calcTotalAmount, additionalDetail.getCalcTotalAmount());
      this.realAmount = NumberUtil.add(this.realAmount, additionalDetail.getRealAmount());
      this.refundAmount = NumberUtil.add(this.refundAmount, additionalDetail.getRefundAmount());
      this.goodsGetNum = NumberUtil.add(this.goodsGetNum, additionalDetail.getGoodsGetNum()).intValue();
      this.goodsRefundNum = NumberUtil.add(this.goodsRefundNum, additionalDetail.getGoodsRefundNum()).intValue();
   }

   public void plusRefundAmount(BigDecimal additionalRefundAmount) {
      this.refundAmount = NumberUtil.add(this.refundAmount, additionalRefundAmount);
   }

   public void plusRefundQuantity(Integer refundQuantity) {
      this.goodsRefundNum = NumberUtil.add(this.goodsRefundNum, refundQuantity).intValue();
      if (this.goodsRefundNum > this.quantity) {
         this.goodsRefundNum = this.quantity;
      }

   }

   public Integer calcUnRefundGoodsNum() {
      return NumberUtil.sub(this.quantity, this.goodsRefundNum).intValue();
   }

   public BigDecimal calcUnRefundAmount() {
      return NumberUtil.sub(this.realAmount, this.refundAmount);
   }

   public OrderDetail copyInstance() {
      return (OrderDetail)BeanUtil.copyProperties(this, OrderDetail.class, new String[0]);
   }

   public static OrderDetail newDefaultDetail(BigDecimal price, Integer detailType) {
      OrderDetail orderDetail = new OrderDetail();
      orderDetail.setGoodsDishesId(LeConstants.DATA_DEFAULT_LONG);
      orderDetail.setGoodsDishesName(DetailTypeEnum.getDesc(detailType));
      orderDetail.setWeightUnit(100);
      orderDetail.setQuantity(1);
      orderDetail.setUnitName((String)null);
      orderDetail.setSalesMode(MenuSalesTypeEnum.PORTION_ON.key());
      orderDetail.setDetailType(detailType);
      orderDetail.setDetailState(DetailStateEnum.NORMAL.getKey());
      orderDetail.setGoodsGetNum(0);
      orderDetail.setGoodsRefundNum(0);
      orderDetail.setSalePrice(price);
      orderDetail.setPrefPrice(price);
      orderDetail.setPrice(price);
      orderDetail.setTotalAmount(price);
      orderDetail.setCalcTotalAmount(price);
      orderDetail.setRealAmount(price);
      orderDetail.setRefundAmount(BigDecimal.ZERO);
      return orderDetail;
   }

   public static String[] logFields() {
      return new String[]{"goodsDishesId", "goodsDishesName", "menuDetailId", "salePrice", "prefPrice", "price", "weightUnit", "quantity", "unitName", "totalAmount", "calcTotalAmount", "realAmount", "refundAmount", "salesMode", "detailType", "tasteName", "detailState", "goodsGetNum", "goodsRefundNum", "inventoryId"};
   }

   public static String[] logFieldsGoods() {
      return new String[]{"goodsDishesId", "goodsDishesName", "menuDetailId", "salePrice", "prefPrice", "price", "weightUnit", "quantity", "total_weight", "unitName", "salesMode", "detailType"};
   }

   public static String[] logFieldsAmount() {
      return new String[]{"goodsDishesId", "goodsDishesName", "menuDetailId", "salePrice", "prefPrice", "price", "totalAmount", "calcTotalAmount", "realAmount", "refundAmount"};
   }

   public static String[] logFieldsRefund() {
      return new String[]{"goodsDishesId", "goodsDishesName", "menuDetailId", "price", "totalAmount", "calcTotalAmount", "realAmount", "refundAmount", "detailState", "goodsGetNum", "goodsRefundNum", "quantity", "weightUnit"};
   }

   public Long getDetailId() {
      return this.detailId;
   }

   public LocalDate getOrderDate() {
      return this.orderDate;
   }

   public Long getOrderId() {
      return this.orderId;
   }

   public String getSubmitKey() {
      return this.submitKey;
   }

   public String getMachineSn() {
      return this.machineSn;
   }

   @Override
   public Long getGoodsDishesId() {
      return this.goodsDishesId;
   }

   public String getGoodsDishesName() {
      return this.goodsDishesName;
   }

   @Override
   public String getGoodsDishesImgUrl() {
      return this.goodsDishesImgUrl;
   }

   public Long getMenuDetailId() {
      return this.menuDetailId;
   }

   public String getMacDetailId() {
      return this.macDetailId;
   }

   public String getMacGoodsDishesId() {
      return this.macGoodsDishesId;
   }

   public BigDecimal getSalePrice() {
      return this.salePrice;
   }

   public BigDecimal getPrefPrice() {
      return this.prefPrice;
   }

   public BigDecimal getPrice() {
      return this.price;
   }

   public Integer getWeightUnit() {
      return this.weightUnit;
   }

   public Integer getQuantity() {
      return this.quantity;
   }

   public Integer getTotalWeight() {
      return this.totalWeight;
   }

   public String getUnitName() {
      return this.unitName;
   }

   public BigDecimal getTotalAmount() {
      return this.totalAmount;
   }

   public BigDecimal getCalcTotalAmount() {
      return this.calcTotalAmount;
   }

   public BigDecimal getRealAmount() {
      return this.realAmount;
   }

   public BigDecimal getRefundAmount() {
      return this.refundAmount;
   }

   public Integer getSalesMode() {
      return this.salesMode;
   }

   @Override
   public Integer getDetailType() {
      return this.detailType;
   }

   public String getTasteName() {
      return this.tasteName;
   }

   public Integer getDetailState() {
      return this.detailState;
   }

   public Integer getGoodsGetNum() {
      return this.goodsGetNum;
   }

   public Integer getGoodsRefundNum() {
      return this.goodsRefundNum;
   }

   public String getInventoryId() {
      return this.inventoryId;
   }

   public JsonNode getExtParam() {
      return this.extParam;
   }

   public String getCrby() {
      return this.crby;
   }

   public LocalDateTime getCrtime() {
      return this.crtime;
   }

   public String getUpby() {
      return this.upby;
   }

   public LocalDateTime getUptime() {
      return this.uptime;
   }

   public void setDetailId(final Long detailId) {
      this.detailId = detailId;
   }

   @JsonFormat(
      pattern = "yyyy-MM-dd"
   )
   public void setOrderDate(final LocalDate orderDate) {
      this.orderDate = orderDate;
   }

   public void setOrderId(final Long orderId) {
      this.orderId = orderId;
   }

   public void setSubmitKey(final String submitKey) {
      this.submitKey = submitKey;
   }

   public void setMachineSn(final String machineSn) {
      this.machineSn = machineSn;
   }

   public void setGoodsDishesId(final Long goodsDishesId) {
      this.goodsDishesId = goodsDishesId;
   }

   public void setGoodsDishesName(final String goodsDishesName) {
      this.goodsDishesName = goodsDishesName;
   }

   @Override
   public void setGoodsDishesImgUrl(final String goodsDishesImgUrl) {
      this.goodsDishesImgUrl = goodsDishesImgUrl;
   }

   public void setMenuDetailId(final Long menuDetailId) {
      this.menuDetailId = menuDetailId;
   }

   public void setMacDetailId(final String macDetailId) {
      this.macDetailId = macDetailId;
   }

   public void setMacGoodsDishesId(final String macGoodsDishesId) {
      this.macGoodsDishesId = macGoodsDishesId;
   }

   public void setSalePrice(final BigDecimal salePrice) {
      this.salePrice = salePrice;
   }

   public void setPrefPrice(final BigDecimal prefPrice) {
      this.prefPrice = prefPrice;
   }

   public void setPrice(final BigDecimal price) {
      this.price = price;
   }

   public void setWeightUnit(final Integer weightUnit) {
      this.weightUnit = weightUnit;
   }

   public void setQuantity(final Integer quantity) {
      this.quantity = quantity;
   }

   public void setTotalWeight(final Integer totalWeight) {
      this.totalWeight = totalWeight;
   }

   public void setUnitName(final String unitName) {
      this.unitName = unitName;
   }

   public void setTotalAmount(final BigDecimal totalAmount) {
      this.totalAmount = totalAmount;
   }

   public void setCalcTotalAmount(final BigDecimal calcTotalAmount) {
      this.calcTotalAmount = calcTotalAmount;
   }

   public void setRealAmount(final BigDecimal realAmount) {
      this.realAmount = realAmount;
   }

   public void setRefundAmount(final BigDecimal refundAmount) {
      this.refundAmount = refundAmount;
   }

   public void setSalesMode(final Integer salesMode) {
      this.salesMode = salesMode;
   }

   public void setDetailType(final Integer detailType) {
      this.detailType = detailType;
   }

   public void setTasteName(final String tasteName) {
      this.tasteName = tasteName;
   }

   public void setDetailState(final Integer detailState) {
      this.detailState = detailState;
   }

   public void setGoodsGetNum(final Integer goodsGetNum) {
      this.goodsGetNum = goodsGetNum;
   }

   public void setGoodsRefundNum(final Integer goodsRefundNum) {
      this.goodsRefundNum = goodsRefundNum;
   }

   public void setInventoryId(final String inventoryId) {
      this.inventoryId = inventoryId;
   }

   public void setExtParam(final JsonNode extParam) {
      this.extParam = extParam;
   }

   public void setCrby(final String crby) {
      this.crby = crby;
   }

   @JsonFormat(
      pattern = "yyyy-MM-dd HH:mm:ss"
   )
   public void setCrtime(final LocalDateTime crtime) {
      this.crtime = crtime;
   }

   public void setUpby(final String upby) {
      this.upby = upby;
   }

   @JsonFormat(
      pattern = "yyyy-MM-dd HH:mm:ss"
   )
   public void setUptime(final LocalDateTime uptime) {
      this.uptime = uptime;
   }

}
