package com.red.circle.other.app.command.dynamic;

import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.app.common.room.DynamicCommon;
import com.red.circle.other.app.dto.cmd.dynamic.DynamicLikeCmd;
import com.red.circle.other.infra.database.cache.service.other.DynamicCacheService;
import com.red.circle.other.infra.database.mongo.service.dynamic.DynamicPopularService;
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicContent;
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicLike;
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicContentService;
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicLikeService;
import com.red.circle.other.inner.asserts.DynamicErrorCode;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.num.NumUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * <p>
 * 动态-点赞.
 * </p>
 *
 * @author pengshigang
 * @since 2022-04-14
 */
@Component
@RequiredArgsConstructor
public class DynamicLikeCmdExe {

  private final DynamicCommon dynamicCommon;
  private final DynamicLikeService dynamicLikeService;
  private final DynamicCacheService dynamicCacheService;
  private final DynamicContentService dynamicContentService;
  private final DynamicPopularService dynamicPopularService;

  public String execute(DynamicLikeCmd cmd) {

    DynamicContent content = checkParams(cmd);

    Long commentId = IdWorkerUtils.getId();
    //点赞动态
    if (Boolean.TRUE.equals(cmd.getLike())) {

      ResponseAssert.isFalse(DynamicErrorCode.LIKED, getExist(cmd));
      save(cmd, commentId);

      String quantity = getQuantity(cmd);

      if (Objects.equals(cmd.getReqUserId(), content.getCreateUser())) {
        return quantity;
      }

      dynamicPopularService.updateScore(content.getId(), dynamicCacheService.getLikeScore(),
          cmd.getReqSysOrigin().getOrigin(), content.getRegion());

      dynamicCommon.sendMsg(content.getCreateUser());
      return quantity;
    }

    ResponseAssert.isTrue(DynamicErrorCode.UNLIKED, getExist(cmd));

    dynamicLikeService.delete(cmd.getDynamicId(), cmd.getReqUserId());

    if (Objects.equals(cmd.getReqUserId(), content.getCreateUser())) {
      return NumUtils.formatLong(dynamicCacheService.decrLikeQuantity(cmd.getDynamicId()));
    }

    dynamicPopularService.updateScore(content.getId(),
        dynamicCacheService.getLikeScore() > 0 ? -dynamicCacheService.getLikeScore() : 0,
        cmd.getReqSysOrigin().getOrigin(), content.getRegion());

    return NumUtils.formatLong(dynamicCacheService.decrLikeQuantity(cmd.getDynamicId()));
  }

  private DynamicContent checkParams(DynamicLikeCmd cmd) {
    DynamicContent content = dynamicContentService.getById(cmd.getDynamicId());
    ResponseAssert.notNull(DynamicErrorCode.CONTENT_IS_NULL, content);
    ResponseAssert.isFalse(DynamicErrorCode.CONTENT_DELETE, content.getDel());
    return content;
  }

  private String getQuantity(DynamicLikeCmd cmd) {
    return NumUtils.formatLong(dynamicCacheService.incrLikeQuantity(cmd.getDynamicId()));
  }

  private void save(DynamicLikeCmd cmd, Long commentId) {
    DynamicLike dynamicLike = new DynamicLike();
    dynamicLike.setId(commentId);
    dynamicLike.setDynamicContentId(cmd.getDynamicId());
    dynamicLike.setCreateUser(cmd.getReqUserId());
    dynamicLike.setCreateTime(TimestampUtils.now());
    dynamicLikeService.save(dynamicLike);
  }

  private Boolean getExist(DynamicLikeCmd cmd) {
    return dynamicLikeService.exist(cmd.getDynamicId(), cmd.getReqUserId());
  }


}
