package com.red.circle.order.inner.service.impl;

import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.order.infra.database.rds.entity.pay.PayApplication;
import com.red.circle.order.infra.database.rds.entity.pay.PayApplicationCommodity;
import com.red.circle.order.infra.database.rds.service.pay.PayApplicationCommodityService;
import com.red.circle.order.infra.database.rds.service.pay.PayApplicationService;
import com.red.circle.order.inner.convertor.WebPayInnerConvertor;
import com.red.circle.order.inner.model.cmd.SysPayApplicationCommodityCmd;
import com.red.circle.order.inner.model.cmd.SysPayApplicationCommodityQryCmd;
import com.red.circle.order.inner.model.dto.SysPayApplicationCommodityDTO;
import com.red.circle.order.inner.model.dto.SysPayApplicationDTO;
import com.red.circle.order.inner.service.PayApplicationClientService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.other.inner.endpoint.user.region.RegionConfigClient;
import java.util.List;
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;

/**
 * 开通支付应用.
 *
 * @author pengliang on 2023/11/3
 */
@Service
@RequiredArgsConstructor
public class PayApplicationClientServiceImpl implements PayApplicationClientService {

  private final RegionConfigClient regionConfigClient;
  private final WebPayInnerConvertor webPayInnerConvertor;
  private final PayApplicationService payApplicationService;
  private final PayApplicationCommodityService payApplicationCommodityService;

  @Override
  public List<SysPayApplicationDTO> listApplication() {
    return Optional.ofNullable(payApplicationService.query()
            .orderByDesc(PayApplication::getId)
            .list())
        .map(sysPayApplications -> sysPayApplications.stream()
            .map(webPayInnerConvertor::toSysPayApplicationDTO)
            .collect(
                Collectors.toList()))
        .orElseGet(Lists::newArrayList);
  }

  @Override
  public void addApplication(SysPayApplicationDTO param) {
    payApplicationService.addApplication(webPayInnerConvertor.toPayApplication(param));
  }

  @Override
  public void updateApplication(SysPayApplicationDTO param) {
    payApplicationService.updateSelectiveById(webPayInnerConvertor.toPayApplication(param));
  }


  @Override
  public PageResult<SysPayApplicationCommodityDTO> pageCommodity(
      SysPayApplicationCommodityQryCmd query) {

    PageResult<SysPayApplicationCommodityDTO> commodityPage = payApplicationCommodityService.query()
        .eq(StringUtils.isNotBlank(query.getType()), PayApplicationCommodity::getType,
            query.getType())
        .eq(Objects.nonNull(query.getId()), PayApplicationCommodity::getId,
            query.getId())
        .eq(Objects.nonNull(query.getApplicationId()), PayApplicationCommodity::getApplicationId,
            query.getApplicationId())
        .eq(Objects.nonNull(query.getPayCountryId()), PayApplicationCommodity::getPayCountryId,
            query.getPayCountryId())
        .eq(Objects.nonNull(query.getShelf()), PayApplicationCommodity::getShelf,
            query.getShelf())
        .eq(StringUtils.isNotBlank(query.getRegionId()), PayApplicationCommodity::getRegionId,
            query.getRegionId())
        .eq(StringUtils.isBlank(query.getRegionId()), PayApplicationCommodity::getRegionId, "")
        .orderByDesc(PayApplicationCommodity::getAmountUsd)
        .page(query.getPageQuery())
        .convert(webPayInnerConvertor::toSysPayApplicationCommodityDTO);

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

    Map<String, String> mapRegionName = getMapRegionName(commodityPage);

    return commodityPage.convert(commodity -> {

      if (StringUtils.isNotBlank(commodity.getRegionId())) {
        commodity.setRegionName(mapRegionName.get(commodity.getRegionId()));
      }
      return commodity;
    });
  }

  private Map<String, String> getMapRegionName(
      PageResult<SysPayApplicationCommodityDTO> commodityPage) {

    return ResponseAssert.requiredSuccess(regionConfigClient.mapRegionNameByRegionIds(
        commodityPage.getRecords().stream().map(SysPayApplicationCommodityDTO::getRegionId).collect(
            Collectors.toSet())));
  }

  @Override
  public void addOrUpdateCommodity(SysPayApplicationCommodityCmd param) {
    payApplicationCommodityService.saveOrUpdate(
        webPayInnerConvertor.toPayApplicationCommodity(param));
  }

  @Override
  public void switchShelf(Long id, Boolean shelf) {
    payApplicationCommodityService.update()
        .set(PayApplicationCommodity::getShelf, shelf)
        .eq(PayApplicationCommodity::getId, id)
        .execute();
  }
}
