package com.caliverse.admin.Indicators.Indicatorsservice.aggregationservice;

import com.caliverse.admin.Indicators.Indicatordomain.IndicatorsLog;
import com.caliverse.admin.Indicators.Indicatorsservice.base.IndicatorsLogLoadServiceBase;
import com.caliverse.admin.global.common.constants.AdminConstants;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class IndicatorsAssetsLoadService extends IndicatorsLogLoadServiceBase {
    public IndicatorsAssetsLoadService(
            @Qualifier("mongoIndicatorTemplate") MongoTemplate mongoTemplate
    ) {
        super(mongoTemplate);
    }

    @Override
    public <T extends IndicatorsLog> List<T> getIndicatorsLogData(String startTime, String endTime, Class<T> clazz) {

        Criteria criteria = makeCriteria(startTime, endTime, "logDay");

        GroupOperation groupOperation = Aggregation.group("logDay")
                .sum("gold").as("gold")
                .sum("sapphire").as("sapphire")
                .sum("calium").as("calium")
                .sum("ruby").as("ruby")
                .sum("item_11570001").as("item_11570001")
                .sum("item_11570002").as("item_11570002")
                .sum("item_13080002").as("item_13080002")
                .sum("item_13080004").as("item_13080004")
                .sum("item_13080005").as("item_13080005")
                .sum("item_13080006").as("item_13080006")
                .sum("item_13080007").as("item_13080007")
                .sum("item_13080008").as("item_13080008")
                .sum("item_13080009").as("item_13080009")
                .count().as("userCount");

        ProjectionOperation projection = Aggregation.project()
                .andExclude("_id")
                .and("_id").as(AdminConstants.MONGO_DB_KEY_LOGDAY)
                .and("gold").as("gold")
                .and("sapphire").as("sapphire")
                .and("calium").as("calium")
                .and("ruby").as("ruby")
                .and("item_11570001").as("item_11570001")   //강화잉크
                .and("item_11570002").as("item_11570002")   //연성잉크
                .and("item_13080002").as("item_13080002")   //퀘스트 메달
                .and("item_13080004").as("item_13080004")   //보급품 메달
                .and("item_13080005").as("item_13080005")   //제작 메달
                .and("item_13080006").as("item_13080006")   //315 포드
                .and("item_13080007").as("item_13080007")   //316 포드
                .and("item_13080008").as("item_13080008")   //317 포드
                .and("item_13080009").as("item_13080009")   //318 포드
                .and("userCount").as("userCount");

        List<AggregationOperation> operations = List.of(
                Aggregation.match(criteria),
                groupOperation,
                projection,
                Aggregation.sort(Sort.Direction.ASC, AdminConstants.MONGO_DB_KEY_LOGDAY)
        );

        Aggregation aggregation = Aggregation.newAggregation(operations);

        return mongoTemplate.aggregate(
                aggregation.withOptions(AggregationOptions.builder().allowDiskUse(true).build())
                , AdminConstants.MONGO_DB_COLLECTION_ASSETS
                , clazz
        ).getMappedResults();
    }

    public <T extends IndicatorsLog> List<T> getAssetsLogData(String startTime, String endTime, Class<T> clazz) {

        Criteria criteria = makeCriteria(startTime, endTime, "logDay");

        GroupOperation groupOperation = Aggregation.group("logDay")
                .sum("gold").as("gold")
                .sum("sapphire").as("sapphire")
                .sum("calium").as("calium")
                .sum("ruby").as("ruby")
                .sum("item_11570001").as("item_11570001")
                .sum("item_11570002").as("item_11570002")
                .sum("item_13080002").as("item_13080002")
                .sum("item_13080004").as("item_13080004")
                .sum("item_13080005").as("item_13080005")
                .sum("item_13080006").as("item_13080006")
                .sum("item_13080007").as("item_13080007")
                .sum("item_13080008").as("item_13080008")
                .sum("item_13080009").as("item_13080009")
                .count().as("userCount");

        ProjectionOperation projection = Aggregation.project()
                .andExclude("_id")
                .and("logDay").as(AdminConstants.MONGO_DB_KEY_LOGDAY)
                .and("gold").as("gold")
                .and("sapphire").as("sapphire")
                .and("calium").as("calium")
                .and("ruby").as("ruby")
                .and("item_11570001").as("item_11570001")
                .and("item_11570002").as("item_11570002")
                .and("item_13080002").as("item_13080002")
                .and("item_13080004").as("item_13080004")
                .and("item_13080005").as("item_13080005")
                .and("item_13080006").as("item_13080006")
                .and("item_13080007").as("item_13080007")
                .and("item_13080008").as("item_13080008")
                .and("item_13080009").as("item_13080009")
                .and("userCount").as("userCount");

        List<AggregationOperation> operations = List.of(
                Aggregation.match(criteria),
                groupOperation,
                projection,
                Aggregation.sort(Sort.Direction.ASC, AdminConstants.MONGO_DB_KEY_LOGDAY)
        );

        Aggregation aggregation = Aggregation.newAggregation(operations);

        return mongoTemplate.aggregate(
                aggregation.withOptions(AggregationOptions.builder().allowDiskUse(true).build())
                , AdminConstants.MONGO_DB_COLLECTION_ASSETS
                , clazz
        ).getMappedResults();
    }
}
