package com.red.circle.other.app.inner.service.approval.impl;

import com.red.circle.common.business.core.enums.ApprovalStatusEnum;
import com.red.circle.common.business.core.enums.DataApprovalTypeEnum;
import com.red.circle.common.business.enums.DynamicMessageEnum;
import com.red.circle.component.mq.MessageEvent;
import com.red.circle.component.mq.service.SenderService;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.mq.business.model.event.approval.ApprovalContentEvent;
import com.red.circle.mq.business.model.event.approval.ApprovalDynamicEvent;
import com.red.circle.mq.rocket.business.streams.ConsoleApprovalSink;
import com.red.circle.other.app.inner.convertor.approval.ApprovalDynamicConvertor;
import com.red.circle.other.app.inner.convertor.dynamic.DynamicInnerConvertor;
import com.red.circle.other.app.inner.service.approval.ApprovalDynamicClientService;
import com.red.circle.other.infra.database.rds.entity.approval.ApprovalDynamicContent;
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicContent;
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicPicture;
import com.red.circle.other.infra.database.rds.service.approval.ApprovalDynamicContentService;
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicContentService;
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicPictureService;
import com.red.circle.other.inner.model.cmd.approval.ApprovalDynamicCmd;
import com.red.circle.other.inner.model.cmd.approval.ApprovalDynamicContentCmd;
import com.red.circle.other.inner.model.cmd.approval.ApprovalDynamicQryCmd;
import com.red.circle.other.inner.model.dto.approval.ApprovalDynamicDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 审批动态
 *
 * @author zongpubin on 2024/1/19
 */
@Service
@RequiredArgsConstructor
public class ApprovalDynamicClientServiceImpl implements ApprovalDynamicClientService {

  private final SenderService senderService;
  private final DynamicContentService dynamicContentService;
  private final DynamicPictureService dynamicPictureService;
  private final DynamicInnerConvertor dynamicInnerConvertor;
  private final ApprovalDynamicConvertor approvalDynamicConvertor;
  private final ApprovalDynamicContentService approvalDynamicContentService;

  @Override
  public PageResult<ApprovalDynamicDTO> pageApprovalDynamic(ApprovalDynamicQryCmd query) {
    PageResult<ApprovalDynamicContent> pageResult = approvalDynamicContentService.pageApprovalDynamic(
        query);
    if (CollectionUtils.isEmpty(pageResult.getRecords())) {
      return pageResult.convert(approvalDynamicConvertor::toApprovalDynamicDTO);
    }

    Set<Long> dynamicIds = getDynamicIds(pageResult);
    Map<Long, DynamicContent> contentMap = dynamicContentService.mapByIds(dynamicIds);
    Map<Long, List<DynamicPicture>> pictureMap = dynamicPictureService.mapByDynamicIds(dynamicIds);

    return pageResult.convert(approvalDynamicContent -> {
      DynamicContent content = contentMap.get(approvalDynamicContent.getDynamicId());
      List<DynamicPicture> pictures = pictureMap.get(approvalDynamicContent.getDynamicId());
      ApprovalDynamicDTO approvalDynamicDTO = approvalDynamicConvertor.toApprovalDynamicDTO(
          approvalDynamicContent);

      if (Objects.nonNull(content)) {
        approvalDynamicDTO.setDynamicContent(content.getContent());
      }

      if (CollectionUtils.isNotEmpty(pictures)) {
        approvalDynamicDTO.setPictures(
            pictures.stream().map(dynamicInnerConvertor::toDynamicPictureDTO)
                .collect(Collectors.toList()));
      }

      return approvalDynamicDTO;
    });
  }

  @Override
  public void approvalPass(Set<Long> ids) {
    ResponseAssert.notEmpty(CommonErrorCode.NOT_FOUND_RECORD_INFO, ids);
    approvalDynamicContentService.approvalPass(ids);

  }

  @Override
  public void approvalNotPass(ApprovalDynamicCmd approvalDynamicCmd) {
    ResponseAssert.notEmpty(CommonErrorCode.NOT_FOUND_RECORD_INFO, approvalDynamicCmd.getIds());
    approvalDynamicContentService.approvalNotPass(approvalDynamicCmd.getIds());

    senderService.sendEventMessage(MessageEvent.builder()
        .consumeId(IdWorkerUtils.getIdStr())
        .tag(ConsoleApprovalSink.TAG)
        .body(new ApprovalDynamicEvent()
            .setApprovalType(DataApprovalTypeEnum.DYNAMIC_CONTENT)
            .setOriginType(Boolean.FALSE)
            .setApprovalId(IdWorkerUtils.getId())
            .setApprovalUserId(approvalDynamicCmd.getUserId())
            .setApprovalStatus(ApprovalStatusEnum.NOT_PASS)
            .setWaitApprovalUser(
                approvalDynamicCmd.getIds().parallelStream().map(id -> new ApprovalContentEvent()
                        .setContentId(id)
                        .setTags(DynamicMessageEnum.DYNAMIC_VIOLATION.name()))
                    .filter(Objects::nonNull).collect(Collectors.toList()))).build());
  }

  private Set<Long> getDynamicIds(PageResult<ApprovalDynamicContent> pageResult) {
    return pageResult.getRecords().stream().map(ApprovalDynamicContent::getDynamicId)
        .collect(Collectors.toSet());
  }

  @Override
  public void save(ApprovalDynamicContentCmd cmd) {
    ApprovalDynamicContent approvalDynamicContent = approvalDynamicConvertor.toApprovalDynamicContent(cmd);
    if (Objects.nonNull(approvalDynamicContent)) {
      approvalDynamicContentService.save(approvalDynamicContent);
    }
  }
}
