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.external.inner.endpoint.message.NewsletterClient;
import com.red.circle.external.inner.model.cmd.message.NewsletterResultCmd;
import com.red.circle.external.inner.model.enums.message.NewsletterEvent;
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.service.MessageSenderService;
import com.red.circle.mq.rocket.business.streams.ConsoleApprovalSink;
import com.red.circle.other.app.inner.convertor.approval.ApprovalDynamicReportConvertor;
import com.red.circle.other.app.inner.convertor.dynamic.DynamicInnerConvertor;
import com.red.circle.other.app.inner.service.approval.ApprovalDynamicReportClientService;
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.DynamicPicture;
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicReport;
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicContentService;
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicMessageService;
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicPictureService;
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicReportService;
import com.red.circle.other.inner.model.cmd.approval.ApprovalDynamicReportCmd;
import com.red.circle.other.inner.model.cmd.approval.ApprovalDynamicReportQryCmd;
import com.red.circle.other.inner.model.dto.approval.ApprovalDynamicReportedDTO;
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/20
 */
@Service
@RequiredArgsConstructor
public class ApprovalDynamicReportClientServiceImpl implements ApprovalDynamicReportClientService {

  private final MessageSenderService senderService;
  private final NewsletterClient newsletterClient;
  private final DynamicReportService dynamicReportService;
  private final DynamicPopularService dynamicPopularService;
  private final DynamicMessageService dynamicMessageService;
  private final DynamicContentService dynamicContentService;
  private final DynamicPictureService dynamicPictureService;
  private final DynamicInnerConvertor dynamicInnerConvertor;
  private final ApprovalDynamicReportConvertor approvalDynamicReportConvertor;

  @Override
  public PageResult<ApprovalDynamicReportedDTO> pageData(ApprovalDynamicReportQryCmd query) {
    PageResult<DynamicReport> pageResult = dynamicReportService.pageData(query);

    if (CollectionUtils.isEmpty(pageResult.getRecords())) {
      return pageResult.convert(approvalDynamicReportConvertor::toApprovalDynamicReportedDTO);
    }

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

    var result = pageResult.convert(dynamicReport -> {

      DynamicContent content = contentMap.get(dynamicReport.getDynamicContentId());
      if (Objects.isNull(content)) {
        return null;
      }
      List<DynamicPicture> pictures = pictureMap.get(content.getId());
      ApprovalDynamicReportedDTO approvalDynamicReportedDTO = approvalDynamicReportConvertor.toApprovalDynamicReportedDTO(
          dynamicReport);

      approvalDynamicReportedDTO.setDynamicContent(content.getContent());

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

      return approvalDynamicReportedDTO;
    });
    result.setRecords(result.getRecords().stream().filter(Objects::nonNull).collect(
        Collectors.toList()));
    return result;
  }

  @Override
  public void report(ApprovalDynamicReportCmd cmd) {
    ResponseAssert.isFalse(CommonErrorCode.UPDATE_FAILURE, cmd.getApprovalStatus() == 0);

    for (Long contentId : cmd.getContentIds()) {

      DynamicContent content = dynamicContentService.getById(contentId);
      if (Objects.isNull(content)) {
        continue;
      }

      List<DynamicReport> complaints = dynamicReportService.getByContentId(contentId);
      if (CollectionUtils.isEmpty(complaints)) {
        continue;
      }

      updateDynamicReport(cmd, complaints);

      if (content.getDel()) {
        //如果是已被删除的动态则修改下状态，不做发消息等处理。
        continue;
      }

      //举报成功
      if (Objects.equals(cmd.getApprovalStatus(), 1)) {

        dynamicPopularService.removeByDynamicId(content.getId());

        dynamicContentService.deleteById(content.getId());

        dynamicMessageService.save(content.getContent(), content.getId(), content.getCreateUser(),
            DynamicMessageEnum.DYNAMIC_VIOLATION);

        //发送消息给被举报人
//        newsletterClient.send(
//            new NewsletterResultCmd()
//                .setUserIds(List.of(content.getCreateUser()))
//                .setEvent(NewsletterEvent.DYNAMIC_MESSAGE_QUANTITY)
//                .setData(1));

        //发送消息给举报人
        sendMq(cmd.getApprovalUserId(), content, complaints, DynamicMessageEnum.REPORT_SUCCESS,
            ApprovalStatusEnum.PASS);
        return;
      }

      //举报驳回
      sendMq(cmd.getApprovalUserId(), content, complaints, DynamicMessageEnum.REPORT_FAIL,
          ApprovalStatusEnum.NOT_PASS);
    }
  }

  private void updateDynamicReport(ApprovalDynamicReportCmd cmd, List<DynamicReport> complaints) {
    dynamicReportService.updateDynamicReport(cmd, complaints);
  }

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

  private void sendMq(Long approvalUserId, DynamicContent content, List<DynamicReport> complaints,
      DynamicMessageEnum type, ApprovalStatusEnum status) {

    senderService.sendEventMessage(MessageEvent.builder()
        .consumeId(IdWorkerUtils.getIdStr())
        .tag(ConsoleApprovalSink.TAG)
        .body(new ApprovalDynamicEvent()
            .setApprovalType(DataApprovalTypeEnum.DYNAMIC_REPORT)
            .setOriginType(Boolean.FALSE)
            .setApprovalId(IdWorkerUtils.getId())
            .setApprovalUserId(approvalUserId)
            .setApprovalStatus(status)
            .setWaitApprovalUser(
                complaints.parallelStream().map(complaint -> new ApprovalContentEvent()
                    .setContent(content.getContent())
                    .setContentId(content.getId())
                    .setUserId(complaint.getCreateUser())
                    .setTags(type.name())).filter(Objects::nonNull).collect(Collectors.toList())))
        .build());
  }
}
