package com.red.circle.other.infra.database.rds.service.dynamic.impl;

import com.red.circle.common.business.enums.DynamicMessageEnum;
import com.red.circle.framework.dto.PageQuery;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.other.infra.database.rds.dao.dynamic.DynamicMessageDAO;
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicMessage;
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicMessageService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;

import java.util.*;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 动态-我的消息 服务实现类.
 * </p>
 *
 * @author pengshigang
 * @since 2022-04-11
 */
@Service
public class DynamicMessageServiceImpl extends
    BaseServiceImpl<DynamicMessageDAO, DynamicMessage> implements DynamicMessageService {

  @Override
  public void saveBatch(String content, Long contentId, Set<Long> toUserIds, String type) {

    if (CollectionUtils.isEmpty(toUserIds)) {
      return;
    }

    saveBatch(toUserIds.stream().map(toUserId -> {
      DynamicMessage dynamicMessage = new DynamicMessage();
      dynamicMessage.setContent(content);
      dynamicMessage.setDynamicContentId(contentId);
      dynamicMessage.setToUserId(toUserId);
      dynamicMessage.setType(type);
      dynamicMessage.setCreateTime(TimestampUtils.now());
      dynamicMessage.setId(IdWorkerUtils.getId());
      return dynamicMessage;
    }).collect(Collectors.toList()));

  }

  @Override
  public void save(String content, Long contentId, Long toUserId, DynamicMessageEnum type) {
    DynamicMessage dynamicMessage = new DynamicMessage();
    dynamicMessage.setContent(content);
    dynamicMessage.setDynamicContentId(contentId);
    dynamicMessage.setToUserId(toUserId);
    dynamicMessage.setType(type.name());
    dynamicMessage.setCreateTime(TimestampUtils.now());
    dynamicMessage.setId(IdWorkerUtils.getId());
    super.save(dynamicMessage);
  }

  @Override
  public Map<Long, List<DynamicMessage>> mapByUserIdsByContentId(Collection<Long> toUserIds) {

    if (CollectionUtils.isEmpty(toUserIds)) {
      return CollectionUtils.newHashMap();
    }
    return Optional.ofNullable(
            query()
                .in(DynamicMessage::getToUserId, toUserIds)
                .eq(DynamicMessage::getDel, Boolean.FALSE)
                .eq(DynamicMessage::getReading, Boolean.FALSE)
                .last(PageConstant.formatLimit(toUserIds.size()))
                .list()
        ).map(contents -> contents.stream()
            .collect(Collectors.groupingBy(DynamicMessage::getToUserId)))
        .orElseGet(CollectionUtils::newHashMap);
  }

  @Override
  public Integer getCountByToUserId(Long toUserId) {

    return Optional.ofNullable(query()
        .eq(DynamicMessage::getReading, Boolean.FALSE)
        .eq(DynamicMessage::getDel, Boolean.FALSE)
        .eq(DynamicMessage::getToUserId, toUserId)
        .count()).map(Long::intValue).orElse(0);
  }

  @Override
  public PageResult<DynamicMessage> pageByTimeDesc(PageQuery pageQuery, Long toUserId, List<DynamicMessageEnum> dynamicMessageEnums) {

    return query()
        .eq(DynamicMessage::getToUserId, toUserId)
        .eq(DynamicMessage::getDel, Boolean.FALSE)
        .in(dynamicMessageEnums != null, DynamicMessage::getType,
                dynamicMessageEnums != null ? dynamicMessageEnums.stream().map(Enum::name).toList() : Collections.emptyList())
        .orderByDesc(DynamicMessage::getCreateTime)
        .page(pageQuery);
  }

  @Override
  public Long countDynamicMessage(Long toUserId) {

    return query()
        .eq(DynamicMessage::getToUserId, toUserId)
        .eq(DynamicMessage::getDel, Boolean.FALSE)
        .eq(DynamicMessage::getReading, Boolean.FALSE)
        .count();
  }

  private String getPageSql(Integer pageNumber) {

    return String.format("LIMIT %s, %s", (pageNumber - 1) * PageConstant.DEFAULT_LIMIT_SIZE,
        PageConstant.DEFAULT_LIMIT_SIZE);
  }


}
