package com.red.circle.other.infra.database.mongo.service.user.region.impl;

import com.google.common.collect.Lists;
import com.red.circle.other.infra.database.mongo.entity.user.region.SysRegionAssistConfig;
import com.red.circle.other.infra.database.mongo.service.user.region.SysRegionAssistConfigService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.other.inner.model.cmd.user.RegionAssistConfigQryCmd;
import com.red.circle.other.inner.enums.user.RegionAssistTypeEnum;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

/**
 * 区域辅助数据.
 *
 * @author pengshigang on 2023/03/14
 */
@Service
@RequiredArgsConstructor
public class SysRegionAssistConfigServiceImpl implements SysRegionAssistConfigService {

  private final MongoTemplate mongoTemplate;

  @Override
  public void add(SysRegionAssistConfig config) {
    config.setId(IdWorkerUtils.getIdStr());
    config.setCreateTime(TimestampUtils.now());
    config.setDel(Boolean.FALSE);
    mongoTemplate.save(config);
  }

  @Override
  public void update(SysRegionAssistConfig config) {
    if (StringUtils.isBlank(config.getId())) {
      return;
    }
    mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(config.getId())),
        new Update()
            .set("imgUrl", config.getImgUrl())
            .set("data", config.getData())
            .set("updateTime", config.getUpdateTime())
            .set("updateUser", config.getUpdateUser()), SysRegionAssistConfig.class);
  }

  @Override
  public void deleteById(String id, Long updateUser) {

    mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(id)),
        new Update().set("del", Boolean.TRUE)
            .set("updateUser", updateUser)
            .set("updateTime", TimestampUtils.now()),
        SysRegionAssistConfig.class);
  }

  @Override
  public void deleteByRegionId(String regionId, Long updateUser) {
    mongoTemplate.updateMulti(Query.query(Criteria.where("regionId").is(regionId)),
        new Update().set("del", Boolean.TRUE)
            .set("updateUser", updateUser)
            .set("updateTime", TimestampUtils.now()),
        SysRegionAssistConfig.class);
  }

  @Override
  public List<SysRegionAssistConfig> listByCondition(RegionAssistConfigQryCmd query) {

    Criteria criteria = Criteria.where("sysOrigin").is(query.getSysOrigin()).and("del")
        .is(Boolean.FALSE);

    if (StringUtils.isNotBlank(query.getType())) {
      criteria.and("type").is(query.getType());
    }

    if (StringUtils.isNotBlank(query.getRegionId())) {
      criteria.and("regionId").is(query.getRegionId());
    }

    return mongoTemplate.find(Query.query(criteria)
            .with(Sort.by(Sort.Order.desc("createTime"))),
        SysRegionAssistConfig.class);

  }

  @Override
  public SysRegionAssistConfig getById(String id) {
    return mongoTemplate
        .findOne(Query.query(Criteria.where("id").is(id).and("del").is(Boolean.FALSE)),
            SysRegionAssistConfig.class);
  }

  @Override
  public SysRegionAssistConfig getRegionAssistConfig(RegionAssistTypeEnum type, String regionId) {
    if (Objects.isNull(type) || StringUtils.isBlank(regionId)) {
      return null;
    }
    return mongoTemplate.findOne(Query.query(Criteria.where("type").is(type)
            .and("regionId").is(regionId).and("del").is(Boolean.FALSE)),
        SysRegionAssistConfig.class);
  }

  @Override
  public List<SysRegionAssistConfig> listByTypeByRegionId(RegionAssistTypeEnum type,
      String regionId) {

    return mongoTemplate.find(Query.query(Criteria.where("type").is(type)
            .and("regionId").is(regionId).and("del").is(Boolean.FALSE)),
        SysRegionAssistConfig.class);
  }

  @Override
  public <T> List<T> listByTypeByRegionId(RegionAssistTypeEnum type, String regionId,
      Class<T> clazz) {
    List<SysRegionAssistConfig> assistConfigs = listByTypeByRegionId(
        RegionAssistTypeEnum.WITHDRAW_PROPORTION_TIPS, regionId);
    if (CollectionUtils.isEmpty(assistConfigs)) {
      return Lists.newArrayList();
    }

    return assistConfigs.stream()
        .filter(config -> StringUtils.isNotBlank(config.getData()))
        .map(config -> JacksonUtils.readValue(config.getData(), clazz))
        .filter(Objects::nonNull).collect(Collectors.toList());
  }

}
