package com.red.circle.wallet.infra.database.rds.service.impl;

import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.wallet.domain.wallet.WalletBizStatus;
import com.red.circle.wallet.domain.wallet.WalletBizType;
import com.red.circle.wallet.infra.database.rds.dao.WalletAssetRecordStatusDAO;
import com.red.circle.wallet.infra.database.rds.entity.WalletAssetRecordStatus;
import com.red.circle.wallet.infra.database.rds.service.WalletAssetRecordStatusService;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;

/**
 * 用户金币资产流水状态 服务实现.
 *
 * @author pengliang on 2023/7/3
 */
@Service
public class WalletAssetRecordStatusServiceImpl extends
    BaseServiceImpl<WalletAssetRecordStatusDAO, WalletAssetRecordStatus> implements
    WalletAssetRecordStatusService {

  @Override
  public boolean exists(String bizId, WalletBizType bizType) {
    return Optional.ofNullable(query()
            .select(WalletAssetRecordStatus::getId)
            .eq(WalletAssetRecordStatus::getBizId, bizId)
            .eq(WalletAssetRecordStatus::getBizType, bizType.getType())
            .last(PageConstant.LIMIT_ONE)
            .getOne())
        .map(record -> Objects.nonNull(record.getId()))
        .orElse(false);
  }

  @Override
  public boolean saveIfAbsent(String bizId, WalletBizType bizType, WalletBizStatus status) {
    if (exists(bizId, bizType, status.getStatus())) {
      return false;
    }

    save(new WalletAssetRecordStatus()
        .setBizId(bizId)
        .setBizType(bizType.getType())
        .setStatus(status.getStatus())
    );
    return true;
  }

  @Override
  public Map<Long, WalletBizStatus> mapStatusEnum(WalletBizType bizType, Set<Long> ids) {
    if (Objects.isNull(bizType) || CollectionUtils.isEmpty(ids)) {
      return CollectionUtils.newHashMap();
    }

    List<WalletAssetRecordStatus> walletBizStatus = query()
        .eq(WalletAssetRecordStatus::getBizType, bizType.getType())
        .in(WalletAssetRecordStatus::getId, ids)
        .list();

    if (CollectionUtils.isEmpty(walletBizStatus)) {
      return CollectionUtils.newHashMap();
    }
    return walletBizStatus.stream()
        .collect(Collectors.toMap(WalletAssetRecordStatus::getId,
            v -> WalletBizStatus.toEnum(v.getStatus())));
  }

  private boolean exists(String bizId, WalletBizType bizType, Integer status) {
    return Optional.ofNullable(query()
            .select(WalletAssetRecordStatus::getId)
            .eq(WalletAssetRecordStatus::getBizId, bizId)
            .eq(WalletAssetRecordStatus::getBizType, bizType.getType())
            .eq(WalletAssetRecordStatus::getStatus, status)
            .last(PageConstant.LIMIT_ONE)
            .getOne())
        .map(record -> Objects.nonNull(record.getId()))
        .orElse(false);
  }
}
