package com.red.circle.console.app.service.app.sys;

import com.red.circle.console.app.convertor.sys.FeedbackAppConvertor;
import com.red.circle.console.app.dto.clienobject.sys.SysFeedbackCO;
import com.red.circle.console.infra.database.rds.entity.admin.User;
import com.red.circle.console.infra.database.rds.service.admin.UserService;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.inner.endpoint.sys.SysFeedbackClient;
import com.red.circle.other.inner.model.cmd.sys.BatchProcessFeedbackCmd;
import com.red.circle.other.inner.model.cmd.sys.SysFeedbackQryCmd;
import com.red.circle.other.inner.model.dto.sys.SysFeedbackDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 意见反馈 服务实现类.
 * </p>
 *
 * @author pengliang
 * @since 2019-11-08
 */
@Service
@RequiredArgsConstructor
public class SysFeedbackServiceImpl implements SysFeedbackService {

  private final UserService userService;
  private final UserProfileClient userProfileClient;
  private final SysFeedbackClient sysFeedbackClient;
  private final FeedbackAppConvertor feedbackAppConvertor;

  @Override
  public PageResult<SysFeedbackCO> pageSysFeedbackVO(SysFeedbackQryCmd query) {

    PageResult<SysFeedbackDTO> sysFeedbackPage = ResponseAssert.requiredSuccess(
        sysFeedbackClient.pageSysFeedbackVO(query));

    Map<Long, UserProfileDTO> userProfileMap = getUserMap(sysFeedbackPage);

    Map<Long, User> userMap = userService.mapBackUser(
        sysFeedbackPage.getRecords().stream().map(SysFeedbackDTO::getUpdateUser)
            .filter(Objects::nonNull).collect(Collectors.toSet()));

    return sysFeedbackPage.convert(sysFeedback -> feedbackAppConvertor.toSysFeedbackCO(sysFeedback)
        .setUserProfile(userProfileMap.get(sysFeedback.getUserId()))
        .setUpdateNickname(Optional.ofNullable(userMap.get(sysFeedback.getUpdateUser()))
            .map(User::getNickname)
            .orElse(null))
    );
  }

  private Map<Long, UserProfileDTO> getUserMap(PageResult<SysFeedbackDTO> sysFeedbackPage) {
    return ResponseAssert.requiredSuccess(
        userProfileClient.mapByUserIds(getUserIds(sysFeedbackPage)));
  }

  private Set<Long> getUserIds(PageResult<SysFeedbackDTO> sysFeedbackPage) {
    return sysFeedbackPage.getRecords().stream()
        .map(sysFeedback -> {
          if (Objects.equals(sysFeedback.getUserId(), 0L)) {
            return null;
          }
          return sysFeedback.getUserId();
        })
        .filter(Objects::nonNull)
        .collect(Collectors.toSet());
  }


  @Override
  public void updateApprovalStatus(Long updateUserId, Long id, Integer status) {
    ResponseAssert.requiredSuccess(
        sysFeedbackClient.updateApprovalStatus(updateUserId, id, status));
  }

  @Override
  public void updateApprovalRemarks(Long userId, Long id, String remarks) {
    ResponseAssert.requiredSuccess(sysFeedbackClient.updateApprovalRemarks(userId, id, remarks));
  }

  @Override
  public void updateRemarksAndNotice(Long updateUserId, Long userId, Long id, String remarks) {
    ResponseAssert.requiredSuccess(
        sysFeedbackClient.updateRemarksAndNotice(updateUserId, userId, id, remarks));
  }

  @Override
  public void batchUpdateRemarksAndNotice(BatchProcessFeedbackCmd cmd) {
    ResponseAssert.requiredSuccess(sysFeedbackClient.batchUpdateRemarksAndNotice(cmd));
  }
}
