package com.red.circle.wallet.inner.service.freight.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.wallet.infra.database.rds.entity.freight.FreightBalanceRunningWater;
import com.red.circle.wallet.infra.database.rds.service.freight.FreightBalanceRunningWaterService;
import com.red.circle.wallet.inner.convertor.FreightBalanceRunningWaterInnerConvertor;
import com.red.circle.wallet.inner.model.dto.FreightBalanceRunningWaterDTO;
import com.red.circle.wallet.inner.service.freight.FreightBalanceRunningWaterClientService;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Service;

/**
 * 用户货运账户流水.
 *
 * @author pengliang on 2023/12/26
 */
@Service
@RequiredArgsConstructor
public class FreightBalanceRunningWaterClientServiceImpl implements
    FreightBalanceRunningWaterClientService {

  private final FreightBalanceRunningWaterService freightBalanceRunningWaterService;
  private final FreightBalanceRunningWaterInnerConvertor freightBalanceRunningWaterInnerConvertor;
  private final UserProfileClient userProfileClient;

  @Override
  public List<FreightBalanceRunningWaterDTO> flowByUserId(Long userId, Long searchId, Integer type, Long lastId) {
    Long acceptUserId = getByUserId(searchId);

    List<FreightBalanceRunningWater> runningWaters = freightBalanceRunningWaterService.flowByUserId(userId, acceptUserId, type, lastId);
    List<FreightBalanceRunningWaterDTO> runningWaterDTO = freightBalanceRunningWaterInnerConvertor.toListFreightBalanceRunningWaterDTO(runningWaters);

    Set<Long> acceptUserIdList = runningWaterDTO.stream().map(FreightBalanceRunningWaterDTO::getAcceptUserId).collect(Collectors.toSet());
    Set<Long> userIdList = runningWaterDTO.stream().map(FreightBalanceRunningWaterDTO::getUserId).collect(Collectors.toSet());
    acceptUserIdList.addAll(userIdList);

    Map<Long, UserProfileDTO> userProfileDTOMap = userProfileClient.mapByUserIds(acceptUserIdList).getBody();

    runningWaterDTO.forEach(dto -> {
      UserProfileDTO profileDTO = userProfileDTOMap.get(dto.getAcceptUserId());
      FreightBalanceRunningWaterDTO.AccountItem accountItem = getAcceptUserAccount(profileDTO);
      dto.setAcceptUserAccount(accountItem);

      UserProfileDTO userProfileDTO = userProfileDTOMap.get(dto.getUserId());
      FreightBalanceRunningWaterDTO.AccountItem userAccount = getAcceptUserAccount(userProfileDTO);
      dto.setUserAccount(userAccount);
    });
    return runningWaterDTO;
  }

  private static FreightBalanceRunningWaterDTO.AccountItem getAcceptUserAccount(UserProfileDTO profileDTO) {
    FreightBalanceRunningWaterDTO.AccountItem accountItem = null;
    if (profileDTO != null) {
        accountItem = new FreightBalanceRunningWaterDTO.AccountItem();
        accountItem.setAccount(profileDTO.getAccount());
        accountItem.setUserAvatar(profileDTO.getUserAvatar());
        accountItem.setUserNickName(profileDTO.getUserNickname());
    }
    return accountItem;
  }

    private Long getByUserId(Long searchId) {
      if (searchId == null || searchId <= 0) {
          return null;
      }

        List<UserProfileDTO> body = userProfileClient.getByAccount(String.valueOf(searchId)).getBody();
        if (body != null) {
            return body.get(0).getId();
        }
        return userProfileClient.getByUserId(searchId).getBody().getId();
    }

    public  List<FreightBalanceRunningWaterDTO> listByIds(Set<Long> ids) {
      if (ids.isEmpty()) {
          return Collections.emptyList();
      }

      LambdaQueryWrapper<FreightBalanceRunningWater> in = Wrappers.lambdaQuery(FreightBalanceRunningWater.class)
              .in(FreightBalanceRunningWater::getId, ids);
      List<FreightBalanceRunningWater> runningWaters = freightBalanceRunningWaterService.list(in);
      return freightBalanceRunningWaterInnerConvertor.toListFreightBalanceRunningWaterDTO(runningWaters);
  }

  @Override
  public List<FreightBalanceRunningWaterDTO> flowBySellerId(Long sellerId, Long lastId) {
    return freightBalanceRunningWaterInnerConvertor.toListFreightBalanceRunningWaterDTO(
        freightBalanceRunningWaterService.flowBySellerId(sellerId, lastId)
    );
  }

  @Override
  public List<FreightBalanceRunningWaterDTO> flowByUserIdAndDate(Long userId, Long lastId,
      String currentDate) {
    return freightBalanceRunningWaterInnerConvertor.toListFreightBalanceRunningWaterDTO(
        freightBalanceRunningWaterService.flowByUserIdAndDate(userId, lastId, currentDate)
    );
  }

  @Override
  public void save(FreightBalanceRunningWaterDTO dto) {
    freightBalanceRunningWaterService.save(
        freightBalanceRunningWaterInnerConvertor.toFreightBalanceRunningWater(dto)
    );
  }
}
