package com.red.circle.other.infra.database.mongo.entity.game.redpacket;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.red.circle.other.inner.enums.game.RedPacketScopeEnum;
import com.red.circle.tool.core.date.LocalDateTimeUtils;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

/**
 * <p>
 * 红包发送记录.
 * </p>
 *
 * @author pengliang on 2022/7/8
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Document("game_red_packet")
public class GameRedPacket implements Serializable {

  private static final long serialVersionUID = 1L;

  /**
   * 主键标识.
   */
  @Id
  @JsonSerialize(using = ToStringSerializer.class)
  private Long id;

  /**
   * 系统平台.
   */
  private String sysOrigin;

  /**
   * 房间id.
   */
  @JsonSerialize(using = ToStringSerializer.class)
  private Long roomId;

  /**
   * 红包类型:USER / ROOM
   */
  private String type;

  /**
   * 关联id.
   */
  @JsonSerialize(using = ToStringSerializer.class)
  private Long relationId;

  /**
   * 用户id.
   */
  @JsonSerialize(using = ToStringSerializer.class)
  private Long userId;

  /**
   * 发送金额.
   */
  private BigDecimal amount;

  /**
   * 发送数量.
   */
  private Integer quantity;

  /**
   * 状态.
   */
  private GameRedPacketStatus status;

  /**
   * 领取用户.
   */
  private List<GameRedPacketReceiveUsers> receiveUsers;

  /**
   * 领取人用户id(type是USER时,领取人字段才需要传值).
   */
  private Long receiverId;

  /**
   * 处理日志.
   */
  private List<GameRedPacketProcessLog> logs;

  /**
   * 过期时间.
   */
  private Timestamp expiredTime;

  /**
   * 创建时间.
   */
  private Timestamp createTime;

  /**
   * 修改时间.
   */
  private Timestamp updateTime;

  /**
   * 红包范围类型
   */
  private RedPacketScopeEnum redPacketScopeEnum;

  /**
   * 红包所属国家编码(红包范围类型为国家时才有值)
   */
  private String countryCode;

  /**
   * 是否可用状态.
   */
  public boolean checkStatusEqAvailable() {
    return Objects.equals(getStatus(), GameRedPacketStatus.AVAILABLE);
  }

  /**
   * true 过期, false 没过期.
   */
  public boolean checkExpired() {

    if (Objects.equals(type, "USER")) {
      return LocalDateTime.now()
          .isAfter(LocalDateTimeUtils.convert(createTime.getTime()).plusDays(1));
    }
    return LocalDateTime.now()
        .isAfter(LocalDateTimeUtils.convert(createTime.getTime()).plusMinutes(30));
  }

  /**
   * 非可用红包.
   */
  public boolean checkStatusEqNotAvailable() {
    return !Objects.equals(getStatus(), GameRedPacketStatus.AVAILABLE);
  }

  /**
   * 已抢完.
   */
  public boolean checkStatusEqNotReceive() {
    return Objects.equals(getStatus(), GameRedPacketStatus.NOT_RECEIVE);
  }

  /**
   * 领取金额.
   */
  public BigDecimal sumReceiveAmount() {
    return Optional.ofNullable(receiveUsers)
        .map(receiveUsers -> receiveUsers.stream().map(GameRedPacketReceiveUsers::getAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add)
            .setScale(0, RoundingMode.DOWN))
        .orElse(BigDecimal.ZERO);
  }

  public enum GameRedPacketStatus {

    /**
     * 可用状态.
     */
    AVAILABLE,

    /**
     * 都被抢完状态.
     */
    NOT_RECEIVE,

    /**
     * 退款状态: 已处理退款.
     */
    REIMBURSE,

    /**
     * 没有可退款金额.
     */
    NOT_REIMBURSE

  }

}
