package com.caliverse.admin.domain.service;

import com.caliverse.admin.domain.dao.admin.BattleMapper;
import com.caliverse.admin.domain.datacomponent.MetaDataHandler;
import com.caliverse.admin.domain.entity.BattleEvent;
import com.caliverse.admin.domain.entity.HISTORYTYPE;
import com.caliverse.admin.domain.entity.metadata.MetaBattleConfigData;
import com.caliverse.admin.domain.entity.metadata.MetaBattleRewardData;
import com.caliverse.admin.domain.request.BattleEventRequest;
import com.caliverse.admin.domain.response.BattleEventResponse;
import com.caliverse.admin.dynamodb.service.DynamodbBattleEventService;
import com.caliverse.admin.global.common.code.CommonCode;
import com.caliverse.admin.global.common.code.ErrorCode;
import com.caliverse.admin.global.common.code.SuccessCode;
import com.caliverse.admin.global.common.constants.CommonConstants;
import com.caliverse.admin.global.common.constants.MysqlConstants;
import com.caliverse.admin.global.common.utils.CommonUtils;
import com.caliverse.admin.history.service.MysqlHistoryLogService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

@Service
@RequiredArgsConstructor
@Slf4j
public class BattleEventService {

    private final DynamodbBattleEventService dynamodbBattleEventService;

    private final BattleMapper battleMapper;
    private final MetaDataHandler metaDataHandler;
    private final HistoryService historyService;
    private final ObjectMapper objectMapper;
    private final MysqlHistoryLogService mysqlHistoryLogService;

    //전투시스템 설정 데이터
    public BattleEventResponse getBattleConfigList(){

        List<MetaBattleConfigData> list = metaDataHandler.getMetaBattleConfigsListData();

        return BattleEventResponse.builder()
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .resultData(BattleEventResponse.ResultData.builder()
                        .battleConfigList(list)
                        .build()
                )
                .build();
    }

    //전투시스템 보상 데이터
    public BattleEventResponse getBattleRewardList(){

        List<MetaBattleRewardData> list = metaDataHandler.getMetaBattleRewardsListData();

        return BattleEventResponse.builder()
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .resultData(BattleEventResponse.ResultData.builder()
                        .battleRewardList(list)
                        .build()
                )
                .build();
    }

    // 전투시스템 이벤트 조회
    public BattleEventResponse getBattleEventList(@RequestParam Map<String, String> requestParam){

        requestParam = CommonUtils.pageSetting(requestParam);

        List<BattleEvent> list = battleMapper.getBattleEventList(requestParam);

        int allCnt = battleMapper.getAllCnt(requestParam);

        return BattleEventResponse.builder()
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .resultData(BattleEventResponse.ResultData.builder()
                        .battleEventList(list)
                        .total(battleMapper.getTotal())
                        .totalAll(allCnt)
                        .pageNo(requestParam.get("page_no")!=null?
                                Integer.parseInt(requestParam.get("page_no")):1)
                        .build()
                )
                .build();
    }

    // 전투시스템 이벤트 상세조회
    public BattleEventResponse getBattleEventDetail(Long id){

        BattleEvent battleEvent = battleMapper.getBattleEventDetail(id);

        return BattleEventResponse.builder()
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .resultData(BattleEventResponse.ResultData.builder()
                        .battleEvent(battleEvent)
                        .build())
                .build();
    }

    @Transactional(transactionManager = "transactionManager")
    public BattleEventResponse postBattleEvent(BattleEventRequest battleEventRequest){
        if(battleEventRequest.getRepeatType().equals(BattleEvent.BATTLE_REPEAT_TYPE.NONE)){
            LocalDateTime start_dt = battleEventRequest.getEventStartDt();
            LocalDateTime end_dt = start_dt.plusHours(12);
            battleEventRequest.setEventEndDt(end_dt);
        }else{
            // 일자만 필요해서 UTC시간으로 변경되다보니 한국시간(+9)을 더해서 마지막시간으로 설정
            LocalDateTime end_dt_kst = battleEventRequest.getEventEndDt()
                    .plusHours(9)
                    .withHour(23)
                    .withMinute(59)
                    .withSecond(59)
                    .withNano(0);
            battleEventRequest.setEventEndDt(end_dt_kst);
        }
        battleEventRequest.setInstanceId(CommonConstants.BATTLE_INSTANCE_ID);  //고정값으로 넣고 추후 맵정보가 늘어나면 선택하는 걸로

        int operation_time = calcEndTime(battleEventRequest);
        battleEventRequest.setEventOperationTime(operation_time);

//        int is_time = battleMapper.chkTimeOver(battleEventRequest);
        List<BattleEvent> existingList = battleMapper.getCheckBattleEventList(battleEventRequest);
        boolean isTime = isTimeOverlapping(existingList, battleEventRequest);
        if(isTime){
            log.warn("battle Schedule duplication start_dt: {}, end_dt: {}, operation_time: {}", battleEventRequest.getEventStartDt(), battleEventRequest.getEventEndDt(), operation_time);
            return BattleEventResponse.builder()
                    .status(CommonCode.ERROR.getHttpStatus())
                    .result(ErrorCode.ERROR_BATTLE_EVENT_TIME_OVER.toString())
                    .build();
        }

        int next_event_id = dynamodbBattleEventService.getEventId() + 1;
        battleEventRequest.setEventId(next_event_id);

        int result = battleMapper.postBattleEvent(battleEventRequest);
        log.info("AdminToolDB BattleEvent Save: {}", battleEventRequest);

        long battle_event_id = battleEventRequest.getId();

        HashMap<String,String> map = new HashMap<>();
        map.put("id",String.valueOf(battle_event_id));

        BattleEvent event_info = battleMapper.getBattleEventDetail(battle_event_id);

        mysqlHistoryLogService.insertHistoryLog(
                HISTORYTYPE.BATTLE_EVENT_ADD,
                MysqlConstants.TABLE_NAME_BATTLE_EVENT,
                HISTORYTYPE.BATTLE_EVENT_ADD.name(),
                event_info,
                CommonUtils.getAdmin().getEmail(),
                CommonUtils.getClientIp()
        );

        dynamodbBattleEventService.insertBattleEvent(battleEventRequest);

        return BattleEventResponse.builder()
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .resultData(BattleEventResponse.ResultData.builder()
                        .message(SuccessCode.SAVE.getMessage())
                        .build())
                .build();
    }

    @Transactional(transactionManager = "transactionManager")
    public BattleEventResponse updateBattleEvent(Long id, BattleEventRequest battleEventRequest) {
        battleEventRequest.setId(id);
        battleEventRequest.setUpdateBy(CommonUtils.getAdmin().getId());
        battleEventRequest.setUpdateDt(LocalDateTime.now());

        BattleEvent before_info = battleMapper.getBattleEventDetail(id);

        if(!before_info.getStatus().equals(BattleEvent.BATTLE_STATUS.STOP)){
            return BattleEventResponse.builder()
                    .status(CommonCode.ERROR.getHttpStatus())
                    .result(ErrorCode.ERROR_BATTLE_EVENT_STATUS_IMPOSSIBLE.toString())
                    .build();
        }

        List<BattleEvent> existingList = battleMapper.getCheckBattleEventList(battleEventRequest);
        boolean isTime = isTimeOverlapping(existingList, battleEventRequest);
        if(isTime){
            return BattleEventResponse.builder()
                    .status(CommonCode.ERROR.getHttpStatus())
                    .result(ErrorCode.ERROR_BATTLE_EVENT_TIME_OVER.toString())
                    .build();
        }

        int operation_time = calcEndTime(battleEventRequest);
        battleEventRequest.setEventOperationTime(operation_time);

        // 일자만 필요해서 UTC시간으로 변경되다보니 한국시간(+9)을 더해서 마지막시간으로 설정
        LocalDateTime end_dt_kst = battleEventRequest.getEventEndDt()
                .plusHours(9)
                .withHour(23)
                .withMinute(59)
                .withSecond(59)
                .withNano(0);
        battleEventRequest.setEventEndDt(end_dt_kst);

        int result = battleMapper.updateBattleEvent(battleEventRequest);
        log.info("AdminToolDB BattleEvent Update Complete: {}", battleEventRequest);

        Map<String, String> map = new HashMap<>();
        map.put("id", String.valueOf(id));

        BattleEvent after_info = battleMapper.getBattleEventDetail(id);

        mysqlHistoryLogService.updateHistoryLog(
                HISTORYTYPE.BATTLE_EVENT_UPDATE,
                MysqlConstants.TABLE_NAME_BATTLE_EVENT,
                HISTORYTYPE.BATTLE_EVENT_UPDATE.name(),
                before_info,
                after_info,
                CommonUtils.getAdmin().getEmail(),
                CommonUtils.getClientIp()
        );

        dynamodbBattleEventService.updateBattleEvent(battleEventRequest);

        return BattleEventResponse.builder()
                .resultData(BattleEventResponse.ResultData.builder()
                        .build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }

    @Transactional(transactionManager = "transactionManager")
    public BattleEventResponse updateStopBattleEvent(Long id){
        Map<String,Object> map = new HashMap<>();

        BattleEvent info = battleMapper.getBattleEventDetail(id);

        if(info.getStatus().equals(BattleEvent.BATTLE_STATUS.RUNNING)){
            return BattleEventResponse.builder()
                    .status(CommonCode.ERROR.getHttpStatus())
                    .result(ErrorCode.ERROR_BATTLE_EVENT_STATUS_START_IMPOSSIBLE.toString())
                    .build();
        }

        map.put("id", id);
        map.put("status", BattleEvent.BATTLE_STATUS.STOP);
        map.put("updateBy", CommonUtils.getAdmin().getId());
        int result = battleMapper.updateStatusBattleEvent(map);
        try{
            log.info("BattleEvent Stop Complete: {}", objectMapper.writeValueAsString(info));
        }catch(Exception e){
            log.error("BattleEvent Stop Failed: {}", e.getMessage());
        }

        mysqlHistoryLogService.updateHistoryLog(
                HISTORYTYPE.BATTLE_EVENT_UPDATE,
                MysqlConstants.TABLE_NAME_BATTLE_EVENT,
                HISTORYTYPE.BATTLE_EVENT_UPDATE.name(),
                info,
                battleMapper.getBattleEventDetail(id),
                CommonUtils.getAdmin().getEmail(),
                CommonUtils.getClientIp()
        );

        dynamodbBattleEventService.updateStopBattleEvent(info);

        return BattleEventResponse.builder()
                .resultData(BattleEventResponse.ResultData.builder()
                        .build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }

    @Transactional(transactionManager = "transactionManager")
    public BattleEventResponse deleteBattleEvent(BattleEventRequest battleEventRequest){
        Map<String,Object> map = new HashMap<>();
        AtomicBoolean is_falil = new AtomicBoolean(false);

        battleEventRequest.getList().forEach(
                item->{
                    Long id = item.getId();
                    BattleEvent info = battleMapper.getBattleEventDetail(id);

                    if(!info.getStatus().equals(BattleEvent.BATTLE_STATUS.STOP)){
                        is_falil.set(true);
                        return;
                    }

                    map.put("id", id);
                    map.put("updateBy", CommonUtils.getAdmin().getId());
                    int result = battleMapper.deleteBattleEvent(map);
                    log.info("BattleEvent Delete Complete: {}", item);

                    mysqlHistoryLogService.deleteHistoryLog(
                            HISTORYTYPE.BATTLE_EVENT_DELETE,
                            MysqlConstants.TABLE_NAME_BATTLE_EVENT,
                            HISTORYTYPE.BATTLE_EVENT_DELETE.name(),
                            info,
                            CommonUtils.getAdmin().getEmail(),
                            CommonUtils.getClientIp()
                    );

//                    dynamodbLandAuctionService.cancelLandAuction(auction_info);
                }
        );

        if(is_falil.get()){
            return BattleEventResponse.builder()
                    .status(CommonCode.ERROR.getHttpStatus())
                    .result(ErrorCode.ERROR_AUCTION_STATUS_IMPOSSIBLE.toString())
                    .build();
        }

        return BattleEventResponse.builder()
                .resultData(BattleEventResponse.ResultData.builder()
                        .build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }

    public List<BattleEvent> getScheduleBattleEventList(){
        return battleMapper.getScheduleBattleEventList();
    }

    @Transactional(transactionManager = "transactionManager")
    public void updateBattleEventStatus(Map<String,Object> map){
        try{
            battleMapper.updateStatusBattleEvent(map);
            log.info("BattleEvent status changed: {}", map.get("status"));
        }catch(Exception e){
            log.error("BattleEvent Status Update Fail map: {}", map);
        }
    }

    // 이벤트 동작 시간 계산
    private int calcEndTime(BattleEventRequest battleEventRequest){
        MetaBattleConfigData config = metaDataHandler.getMetaBattleConfigsListData().stream()
                .filter(data -> data.getId().equals(battleEventRequest.getConfigId()))
                .findFirst()
                .orElse(null);
        if(config == null) return 0;

        int round_time = battleEventRequest.getRoundTime();
        int round_count = battleEventRequest.getRoundCount();
        int round_wait_time = config.getNextRoundWaitTime();
        int result_wait_time = config.getResultUIWaitTime();
        int server_wait_time = CommonConstants.BATTLE_SERVER_WAIT_TIME;

        int total_time = round_time + ((round_count - 1) * (round_time + round_wait_time)) + result_wait_time + server_wait_time;

        return total_time;  // 초
    }

    private boolean isTimeOverlapping(List<BattleEvent> existingList, BattleEventRequest battleEventRequest){
        LocalDateTime newStartDt = battleEventRequest.getEventStartDt();
        LocalDateTime newEndDt = battleEventRequest.getEventEndDt();
        LocalDate newStartDate = newStartDt.toLocalDate();
        LocalDate newEndDate = newEndDt.toLocalDate();
        LocalTime newStartTime = newStartDt.toLocalTime();
        LocalTime newEndTime = newStartTime.plusSeconds(battleEventRequest.getEventOperationTime());
        BattleEvent.BATTLE_REPEAT_TYPE newRepeatType = battleEventRequest.getRepeatType();

        return existingList.stream().anyMatch(existingEvent -> {
            // 자기 자신은 제외 (수정 시)
            if (battleEventRequest.getId() != null && battleEventRequest.getId().equals(existingEvent.getId())) {
                return false;
            }

            // 기존 이벤트 정보
            LocalDateTime existingStartDt = existingEvent.getEventStartDt();
            LocalDateTime existingEndDt = existingEvent.getEventEndDt();
            LocalDate existingStartDate = existingStartDt.toLocalDate();
            LocalDate existingEndDate = existingEndDt.toLocalDate();
            LocalTime existingStartTime = existingStartDt.toLocalTime();
            LocalTime existingEndTime = existingStartTime.plusSeconds(existingEvent.getEventOperationTime());
            BattleEvent.BATTLE_REPEAT_TYPE existingRepeatType = existingEvent.getRepeatType();

            // 1. 두 이벤트가 모두 NONE 타입인 경우
            if (newRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.NONE &&
                    existingRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.NONE) {
                // 같은 날짜인지 확인
                if (newStartDate.equals(existingStartDate)) {
                    // 시간이 겹치는지 확인
                    return !existingStartTime.isAfter(newEndTime) && !newStartTime.isAfter(existingEndTime);
                }
                return false;
            }

            // 2. NONE 타입과 DAY 타입 간의 중복 체크
            if (newRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.NONE &&
                    existingRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.DAY) {
                // NONE 이벤트의 날짜가 DAY 이벤트의 기간 내에 있는지 확인
                if (isDateInRange(newStartDate, existingStartDate, existingEndDate)) {
                    // 시간이 겹치는지 확인
                    return !existingStartTime.isAfter(newEndTime) && !newStartTime.isAfter(existingEndTime);
                }
                return false;
            }

            // 3. DAY 타입과 NONE 타입 간의 중복 체크
            if (newRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.DAY &&
                    existingRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.NONE) {
                // NONE 이벤트의 날짜가 DAY 이벤트의 기간 내에 있는지 확인
                if (isDateInRange(existingStartDate, newStartDate, newEndDate)) {
                    // 시간이 겹치는지 확인
                    return !existingStartTime.isAfter(newEndTime) && !newStartTime.isAfter(existingEndTime);
                }
                return false;
            }

            // 4. 두 이벤트가 모두 DAY 타입인 경우
            if (newRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.DAY &&
                    existingRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.DAY) {
                // 날짜 범위가 겹치는지 확인
                if (datesOverlap(newStartDate, newEndDate, existingStartDate, existingEndDate)) {
                    // 시간이 겹치는지 확인
                    return !existingStartTime.isAfter(newEndTime) && !newStartTime.isAfter(existingEndTime);
                }
                return false;
            }

            // 5. NONE 타입과 요일 타입 간의 중복 체크
            if (newRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.NONE &&
                    isWeekdayType(existingRepeatType)) {
                // NONE 이벤트의 날짜가 요일 이벤트의 기간 내에 있는지 확인
                if (isDateInRange(newStartDate, existingStartDate, existingEndDate)) {
                    // NONE 이벤트의 요일이 요일 이벤트의 요일과 일치하는지 확인
                    DayOfWeek noneDayOfWeek = newStartDate.getDayOfWeek();
                    DayOfWeek weekdayType = getDayOfWeekFromRepeatType(existingRepeatType);

                    if (noneDayOfWeek == weekdayType) {
                        // 시간이 겹치는지 확인
                        return !existingStartTime.isAfter(newEndTime) && !newStartTime.isAfter(existingEndTime);
                    }
                }
                return false;
            }

            // 6. 요일 타입과 NONE 타입 간의 중복 체크
            if (isWeekdayType(newRepeatType) &&
                    existingRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.NONE) {
                // NONE 이벤트의 날짜가 요일 이벤트의 기간 내에 있는지 확인
                if (isDateInRange(existingStartDate, newStartDate, newEndDate)) {
                    // NONE 이벤트의 요일이 요일 이벤트의 요일과 일치하는지 확인
                    DayOfWeek noneDayOfWeek = existingStartDate.getDayOfWeek();
                    DayOfWeek weekdayType = getDayOfWeekFromRepeatType(newRepeatType);

                    if (noneDayOfWeek == weekdayType) {
                        // 시간이 겹치는지 확인
                        return !existingStartTime.isAfter(newEndTime) && !newStartTime.isAfter(existingEndTime);
                    }
                }
                return false;
            }

            // 7. DAY 타입과 요일 타입 간의 중복 체크
            if (newRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.DAY &&
                    isWeekdayType(existingRepeatType)) {
                // 날짜 범위가 겹치는지 확인
                if (datesOverlap(newStartDate, newEndDate, existingStartDate, existingEndDate)) {
                    // 날짜 범위 내에 해당 요일이 적어도 하나 있는지 확인
                    if (hasOverlappingWeekday(newStartDate, newEndDate, existingStartDate, existingEndDate, getDayOfWeekFromRepeatType(existingRepeatType))) {
                        // 시간이 겹치는지 확인
                        return !existingStartTime.isAfter(newEndTime) && !newStartTime.isAfter(existingEndTime);
                    }
                }
                return false;
            }

            // 8. 요일 타입과 DAY 타입 간의 중복 체크
            if (isWeekdayType(newRepeatType) &&
                    existingRepeatType == BattleEvent.BATTLE_REPEAT_TYPE.DAY) {
                // 날짜 범위가 겹치는지 확인
                if (datesOverlap(newStartDate, newEndDate, existingStartDate, existingEndDate)) {
                    // 날짜 범위 내에 해당 요일이 적어도 하나 있는지 확인
                    if (hasOverlappingWeekday(newStartDate, newEndDate, existingStartDate, existingEndDate, getDayOfWeekFromRepeatType(newRepeatType))) {
                        // 시간이 겹치는지 확인
                        return !existingStartTime.isAfter(newEndTime) && !newStartTime.isAfter(existingEndTime);
                    }
                }
                return false;
            }

            // 9. 두 이벤트가 모두 요일 타입인 경우
            if (isWeekdayType(newRepeatType) && isWeekdayType(existingRepeatType)) {
                // 같은 요일인지 확인
                if (newRepeatType == existingRepeatType) {
                    // 날짜 범위가 겹치는지 확인
                    if (datesOverlap(newStartDate, newEndDate, existingStartDate, existingEndDate)) {
                        // 시간이 겹치는지 확인
                        return !existingStartTime.isAfter(newEndTime) && !newStartTime.isAfter(existingEndTime);
                    }
                }
                return false;
            }

            return false;
        });
    }

    private boolean isDateInRange(LocalDate date, LocalDate rangeStart, LocalDate rangeEnd) {
        return !date.isBefore(rangeStart) && !date.isAfter(rangeEnd);
    }

    private boolean datesOverlap(LocalDate start1, LocalDate end1, LocalDate start2, LocalDate end2) {
        return !start1.isAfter(end2) && !start2.isAfter(end1);
    }

    private boolean isWeekdayType(BattleEvent.BATTLE_REPEAT_TYPE repeatType) {
        return repeatType == BattleEvent.BATTLE_REPEAT_TYPE.SUNDAY ||
                repeatType == BattleEvent.BATTLE_REPEAT_TYPE.MONDAY ||
                repeatType == BattleEvent.BATTLE_REPEAT_TYPE.TUESDAY ||
                repeatType == BattleEvent.BATTLE_REPEAT_TYPE.WEDNESDAY ||
                repeatType == BattleEvent.BATTLE_REPEAT_TYPE.THURSDAY ||
                repeatType == BattleEvent.BATTLE_REPEAT_TYPE.FRIDAY ||
                repeatType == BattleEvent.BATTLE_REPEAT_TYPE.SATURDAY;
    }

    private DayOfWeek getDayOfWeekFromRepeatType(BattleEvent.BATTLE_REPEAT_TYPE repeatType) {
        switch (repeatType) {
            case MONDAY: return DayOfWeek.MONDAY;
            case TUESDAY: return DayOfWeek.TUESDAY;
            case WEDNESDAY: return DayOfWeek.WEDNESDAY;
            case THURSDAY: return DayOfWeek.THURSDAY;
            case FRIDAY: return DayOfWeek.FRIDAY;
            case SATURDAY: return DayOfWeek.SATURDAY;
            case SUNDAY: return DayOfWeek.SUNDAY;
            default: throw new IllegalArgumentException("Invalid repeat type: " + repeatType);
        }
    }

    private boolean hasOverlappingWeekday(
            LocalDate start1, LocalDate end1,
            LocalDate start2, LocalDate end2,
            DayOfWeek dayOfWeek) {

        // 두 범위의 교집합 계산
        LocalDate overlapStart = start1.isAfter(start2) ? start1 : start2;
        LocalDate overlapEnd = end1.isBefore(end2) ? end1 : end2;

        if (overlapStart.isAfter(overlapEnd)) {
            return false; // 겹치는 날짜 범위 없음
        }

        // 겹치는 날짜 범위 내에 해당 요일이 있는지 확인
        LocalDate current = overlapStart;
        while (!current.isAfter(overlapEnd)) {
            if (current.getDayOfWeek() == dayOfWeek) {
                return true; // 해당 요일 발견
            }
            current = current.plusDays(1);
        }

        return false; // 해당 요일 없음
    }
}
