package tv.pluto.mongo.utils;

import static com.mongodb.client.model.Projections.fields;
import static com.mongodb.client.model.Projections.include;

import com.mongodb.BasicDBObject;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import tv.pluto.mongo.entities.channels.Channels;
import tv.pluto.mongo.entities.vod.VodCategories;
import tv.pluto.utils.CommonUtils;

public class VodCategoryUtils extends MongoUtils {

  public VodCategoryUtils() {
    super(new VodCategories());
  }

  public String getValidActiveRegion() {
    BasicDBObject query = new BasicDBObject("is_stitched", true).append("published", true);
    List<String> activeRegions = new ArrayList<>();
    genericCollection
        .find(query)
        .projection(fields(include("activeRegion")))
        .forEach(channel -> activeRegions.add(((Channels) channel).getActiveRegion()));

    List<String> uniqueActiveRegions =
        activeRegions.stream().distinct().collect(Collectors.toList());

    return getRandomItem(uniqueActiveRegions);
  }

  public List<VodCategories> getListVodCategories(BasicDBObject query) {
    List<VodCategories> result = new ArrayList<>();
    genericCollection.find(query).forEach(e -> result.add((VodCategories) e));
    return result;
  }

  public BasicDBObject kidsModeObject(VodCategories vodCategories) {
    BasicDBObject basicDBObject = new BasicDBObject();
    basicDBObject.put("kidsMode", vodCategories.getKidsMode());
    return basicDBObject;
  }

  public VodCategories getDocumentWithoutSpecialCharactersInName() {
    List<VodCategories> vods = this.getRandomDocuments(30);

    return vods.stream()
        .filter(vod -> !CommonUtils.containsSpecialCharacters(vod.getName()))
        .findFirst()
        .orElse(null);
  }

  public List<VodCategories> getDocumentsByRegex(String field, String regex) {
    List<VodCategories> result = new ArrayList<>();

    BasicDBObject query =
        new BasicDBObject(field, new BasicDBObject("$regex", regex).append("$options", "si"));

    genericCollection.find(query).forEach(e -> result.add((VodCategories) e));
    return result;
  }

  public List<VodCategories> getListVOD(BasicDBObject query, int limit, int offset, Bson sort) {
    List<VodCategories> result = new ArrayList<>();
    genericCollection
        .find(query)
        .limit(limit)
        .sort(sort)
        .skip(offset)
        .forEach(e -> result.add((VodCategories) e));
    return result;
  }

  public List<VodCategories> getByIds(
      List<String> categoryIds, int limit, int offset, Bson sort, Bson projection) {
    List<VodCategories> result = new ArrayList<>();

    List<ObjectId> objectIds = categoryIds.stream().map(ObjectId::new).toList();

    BasicDBObject query = new BasicDBObject("_id", new BasicDBObject("$in", objectIds));

    genericCollection
        .find(query)
        .projection(projection)
        .limit(limit)
        .sort(sort)
        .skip(offset)
        .forEach(e -> result.add((VodCategories) e));

    return result;
  }
}
