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

import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.other.inner.model.cmd.user.device.DeviceRegisterQuantityQryCmd;
import com.red.circle.other.inner.model.cmd.user.device.PageLatestMobileDeviceQryCmd;
import com.red.circle.other.inner.model.dto.user.UserLatestMobileDeviceHistoryDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.other.inner.model.dto.user.device.DeviceRegisterQuantityDTO;
import com.red.circle.other.inner.endpoint.user.device.RegisterDeviceClient;
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.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户最新设备信息 服务实现类
 * </p>
 *
 * @author pengliang
 * @since 2021-03-29
 */
@Service
@RequiredArgsConstructor
public class UserLatestMobileDeviceServiceImpl implements
    UserLatestMobileDeviceService {

  private final UserProfileClient userProfileClient;
  private final RegisterDeviceClient registerDeviceClient;

  @Override
  public PageResult<UserLatestMobileDeviceHistoryDTO> page(PageLatestMobileDeviceQryCmd query) {

    if (Objects.nonNull(query.getUserAccount())) {
      Long userId = Optional.ofNullable(ResponseAssert.requiredSuccess(
              userProfileClient.getByAccountOne(String.valueOf(query.getUserAccount()))))
          .map(UserProfileDTO::getId).
          orElse(query.getUserAccount());

      query.setUserId(Optional.ofNullable(query.getUserId())
          .map(userIdTemp -> Objects.equals(userId, userIdTemp) ? userId : 0).orElse(userId));
    }

    return assignmentPage(getResultPage(query), query.getSysOrigin());

  }

  private PageResult<UserLatestMobileDeviceHistoryDTO> assignmentPage(
      PageResult<UserLatestMobileDeviceHistoryDTO> resultPage, String sysOrigin) {

    if (CollectionUtils.isEmpty(resultPage.getRecords())) {
      return resultPage;
    }

    Map<Long, UserProfileDTO> userBaseInfoMap = ResponseAssert.requiredSuccess(
        userProfileClient.mapByUserIds(
            resultPage.getRecords().stream().map(UserLatestMobileDeviceHistoryDTO::getUserId)
                .collect(
                    Collectors.toSet())));

    DeviceRegisterQuantityQryCmd query = new DeviceRegisterQuantityQryCmd();
    query.setDeviceNos(resultPage.getRecords().stream().map(
        UserLatestMobileDeviceHistoryDTO::
            getImei).collect(Collectors.toSet()));
    query.setSysOrigin(sysOrigin);

    Map<String, DeviceRegisterQuantityDTO> registerQuantityMap = ResponseAssert.requiredSuccess(
        registerDeviceClient.mapDeviceRegisterQuantity(query));

    return resultPage.convert(userLatestMobileDeviceDTO -> {
          userLatestMobileDeviceDTO.setUserNickname(userBaseInfoMap.get(userLatestMobileDeviceDTO.
              getUserId()).getUserNickname());

          DeviceRegisterQuantityDTO registerQuantity = registerQuantityMap
              .get(userLatestMobileDeviceDTO.getImei());

          if (Objects.isNull(registerQuantity)) {
            return userLatestMobileDeviceDTO;
          }
          userLatestMobileDeviceDTO.setRegisterNumber(registerQuantity.getRegisterNumber());

          return userLatestMobileDeviceDTO;
        }
    );
  }

  private PageResult<UserLatestMobileDeviceHistoryDTO> getResultPage(
      PageLatestMobileDeviceQryCmd query) {
    return ResponseAssert.requiredSuccess(registerDeviceClient.pageLatestMobileDevice(query));
  }


}
