package com.caliverse.admin.scheduler.batch;

import com.caliverse.admin.global.common.constants.AdminConstants;
import com.caliverse.admin.global.common.utils.CommonUtils;
import com.caliverse.admin.logs.Indicatordomain.StartEndTime;
import com.caliverse.admin.logs.logservice.LogServiceHelper;
import com.caliverse.admin.logs.logservice.indicators.*;
import com.caliverse.admin.scheduler.SchedulerManager;
import com.caliverse.admin.scheduler.batch.service.DataClearService;
import com.caliverse.admin.scheduler.batch.service.LogCompressService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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 java.time.LocalDate;

@Component
@Slf4j
@EnableScheduling
@RequiredArgsConstructor
public class ScheduleRunnerBatch {

    private final SchedulerManager schedulerManager;

    @Autowired private LogCompressService logService;
    @Autowired private DataClearService dataClearService;

    @Autowired private IndicatorsUserCreateService userCreateService;
    @Autowired private IndicatorsUserLoginService userLoginService;
    @Autowired private IndicatorsCurrencyService currencyService;
    @Autowired private IndicatorsItemService itemService;
    @Autowired private IndicatorsSnapshotService snapshotService;

    @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;

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

    //오래된 데이터 삭제
    @Scheduled(cron = "00 05 00 1 * ?") // 매월 1일에 실행
    public void oldDataClear(){
        dataClearService.oldDataClear();
    }

    @Scheduled(cron = "00 30 0 * * *") // 매일 UTC 기준 00시 30분 00초에 실행
    public void userCreateScheduler() {
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        userCreateService.collectUserCreate(startEndTime.getStartTime(), startEndTime.getEndTime());
    }

    @Scheduled(cron = "30 30 0 * * *") // 매일 UTC 기준 00시 30분 30초에 실행
    public void userLoginScheduler() {
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        userLoginService.collectUserLogin(startEndTime.getStartTime(), startEndTime.getEndTime());
    }

    @Scheduled(cron = "00 31 0 * * *") // 매일 UTC 기준 00시 31분 00초에 실행
    public void currencyInfoScheduler() {
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        currencyService.collectCurrency(startEndTime.getStartTime(), startEndTime.getEndTime());
    }

    @Scheduled(cron = "30 31 0 * * *") // 매일 UTC 기준 00시 31분 30초에 실행
    public void itemInfoScheduler() {
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        itemService.collectItem(startEndTime.getStartTime(), startEndTime.getEndTime());
    }

    @Scheduled(cron = "00 32 0 * * *") // 매일 UTC 기준 00시 32분 00초에 실행(오래걸림)
    public void snapshotInfoScheduler() {
        StartEndTime startEndTime = LogServiceHelper.getCurrentLogSearchEndTime(AdminConstants.STAT_DAY_NUM);
        snapshotService.collectSnapshot(startEndTime.getStartTime(), startEndTime.getEndTime());
    }

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

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

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

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

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

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

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

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

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

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

}
