package com.caliverse.admin.domain.service;

import com.caliverse.admin.domain.dao.admin.WorldEventMapper;
import com.caliverse.admin.domain.entity.WorldEvent;
import com.caliverse.admin.domain.entity.log.LogAction;
import com.caliverse.admin.domain.request.WorldEventRequest;
import com.caliverse.admin.domain.response.WorldEventResponse;
import com.caliverse.admin.dynamodb.service.DynamodbRankService;
import com.caliverse.admin.dynamodb.service.DynamodbService;
import com.caliverse.admin.global.common.annotation.BusinessProcess;
import com.caliverse.admin.global.common.annotation.RequestLog;
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.utils.CommonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class WorldEventService {

    private final WorldEventMapper worldEventMapper;
    private final DynamodbService dynamodbService;

    @RequestLog
    public WorldEventResponse getList(Map requestParam){

        //페이징 처리
        requestParam = CommonUtils.pageSetting(requestParam);

        List<WorldEvent> list = worldEventMapper.getWorldEventList(requestParam);

        return WorldEventResponse.builder()
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .resultData(WorldEventResponse.ResultData.builder()
                        .worldEventList(list)
                        .total(worldEventMapper.getTotal())
                        .totalAll(list.size())
                        .pageNo(requestParam.get("page_no")!=null?
                                Integer.parseInt(requestParam.get("page_no").toString()):1)
                        .build()
                )
                .build();
    }

    @RequestLog
    public WorldEventResponse getDetail(Long id){
        WorldEvent worldEvent = worldEventMapper.getWorldEventDetail(id);

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

    @BusinessProcess(action = LogAction.WORLD_EVENT)
    @Transactional(transactionManager = "transactionManager")
    @RequestLog
    public WorldEventResponse postWorldEvent(WorldEventRequest worldEventRequest){
        worldEventRequest.setCreateBy(CommonUtils.getAdmin().getId());

        worldEventMapper.postWorldEvent(worldEventRequest);

        long event_id = worldEventRequest.getId();
        HashMap<String,String> map = new HashMap<>();
        map.put("id",String.valueOf(event_id));

        log.info("postWorldEvent Insert World Event id: {}", worldEventRequest.getId());

        WorldEvent worldEvent = worldEventMapper.getWorldEventDetail(worldEventRequest.getId());

        dynamodbService.insertWorldEventSchedule(worldEventRequest);

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

    @BusinessProcess(action = LogAction.WORLD_EVENT)
    @Transactional(transactionManager = "transactionManager")
    @RequestLog
    public WorldEventResponse updateWorldEvent(Long id, WorldEventRequest worldEventRequest) {
        worldEventRequest.setId(id);
        worldEventRequest.setUpdateBy(CommonUtils.getAdmin().getId());
        worldEventRequest.setUpdateDt(LocalDateTime.now());

        Long event_id = worldEventRequest.getId();
        WorldEvent before_info = worldEventMapper.getWorldEventDetail(event_id);

        worldEventMapper.updateWorldEvent(worldEventRequest);

        log.info("updateWorldEvent Update World Event Complete: {}", worldEventRequest.getId());

        WorldEvent after_info = worldEventMapper.getWorldEventDetail(event_id);

        dynamodbService.updateWorldEventSchedule(worldEventRequest);

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

    @BusinessProcess(action = LogAction.WORLD_EVENT)
    @Transactional(transactionManager = "transactionManager")
    @RequestLog
    public WorldEventResponse deleteWorldEvent(Long id){
        Map<String,Object> map = new HashMap<>();
        map.put("id",id);

        WorldEvent worldEvent = worldEventMapper.getWorldEventDetail(id);

        if(worldEvent.getStartDt().isBefore(LocalDateTime.now())){
            return WorldEventResponse.builder()
                    .status(CommonCode.ERROR.getHttpStatus())
                    .result(CommonCode.ERROR.getResult())
                    .resultData(WorldEventResponse.ResultData.builder()
                            .message(ErrorCode.START_DATE_OVER.getMessage())
                            .build())
                    .build();
        }

        worldEventMapper.deleteWorldEvent(map);

        log.info("deleteWorldEvent Delete World Event Complete id: {}", id);

        dynamodbService.deleteWorldEventSchedule(worldEvent);

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

}
