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

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.other.infra.database.mongo.dto.ActivityTemplateValue;
import com.red.circle.other.infra.database.mongo.entity.sys.ActivityTemplate;
import com.red.circle.other.infra.database.mongo.service.sys.ActivityTemplateService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
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 pengliang on 2022/8/12
 */
@Service
@RequiredArgsConstructor
public class ActivityTemplateServiceImpl implements ActivityTemplateService {

  private final MongoTemplate mongoTemplate;

  @Override
  public void add(ActivityTemplate activityTemplate) {
    mongoTemplate.save(activityTemplate);
  }

  @Override
  public void updateName(Long id, String name, Long updateUser) {
    mongoTemplate.updateFirst(
        Query.query(Criteria.where("id").is(id)),
        new Update()
            .set("name", name)
            .set("updateTime", TimestampUtils.now())
            .set("updateUser", updateUser),
        ActivityTemplate.class
    );
  }

  @Override
  public void updateById(ActivityTemplate activityTemplate) {
    mongoTemplate.updateFirst(
        Query.query(Criteria.where("id").is(activityTemplate.getId())),
        new Update()
            .set("name", activityTemplate.getName())
            .set("indexTree", activityTemplate.getIndexTree())
            .set("updateTime", TimestampUtils.now())
            .set("updateUser", activityTemplate.getUpdateUser()),
        ActivityTemplate.class
    );
  }

  @Override
  public List<ActivityTemplate> list(Long id, Long lastId, Integer pageSize) {
    Criteria criteria = new Criteria();
    if (Objects.nonNull(id)) {
      criteria.and("id").is(id);
    }
    return mongoTemplate.find(Query.query(criteria)
            .with(Sort.by(Sort.Order.desc("id")))
            .limit(pageSize)
        , ActivityTemplate.class);
  }

  @Override
  public List<ActivityTemplateValue> listValues() {
    Query query = Query.query(new Criteria());
    query.fields().include("id");
    query.fields().include("name");
    List<ActivityTemplate> activityTemplates = mongoTemplate.find(query
            .with(Sort.by(Sort.Order.desc("id")))
            .limit(PageConstant.MAX_LIMIT_SIZE)
        , ActivityTemplate.class);

    if (CollectionUtils.isEmpty(activityTemplates)) {
      return Lists.newArrayList();
    }
    return activityTemplates.stream()
        .map(template -> new ActivityTemplateValue()
            .setId(template.getId())
            .setName(template.getName())
        )
        .collect(Collectors.toList());
  }

  @Override
  public ActivityTemplate getById(Long id) {
    return mongoTemplate.findOne(Query.query(Criteria.where("id").is(id))
        , ActivityTemplate.class);
  }

  @Override
  public Map<Long, ActivityTemplateValue> mapByIds(Set<Long> ids) {
    if (CollectionUtils.isEmpty(ids)) {
      return Maps.newHashMap();
    }
    Query query = Query.query(Criteria.where("id").in(ids));
    query.fields().include("id");
    query.fields().include("name");
    return Optional.of(mongoTemplate.find(query, ActivityTemplate.class))
        .map(templates ->
            templates.stream()
                .map(template -> new ActivityTemplateValue()
                    .setId(template.getId())
                    .setName(template.getName())
                )
                .collect(
                    Collectors.toMap(ActivityTemplateValue::getId, Function.identity(),
                        (v0, v1) -> v1))
        ).orElseGet(Maps::newHashMap);
  }

}
