package com.red.circle.order.infra.database.rds.service.pay.impl;

import com.google.api.client.util.Lists;
import com.google.api.client.util.Maps;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.order.infra.database.rds.dao.pay.PayCountryChannelDetailsDAO;
import com.red.circle.order.infra.database.rds.entity.pay.PayCountryChannelDetails;
import com.red.circle.order.infra.database.rds.service.pay.PayCountryChannelDetailsService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.math.BigDecimal;
import java.util.Comparator;
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 lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 国家支持渠道详情 服务实现类.
 * </p>
 *
 * @author pengshigang
 * @since 2021-12-08
 */
@Service
@RequiredArgsConstructor
public class PayCountryChannelDetailsServiceImpl extends
    BaseServiceImpl<PayCountryChannelDetailsDAO, PayCountryChannelDetails> implements
    PayCountryChannelDetailsService {

  @Override
  public List<PayCountryChannelDetails> listChannelCode(Long payCountryId, BigDecimal amountUsd) {
    return Optional
        .ofNullable(query()
            .eq(PayCountryChannelDetails::getPayCountryId, payCountryId)
            .le(PayCountryChannelDetails::getFactoryMinLimit, amountUsd)
            .ge(PayCountryChannelDetails::getFactoryMaxLimit, amountUsd)
            .ge(PayCountryChannelDetails::getFactoryDailyLimit, amountUsd)
            .eq(PayCountryChannelDetails::getShelf, Boolean.TRUE)
            .list())
        .map(details -> details.stream()
            .filter(detail -> StringUtils.isNotBlank(detail.getFactoryChannel())).collect(
                Collectors.toList()))
        .orElseGet(CollectionUtils::newArrayList);
  }

  @Override
  public List<PayCountryChannelDetails> listChannelCode(Long payCountryId) {
    return Optional
        .ofNullable(query()
            .eq(PayCountryChannelDetails::getPayCountryId, payCountryId)
            .eq(PayCountryChannelDetails::getShelf, Boolean.TRUE)
            .list())
        .map(details -> details.stream()
            .filter(detail -> StringUtils.isNotBlank(detail.getFactoryChannel())).collect(
                Collectors.toList()))
        .orElseGet(CollectionUtils::newArrayList);
  }


  @Override
  public PayCountryChannelDetails getSuggestScoreMax(Long payCountryId, String channelCode,
      BigDecimal amountUsd) {
    return Optional
        .ofNullable(query()
            .eq(PayCountryChannelDetails::getChannelCode, channelCode)
            .eq(PayCountryChannelDetails::getPayCountryId, payCountryId)
            .le(PayCountryChannelDetails::getFactoryMinLimit, amountUsd)
            .ge(PayCountryChannelDetails::getFactoryMaxLimit, amountUsd)
            .ge(PayCountryChannelDetails::getFactoryDailyLimit, amountUsd)
            .eq(PayCountryChannelDetails::getShelf, Boolean.TRUE)
            .list())
        .flatMap(details -> details.stream()
            .filter(detail -> StringUtils.isNotBlank(detail.getFactoryChannel()) && Objects
                .nonNull(detail.getSuggestScore()))
            .max(Comparator.comparing(PayCountryChannelDetails::getSuggestScore))
        ).orElse(null);
  }

  @Override
  public Map<Long, List<PayCountryChannelDetails>> mapChannelCodeList(Set<Long> payCountryIds) {

    if (CollectionUtils.isEmpty(payCountryIds)) {
      return CollectionUtils.newHashMap();
    }

    return Optional
        .ofNullable(query()
            .in(PayCountryChannelDetails::getPayCountryId, payCountryIds)
            .eq(PayCountryChannelDetails::getShelf, Boolean.TRUE)
            .list())
        .map(details -> details.stream()
            .filter(detail -> StringUtils.isNotBlank(detail.getFactoryChannel()))
            .collect(Collectors.groupingBy(PayCountryChannelDetails::getPayCountryId)))
        .orElse(CollectionUtils.newHashMap());

  }

  @Override
  public Map<Long, List<PayCountryChannelDetails>> mapByCountryChannelId(
      Set<Long> countryChannelIds) {
    if (CollectionUtils.isEmpty(countryChannelIds)) {
      return Maps.newHashMap();
    }
    return Optional.ofNullable(
            query().in(PayCountryChannelDetails::getCountryChannelId, countryChannelIds).list())
        .map(details -> details.stream().collect(
            Collectors.groupingBy(PayCountryChannelDetails::getCountryChannelId)))
        .orElseGet(Maps::newHashMap);
  }

  @Override
  public List<PayCountryChannelDetails> listSupportAmountUsd(Long payCountryId,
      BigDecimal amountUsd) {
    return Optional
        .ofNullable(query()
            .eq(PayCountryChannelDetails::getPayCountryId, payCountryId)
            .le(PayCountryChannelDetails::getFactoryMinLimit, amountUsd)
            .ge(PayCountryChannelDetails::getFactoryMaxLimit, amountUsd)
            .ge(PayCountryChannelDetails::getFactoryDailyLimit, amountUsd)
            .eq(PayCountryChannelDetails::getShelf, Boolean.TRUE)
            .list())
        .map(details -> details.stream()
            .filter(detail -> StringUtils.isNotBlank(detail.getFactoryChannel())).collect(
                Collectors.toList()))
        .orElseGet(Lists::newArrayList);
  }

}
