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

import com.caliverse.admin.global.common.constants.AdminConstants;
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;


@Service
public class BusinessLogAuByLangService extends BusinessLogServiceBase {

    public BusinessLogAuByLangService(@Qualifier("mongoBusinessLogTemplate") MongoTemplate mongoTemplate) {
        super(mongoTemplate);
    }
    /*
    * 집계시 유의 사항
    * 언어별 카운팅 시 한 유저가 en, ko 동시에 로그가 남을수 있다. (게임에서 언어변경시)
    * */
    public <T> List<T> loadBusinessLogData(String startTime, String endTime, Class<T> class1) {

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

        GroupOperation groupByUserGuid = Aggregation.group(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE, AdminConstants.MONGO_DB_KEY_LOGMINUTE)
            .addToSet(AdminConstants.MONGO_DB_KEY_USER_GUID).as(AdminConstants.MONGO_DB_KEY_USER_GUID_LIST)
            .first(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE).as(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE)
            .first(AdminConstants.MONGO_DB_KEY_LOGTIME).as(AdminConstants.MONGO_DB_KEY_LOGTIME)
            .first(AdminConstants.MONGO_DB_KEY_LOGDAY).as(AdminConstants.MONGO_DB_KEY_LOGDAY)
            .first(AdminConstants.MONGO_DB_KEY_LOGHOUR).as(AdminConstants.MONGO_DB_KEY_LOGHOUR)
            .first(AdminConstants.MONGO_DB_KEY_LOGMINUTE).as(AdminConstants.MONGO_DB_KEY_LOGMINUTE)
        ;

        ProjectionOperation projectWithUserGuidListCount = Aggregation.project()
            .and(AdminConstants.MONGO_DB_KEY_USER_GUID_LIST).size().as(AdminConstants.MONGO_DB_KEY_USER_GUID_LIST_COUNT)
            .and(AdminConstants.MONGO_DB_KEY_USER_GUID_LIST).as(AdminConstants.MONGO_DB_KEY_USER_GUID_LIST)
            .and(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE).as(AdminConstants.MONGO_DB_KEY_LANGUAGE_TYPE)
            .and(AdminConstants.MONGO_DB_KEY_LOGTIME).as(AdminConstants.MONGO_DB_KEY_LOGTIME)
            .and(AdminConstants.MONGO_DB_KEY_LOGDAY).as(AdminConstants.MONGO_DB_KEY_LOGDAY)
            .and(AdminConstants.MONGO_DB_KEY_LOGHOUR).as(AdminConstants.MONGO_DB_KEY_LOGHOUR)
            .and(AdminConstants.MONGO_DB_KEY_LOGMINUTE).as(AdminConstants.MONGO_DB_KEY_LOGMINUTE)
        ;

        operations.add(groupByUserGuid);
        operations.add(projectWithUserGuidListCount);


        Aggregation aggregation = Aggregation.newAggregation(operations);
        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_USER_AUTH)
                        ,Criteria.where(AdminConstants.MONGO_DB_KEY_MESSAGE).regex(AdminConstants.REGEX_MSG_LOGIN_TO_GAME)
                        ,Criteria.where(AdminConstants.MONGO_DB_KEY_MESSAGE).regex(AdminConstants.REGEX_MSG_USER_LOGOUT)
                )
            );
    }

}
