package com.caliverse.admin.domain.service;

import com.caliverse.admin.domain.datacomponent.MetaDataHandler;
import com.caliverse.admin.domain.entity.ITEMLARGETYPE;
import com.caliverse.admin.domain.entity.SEARCHTYPE;
import com.caliverse.admin.domain.entity.log.LogAction;
import com.caliverse.admin.domain.response.ItemDeleteResponse;
import com.caliverse.admin.domain.response.UsersResponse;
import com.caliverse.admin.dynamodb.domain.atrrib.ItemAttrib;
import com.caliverse.admin.dynamodb.domain.doc.ItemDoc;
import com.caliverse.admin.dynamodb.dto.PageResult;
import com.caliverse.admin.dynamodb.service.DynamodbItemService;
import com.caliverse.admin.dynamodb.service.DynamodbUserService;
import com.caliverse.admin.global.common.annotation.BusinessProcess;
import com.caliverse.admin.global.common.annotation.RequestLog;
import com.caliverse.admin.global.common.code.ErrorCode;
import com.caliverse.admin.global.common.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import com.caliverse.admin.domain.request.ItemsRequest;
import com.caliverse.admin.domain.response.ItemsResponse;
import com.caliverse.admin.global.common.code.CommonCode;
import com.caliverse.admin.global.common.code.SuccessCode;

import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class ItemsService {

    private final UserGameSessionService userGameSessionService;
    private final DynamodbUserService dynamodbUserService;
    private final DynamodbItemService dynamodbItemService;
    private final MetaDataHandler metaDataHandler;

    @RequestLog
    public ItemsResponse findItems(ItemsRequest itemDeleteRequest){
        String guid = "";
        String searchData = itemDeleteRequest.getSearchData();

        if(itemDeleteRequest.getSearchType().equals(SEARCHTYPE.NAME)){
            guid = dynamodbUserService.getNameByGuid(searchData);
        }else{
            guid = dynamodbUserService.isUser(searchData) ? searchData: "";
        }

        if(guid.isEmpty()){
            return ItemsResponse.builder()
                    .status(CommonCode.ERROR.getHttpStatus())
                    .result(CommonCode.ERROR.getResult())
                    .resultData(ItemsResponse.ResultData.builder()
                            .message(ErrorCode.DYNAMODB_NOT_USER.name())
                            .build())
                    .build();
        }

        PageResult<ItemDoc> itemPageResult = dynamodbItemService.getItems(guid, itemDeleteRequest.getPageKey());
        List<ItemsResponse.Item> items = new ArrayList<>();
        String finalGuid = guid;
        itemPageResult.getItems().forEach(itemDoc -> {
            ItemAttrib attrib = CommonUtils.stringByObject(itemDoc.getAttribValue(), ItemAttrib.class);
            int itemId = attrib.getItemMetaId();
            String itemType = metaDataHandler.getMetaItemLargeTypeData(itemId);
            ItemsResponse.Item item = ItemsResponse.Item.builder()
                    .userGuid(finalGuid)
                    .itemGuid(attrib.getItemGuid())
                    .id(attrib.getItemGuid())
                    .itemId(itemId)
                    .itemName(metaDataHandler.getTextStringData(metaDataHandler.getMetaItemNameData(itemId)))
                    .count(attrib.getItemStackCount())
                    .level(attrib.getLevel())
                    .equipedPos(attrib.getEquipedPos())
                    .equipType(attrib.getEquipedIvenType())
                    .itemType(ITEMLARGETYPE.valueOf(itemType))
                    .createDt(itemDoc.getCreatedDateTime())
                    .build();
            items.add(item);
        });

        return ItemsResponse.builder()
                .resultData(ItemsResponse.ResultData.builder()
                        .itemList(items)
                        .pageKey(itemPageResult.getLastEvaluatedKey() == null ?
                                null :
                                itemPageResult.getLastEvaluatedKey().entrySet().stream()
                                        .collect(Collectors.toMap(
                                                Map.Entry::getKey,
                                                entry -> entry.getValue().s()
                                        ))
                        )
                        .build())
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .build();
    }

    @BusinessProcess(action = LogAction.ITEM)
    @Transactional(transactionManager = "transactionManager")
    @RequestLog
    public ItemDeleteResponse postItemDelete(ItemsRequest itemDeleteRequest){
        String userGuid = itemDeleteRequest.getUserGuid();
        String itemGuid = itemDeleteRequest.getItemGuid();
        int itemCount = itemDeleteRequest.getItemCount();
        int deleteCount = itemDeleteRequest.getDeleteCount();

        //UserKick
        userGameSessionService.kickUserSession(userGuid, "item delete");

        if(deleteCount >= itemCount){
            dynamodbItemService.deleteItem(userGuid, itemGuid);
        }else{
            int cnt = itemCount - deleteCount;
            dynamodbItemService.updateItemStack(userGuid, itemGuid, cnt);
        }

        return ItemDeleteResponse.builder()
                .status(CommonCode.SUCCESS.getHttpStatus())
                .result(CommonCode.SUCCESS.getResult())
                .resultData(ItemDeleteResponse.ResultData.builder()
                        .message(SuccessCode.DYNAMODB_ITEM_DELETE_SUCCESS.getMessage())
                        .deletedItemGuid(itemGuid)
                        .build())
                .build();

    }

}
