package com.caliverse.admin.scheduler.service;

import com.caliverse.admin.domain.entity.BlackList;
import com.caliverse.admin.domain.service.BlackListService;
import com.caliverse.admin.domain.service.UserGameSessionService;
import com.caliverse.admin.scheduler.ScheduleType;
import com.caliverse.admin.scheduler.Scheduler;
import com.caliverse.admin.scheduler.config.ScheduleExecutionConfig;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;

@Slf4j
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BlackListScheduler implements Scheduler {
    private BlackList blackList;
    private BlackListService blackListService;
    private UserGameSessionService userGameSessionService;

    @Override
    public void execute() {
        try {
            processBlackList();
        } catch (Exception e) {
            log.error("BlackList execution failed for ID: {}", blackList.getId(), e);
            blackListService.updateBlackListStatus(blackList.getId(), BlackList.STATUSTYPE.FAIL);
        }
    }

    @Override
    public boolean isRepeatable() {
        return false;
    }

    @Override
    public ScheduleType getScheduleType() {
        return ScheduleType.DELAYED;
    }

    @Override
    public ScheduleExecutionConfig getSchedulerConfig() {
        return ScheduleExecutionConfig.builder()
                .taskId("blacklist-" + blackList.getId())
                .startTime(blackList.getStartDt())
                .endTime(blackList.getEndDt())
                .build();
    }

    private void processBlackList() {
        LocalDateTime nowDate = LocalDateTime.now();
        LocalDateTime startTime = blackList.getStartDt();
        LocalDateTime endTime = blackList.getEndDt();

        // 이미 지난시간이면 fail 처리
        if(nowDate.isAfter(endTime) && blackList.getStatus().equals(BlackList.STATUSTYPE.WAIT)) {
            blackListService.updateBlackListStatus(blackList.getId(), BlackList.STATUSTYPE.FAIL);
            log.error("blackListJob blackListSchedule timeOut : {}", blackList);
            return;
        }

        // 시작시간 지났으면 정지 처리
        if(!nowDate.isBefore(startTime) && blackList.getStatus().equals(BlackList.STATUSTYPE.WAIT)) {
            // user kick 처리
            userGameSessionService.kickUserSession(blackList.getGuid());
            blackListService.updateScheduleBlockUser(blackList, BlackList.STATUSTYPE.INPROGRESS);
            blackListService.updateBlackListStatus(blackList.getId(), BlackList.STATUSTYPE.INPROGRESS);
            log.info("blackListJob blackListSchedule block start : {}", blackList);
        }

        // 종료시간 지났으면 만료 처리
        if(!nowDate.isBefore(endTime) && blackList.getStatus().equals(BlackList.STATUSTYPE.INPROGRESS)) {
            blackListService.updateScheduleBlockUser(blackList, BlackList.STATUSTYPE.EXPIRATION);
            blackListService.updateBlackListStatus(blackList.getId(), BlackList.STATUSTYPE.EXPIRATION);
            log.info("blackListJob blackListSchedule block end : {}", blackList);
        }
    }
}
