package com.caliverse.admin.logs.logservice.businesslogservice;

import com.caliverse.admin.global.common.constants.AdminConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
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;

@Slf4j
@Service
public class BusinessLogDauService extends BusinessLogServiceBase {

    public BusinessLogDauService(@Qualifier("mongoBusinessLogTemplate") MongoTemplate mongoTemplate) {
        super(mongoTemplate);
    }

    public <T> List<T> loadBusinessLogData(String startTime, String endTime, Class<T> class1) {

        Criteria criteria = makeCriteria(startTime, endTime);
        List<AggregationOperation> operations = setDefaultOperation(criteria);

        GroupOperation groupByUserAccountId = Aggregation.group()
                .addToSet(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID).as(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID)
                .first(AdminConstants.MONGO_DB_KEY_LOGDAY).as(AdminConstants.MONGO_DB_KEY_LOGDAY)
                ;
        ProjectionOperation projectWithAccountIdistCount = Aggregation.project()
                .and(AdminConstants.MONGO_DB_KEY_ACCOUNT_ID).size().as(AdminConstants.MONGO_DB_KEY_ACCOUNT_IDS_COUNT)
                .and(AdminConstants.MONGO_DB_KEY_LOGDAY).as(AdminConstants.MONGO_DB_KEY_LOGDAY)
                ;
        operations.add(groupByUserAccountId);
        operations.add(projectWithAccountIdistCount);

        Aggregation aggregation = Aggregation.newAggregation(operations);
        log.info("loadBusinessLogData DAU Query: {}", aggregation);
        AggregationResults<T> results = getMongoTemplate().aggregate(aggregation, AdminConstants.MONGO_DB_COLLECTION_LOG, class1);

        return results.getMappedResults();
    }


    protected Criteria makeCriteria(String startTime, String endTime) {
        return new Criteria()
            .andOperator(
                Criteria.where(AdminConstants.MONGO_DB_KEY_LOGTIME).gte(startTime)
                ,Criteria.where(AdminConstants.MONGO_DB_KEY_LOGTIME).lt(endTime)
                , new Criteria()
                    .orOperator(
                            Criteria.where(AdminConstants.MONGO_DB_KEY_MESSAGE).regex(AdminConstants.REGEX_MSG_LOGIN_TO_GAME)
                    )
            );
    }

}
