package com.red.circle.other.infra.database.rds.service.badge.impl;

import com.google.common.collect.Lists;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.other.infra.database.rds.dao.badge.BadgeConfigDAO;
import com.red.circle.other.infra.database.rds.entity.badge.BadgeConfig;
import com.red.circle.other.infra.database.rds.service.badge.BadgeConfigService;
import com.red.circle.other.inner.enums.material.BadgeConfigTypeEnum;
import com.red.circle.other.inner.enums.material.BadgeKeyEnum;
import com.red.circle.other.inner.enums.sys.SysBadgeConfigTypeEnum;
import com.red.circle.other.inner.model.cmd.sys.GiveBadgeConfigQryCmd;
import com.red.circle.other.inner.model.cmd.sys.SysBadgeConfigQryCmd;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.text.StringUtils;
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;

/**
 * <p>
 * 徽章配置 服务实现类.
 * </p>
 *
 * @author pengliang
 * @since 2021-03-12
 */
@Service
public class BadgeConfigServiceImpl extends BaseServiceImpl<BadgeConfigDAO, BadgeConfig> implements
    BadgeConfigService {


  @Override
  public List<BadgeConfig> listBadgeByType(SysBadgeConfigTypeEnum type) {
    List<BadgeConfig> badgeConfigs = query()
        .eq(BadgeConfig::getType, type)
        .eq(BadgeConfig::getDel, Boolean.FALSE)
        .orderByDesc(BadgeConfig::getId)
        .list();

    if (CollectionUtils.isEmpty(badgeConfigs)) {
      return Lists.newArrayList();
    }

    return badgeConfigs;
  }

  @Override
  public Long getFreightBadgeId() {
    return Optional.ofNullable(
            query().select(BadgeConfig::getId)
                .eq(BadgeConfig::getType, BadgeConfigTypeEnum.HONOR_ADMIN)
                .eq(BadgeConfig::getBadgeKey, BadgeKeyEnum.RECHARGE_AGENCY)
                .eq(BadgeConfig::getDel, Boolean.FALSE)
                .last(PageConstant.LIMIT_ONE)
                .getOne())
        .map(BadgeConfig::getId)
        .orElse(null);
  }

  @Override
  public List<Long> listAdministratorIds() {
    return Optional.ofNullable(query().select(BadgeConfig::getId)
            .eq(BadgeConfig::getType, BadgeConfigTypeEnum.ADMINISTRATOR)
            .eq(BadgeConfig::getDel, Boolean.FALSE)
            .list())
        .map(badgeConfigs -> badgeConfigs.stream().map(BadgeConfig::getId).collect(
            Collectors.toList()))
        .orElse(null);
  }

  @Override
  public List<Long> listAdminBadgeIds() {
    return Optional.ofNullable(
            query().select(BadgeConfig::getId)
                .eq(BadgeConfig::getType, SysBadgeConfigTypeEnum.HONOR_ADMIN)
                 .likeLeft(BadgeConfig::getBadgeKey, BadgeKeyEnum.ADMIN)
                .eq(BadgeConfig::getDel, Boolean.FALSE)
                .list())
        .map(sysBadgeConfigs -> sysBadgeConfigs.stream().map(BadgeConfig::getId).collect(
            Collectors.toList()))
        .orElse(null);
  }

  @Override
  public List<BadgeConfig> listByBadgeKey(BadgeKeyEnum badgeKey) {
    return query().eq(BadgeConfig::getBadgeKey, badgeKey)
        .eq(BadgeConfig::getDel, Boolean.FALSE)
        .orderByAsc(BadgeConfig::getBadgeLevel)
        .list();
  }

  @Override
  public List<BadgeConfig> listBadgeConfig(BadgeConfigTypeEnum type) {
    return query().eq(BadgeConfig::getType, type)
        .eq(BadgeConfig::getDel, Boolean.FALSE)
        .orderByAsc(BadgeConfig::getBadgeLevel)
        .last(PageConstant.formatLimit(200)).list();
  }

  @Override
  public List<BadgeConfig> listByIds(List<Long> ids) {
    return CollectionUtils.isEmpty(ids) ? CollectionUtils.newArrayList()
        : query().in(BadgeConfig::getId, ids).list();
  }

  @Override
  public Map<Long, BadgeConfig> mapByIds(Set<Long> ids) {
    return CollectionUtils.isEmpty(ids)
        ? CollectionUtils.newHashMap()
        : Optional.ofNullable(query().in(BadgeConfig::getId, ids).list2Map(BadgeConfig::getId))
            .orElseGet(CollectionUtils::newHashMap);
  }

  @Override
  public PageResult<BadgeConfig> getGiveBadgePage(GiveBadgeConfigQryCmd query, Set<Long> collect) {
    return query()
        .eq(BadgeConfig::getDel, Boolean.FALSE)
        .in(BadgeConfig::getId, collect)
        .ne(BadgeConfig::getType, SysBadgeConfigTypeEnum.ACHIEVEMENT.getName())
        .ne(BadgeConfig::getType, SysBadgeConfigTypeEnum.FAMILY.getName())
        .ne(BadgeConfig::getType, SysBadgeConfigTypeEnum.ROOM_ACHIEVEMENT.getName())
        .orderByDesc(BadgeConfig::getCreateTime).page(query.getPageQuery());
  }

  @Override
  public List<BadgeConfig> listBadgeByIds(SysBadgeConfigTypeEnum type, Set<Long> collect) {
    return query().eq(BadgeConfig::getType, type)
        .in(BadgeConfig::getId, collect)
        .list();
  }

  @Override
  public void deleteBadge(Long id) {
    update()
        .set(BadgeConfig::getDel, Boolean.TRUE)
        .eq(BadgeConfig::getId, id)
        .execute();
  }

  @Override
  public void updateBadgeConfig(BadgeConfig badgeConfig) {
    update()
        .set(BadgeConfig::getBadgeName, badgeConfig.getBadgeName())
        .set(BadgeConfig::getType, badgeConfig.getType())
        .set(BadgeConfig::getBadgeKey, badgeConfig.getBadgeKey())
        .set(BadgeConfig::getBadgeLevel, badgeConfig.getBadgeLevel())
        .set(BadgeConfig::getMilestone, badgeConfig.getMilestone())
        .eq(BadgeConfig::getId, badgeConfig.getId())
        .last(PageConstant.LIMIT_ONE)
        .execute();
  }

  @Override
  public PageResult<BadgeConfig> getBadgeConfig(SysBadgeConfigQryCmd query) {
    return query()
        .eq(BadgeConfig::getDel, Boolean.FALSE)
        .like(StringUtils.isNotBlank(query.getBadgeName()), BadgeConfig::getBadgeName,
            query.getBadgeName())
        .like(StringUtils.isNotBlank(query.getBadgeKey()), BadgeConfig::getBadgeKey,
            query.getBadgeKey())
        .eq(Objects.nonNull(query.getId()), BadgeConfig::getId, query.getId())
        .eq(StringUtils.isNotBlank(query.getType()), BadgeConfig::getType, query.getType())
        .orderByDesc(BadgeConfig::getCreateTime)
        .page(query.getPageQuery());
  }

  @Override
  public Long getAdminBadgeId(String key) {
    return Optional.ofNullable(
            query().select(BadgeConfig::getId)
                .eq(BadgeConfig::getType, SysBadgeConfigTypeEnum.HONOR_ADMIN)
                .eq(BadgeConfig::getBadgeKey, key)
                .eq(BadgeConfig::getDel, Boolean.FALSE)
                .last(PageConstant.LIMIT_ONE)
                .getOne())
        .map(BadgeConfig::getId)
        .orElse(null);
  }

  @Override
  public BadgeConfig getUserMaxLevelFamilyBadge(Long userId) {
    return baseDAO.getUserMaxLevelFamilyBadge(userId);
  }

  @Override
  public List<BadgeConfig> getBadgeConfigList(BadgeConfigTypeEnum type, String sysOrgin) {
    return baseDAO.getBadgeConfigList(type,sysOrgin);
  }

  @Override
  public BadgeConfig getByBadgeKey(String badgeKey) {
    return query()
        .eq(BadgeConfig::getBadgeKey, badgeKey)
        .eq(BadgeConfig::getDel, Boolean.FALSE)
        .last(PageConstant.LIMIT_ONE)
        .getOne();
  }
}
