package com.caliverse.admin.scheduler;

import com.caliverse.admin.domain.service.CaliumService;
import com.caliverse.admin.global.common.utils.CommonUtils;
import com.caliverse.admin.logs.logservice.indicators.*;
import com.caliverse.admin.scheduler.batch.service.LogCompressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;


import com.caliverse.admin.global.common.constants.AdminConstants;
import com.caliverse.admin.logs.Indicatordomain.StartEndTime;
import com.caliverse.admin.logs.logservice.LogServiceHelper;
import com.caliverse.admin.redis.service.RedisUserInfoService;

import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;

@Component
@Slf4j
@EnableScheduling
public class ScheduleSetter {

    @Autowired private IndicatorsAuService auService;
    @Autowired private IndicatorsDauService dauService;
    @Autowired private IndicatorsWauService wauService;
    @Autowired private IndicatorsMauService mauService;
    @Autowired private IndicatorsMcuService mcuService;
    @Autowired private IndicatorsNruService nruService;
    @Autowired private IndicatorsPlayTimeService playTimeService;
    @Autowired private IndicatorsDglcService dglcService;
    @Autowired private IndicatorsDBCapacityService capacityService;
    @Autowired private IndicatorsUgqCreateService ugqCreateService;
    @Autowired private IndicatorsMetaverseServerService metaverseServerService;

    @Autowired private IndicatorsNruService statNruService;
    @Autowired private RedisUserInfoService userInfoService;
    @Autowired private DynamicScheduler dynamicScheduler;

    @Autowired private CaliumService caliumService;
    @Autowired private LogCompressService logService;

    @Scheduled(cron = "0 01 0 * * *") // 매일 UTC 기준 00시 01분 00초에 실행
    public void capacityScheduler() {
//        log.info("run capacityScheduler");
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        capacityService.collectDBCapacity(startEndTime.getStartTime(), startEndTime.getEndTime());
//        log.info("end capacityScheduler");
    }

    @Scheduled(cron = "0 02 0 * * *") // 매일 UTC 기준 00시 02분 00초에 실행
    public void metaverServerScheduler() {
//        log.info("run metaverServerScheduler");
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        int serverCount = 13;
        metaverseServerService.collectMetaverseServerCount(startEndTime.getStartTime(), startEndTime.getEndTime(), serverCount);
//        log.info("end metaverServerScheduler");
    }

    /*
        매일 UTC 기준 00시 50분 00초에 실행, (한국 시간 9시 50분) 30분에 돌릴경우 데이터가 다 넘어 오지 않는 경우 있어서 수정처리
        이게 가장 먼저 실행 되어야 한다.
        로그가 많을 경우 성능 이슈 있을 수 있음
    */
    @Scheduled(cron = "0 50 0 * * *")
    public void auScheduler() {
        //이걸 나중에 어떻게 활용할지 생각해보자.
//        log.info("run auScheduler");
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        auService.collectActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime());
//        log.info("end auScheduler");
    }

    @Scheduled(cron = "00 55 0 * * *") // 매일 UTC 기준 00시 55분 00초에 실행
    public void dauScheduler() {
//        log.info("run dauScheduler");
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        dauService.collectDailyActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime());
//        log.info("end dauScheduler");
    }

    @Scheduled(cron = "00 56 0 * * *") // 매일 UTC 기준 00시 56분 00초에 실행
    public void wauScheduler() {
//        log.info("run wauScheduler");
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_WEEK_NUM);
        wauService.collectWeeklyActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime());
//        log.info("end wauScheduler");
    }

//    @Scheduled(cron = "00 57 0 * * *") // 매일 UTC 기준 00시 57분 00초에 실행
    @Scheduled(cron = "00 57 0 1 * ?") // 매월 1일 UTC 기준 00시 57분 00초에 실행
    public void mauScheduler() {
//        log.info("run mauScheduler");
        int monthLength = CommonUtils.getLengthOfLastMonth(LocalDate.now());    // 지난달 총일수 가져오기
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(monthLength);
        mauService.collectMonthlyActiveUser(startEndTime.getStartTime(), startEndTime.getEndTime());
//        log.info("end mauScheduler");
    }

    @Scheduled(cron = "00 58 0 * * *") // 매일 UTC 기준 00시 58분 00초에 실행
    public void mcuScheduler() {
//        log.info("run mcuScheduler");
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        mcuService.collectMaxCountUser(startEndTime.getStartTime(), startEndTime.getEndTime());
//        log.info("end mcuScheduler");
    }

    @Scheduled(cron = "00 59 0 * * *") // 매일 UTC 기준 00시 59분 00초에 실행
    public void nruScheduler() {
//        log.info("run nruScheduler");
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        nruService.collectCharacterCreateCount(startEndTime.getStartTime(), startEndTime.getEndTime());
//        log.info("end nruScheduler");
    }

    @Scheduled(cron = "00 00 1 * * *") // 매일 UTC 기준 1시 00분 00초에 실행
    public void playTimeScheduler() {
//        log.info("run playTimeScheduler");
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        playTimeService.collectUserPlayTime(startEndTime.getStartTime(), startEndTime.getEndTime());
//        log.info("end playTimeScheduler");
    }

    @Scheduled(cron = "00 01 1 * * *") // 매일 UTC 기준 01시 01분 00초에 실행
    public void dglcScheduler() {
//        log.info("run dglcScheduler");
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        dglcService.collectDailyGameLoginCount(startEndTime.getStartTime(), startEndTime.getEndTime());
//        log.info("end dglcScheduler");
    }

    @Scheduled(cron = "00 00 2 * * *") // 매일 UTC 기준 02시 00분 00초에 실행 (Log 데이터가 늦게 넘어올때가 있기때문에 나중에 실행)
    public void ugqCreateScheduler() {
//        log.info("run ugqCreateScheduler");
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        ugqCreateService.collectUGQCreateCount(startEndTime.getStartTime(), startEndTime.getEndTime());
//        log.info("end ugqCreateScheduler");
    }


    @Scheduled(cron = "0 * * * * *") // 매 분 00초에 실행
    public void runJob() {
        //log.info("run runJob");
    }

    @Scheduled(cron = "1 * * * * *")
    public void noticeJob(){
//        log.info("run noticeJob");
        dynamicScheduler.noticeSchedule();
//        log.info("end noticeJob");
    }

    @Scheduled(cron = "2 * * * * *")
    public void mailJob(){
//        log.info("run mailJob");
        dynamicScheduler.mailSchedule();
//        log.info("end mailJob");
    }

    @Scheduled(cron = "3 * * * * *")
    public void blackListJob(){
//        log.info("run blackListJob");
        dynamicScheduler.blackListSchedule();
//        log.info("end blackListJob");
    }

    @Scheduled(cron = "4 * * * * *")
    public void eventJob(){
//        log.info("run eventJob");
        dynamicScheduler.eventSchedule();
//        log.info("end eventJob");
    }

    @Scheduled(cron = "5 * * * * *")
    public void landAuctionJob(){
//        log.info("run landAuctionJob");
        dynamicScheduler.landAuctionSchedule();
//        log.info("end landAuctionJob");
    }

    @Scheduled(cron = "6 * * * * *")
    public void battleEventJob(){
        dynamicScheduler.battleEventSchedule();
    }

    //web3
    @Scheduled(cron = "1 * * * * *")
    public void web3Job(){
//        log.info("run web3Job");
        caliumService.getScheduleCaliumRequestList();
//        log.info("end web3Job");
    }

    //log
    @Scheduled(cron = "00 00 00 1 * ?") // 매월 1일에 실행
    public void logJob(){
        logService.compressLastMonthLogs();
    }
}
