package com.red.circle.other.domain.model.user;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.red.circle.common.business.enums.AccountStatusEnum;
import com.red.circle.other.inner.model.dto.user.CpSimpleUserProfileCO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.other.inner.model.dto.user.props.UserUseBadgeDTO;
import com.red.circle.other.inner.model.dto.user.props.UserUsePropsDTO;
import java.io.Serial;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.Data;

import static com.red.circle.common.business.enums.AccountStatusEnum.ARCHIVE;
import static com.red.circle.common.business.enums.AccountStatusEnum.ARCHIVE_DEVICE;

/**
 * 用户模型.
 *
 * @author pengliang on 2021/5/26
 */
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserProfile implements Serializable {

  @Serial
  private static final long serialVersionUID = 1L;

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

  /**
   * 账号.
   */
  private String account;

  /**
   * 头像.
   */
  private String userAvatar;

  /**
   * 用户昵称.
   */
  private String userNickname;

  /**
   * 用户性别:0 女，1 男.
   */
  private Integer userSex;

  /**
   * 用户类型:0.真实用户 1.马甲用户.
   */
  private Integer userType;

  /**
   * 年龄.
   */
  private Integer age;

  /**
   * 账号状态.
   */
  private String accountStatus;

  /**
   * 冻结时间.
   */
  private Timestamp freezingTime;

  /**
   * 国家id.
   */
  private Long countryId;

  /**
   * 国家名称.
   */
  private String countryName;

  /**
   * 国家编码.
   */
  private String countryCode;

  /**
   * 系统来源.
   */
  private String originSys;

  /**
   * 子系统.
   */
  private String sysOriginChild;

  /**
   * 出身年.
   */
  private Integer bornYear;

  /**
   * 出身月.
   */
  private Integer bornMonth;

  /**
   * 出身日.
   */
  private Integer bornDay;

  /**
   * 背景照片列表（最多9张）
   */
  private List<com.red.circle.other.inner.model.dto.user.PhotoItem> backgroundPhotos;

  /**
   * 个人形象照片列表（最多9张）
   */
  private List<com.red.circle.other.inner.model.dto.user.PhotoItem> personalPhotos;

  /**
   * 0.未删除 1.已删除.
   */
  private Boolean del;

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

  /**
   * 个性签名.
   */
  private String autograph;

  /**
   * 爱好
   */
  private String hobby;


  /**
   * CP列表
   */
  private List<CpSimpleUserProfileCO> cpList;

  /**
   * 家族ID
   */
  @JsonSerialize(using = ToStringSerializer.class)
  private Long familyId;


  /**
   * 拥有的靓号.
   */
  private OwnSpecialId ownSpecialId;

  /**
   * 使用的道具.
   */
  private List<UserUsePropsDTO> useProps;

  /**
   * 用户使用的徽章.
   */
  private List<UserUseBadgeDTO> wearBadge;

    /**
     * 用户使用的荣誉.
     */
    private List<UserUseBadgeDTO> wearHonor;

  private String checkStatus;

    /**
     * 是否未完成首充
     */
    private Boolean firstRecharge;

    /**
     * 首充结束时间
     */
    private Timestamp firstRechargeEndTime;

  /**
   * 覆盖get，过滤已过期靓号.
   */
  public OwnSpecialId getOwnSpecialId() {
    return checkOwnSpecialIdAvailable() ? ownSpecialId : null;
  }

  /**
   * 检查靓号是否可用.
   */
  private boolean checkOwnSpecialIdAvailable() {
    boolean exists = Objects.nonNull(this.ownSpecialId)
        && Objects.nonNull(this.ownSpecialId.getAccount());

    if (!exists) {
      return false;
    }

    return Objects.isNull(this.ownSpecialId.getExpiredTime())
        || this.ownSpecialId.getExpiredTime().after(TimestampUtils.now());
  }

  /**
   * 获取实际的账号.
   */
  @JsonIgnore
  public String getActualAccount() {
    return checkOwnSpecialIdAvailable() ? this.ownSpecialId.getAccount() : this.account;
  }

  /**
   * 覆盖旧账号.
   */
  public void overlayOldAccount() {
    if (checkOwnSpecialIdAvailable()) {
      this.account = this.ownSpecialId.getAccount();
    }
  }

  /**
   * 获取展示账号.
   */
  public String showAccount() {
    return checkOwnSpecialIdAvailable() ? this.ownSpecialId.getAccount() : this.account;
  }

  /**
   * 过滤道具.
   */
  public List<UserUsePropsDTO> filterProps(Predicate<UserUsePropsDTO> predicate) {
    return Optional.ofNullable(useProps)
        .map(usePropsEntities -> usePropsEntities.stream()
            .filter(Objects::nonNull)
            .filter(predicate)
            .collect(Collectors.toList()))
        .orElse(CollectionUtils.newArrayList());
  }

  /**
   * 是否是普通用户.
   *
   * @return true 是，false 否
   */
  public boolean checkOrdinaryUser() {
    return Objects.equals(userType, 0);
  }

  /**
   * 是否是马甲用户.
   *
   * @return true 是，false 否
   */
  public boolean checkVestUser() {
    return Objects.equals(userType, 1);
  }

  /**
   * 账号是否正常.
   *
   * @return true 是， false 否
   */
  public boolean checkAccountAvailable() {
    return !checkAccountArchive() && !checkAccountFreeze();
  }

  /**
   * 账号是否为封禁状态.
   *
   * @return true 是， false 否
   */
  public boolean checkAccountArchive() {
    if (Objects.equals(ARCHIVE_DEVICE.name(), this.getAccountStatus())) {
      return true;
    }
    return Objects.equals(ARCHIVE.name(), this.getAccountStatus()) && checkAccountFreeze();
  }

  /**
   * 账号是否为冻结状态.
   *
   * @return true 是， false 否
   */
  public boolean checkAccountFreeze() {
    return AccountStatusEnum.isFreeze(this.getFreezingTime());
  }

}
