package com.caliverse.admin.dynamodb.repository.Impl;

import com.caliverse.admin.domain.entity.EFilterOperator;
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.repository.BaseDynamoDBRepository;
import com.caliverse.admin.dynamodb.repository.ItemRepository;
import com.caliverse.admin.dynamodb.service.DynamoDBOperations;
import com.caliverse.admin.global.common.code.CommonCode;
import com.caliverse.admin.global.common.code.ErrorCode;
import com.caliverse.admin.global.common.constants.DynamoDBConstants;
import com.caliverse.admin.global.common.exception.RestApiException;
import com.caliverse.admin.global.common.utils.CommonUtils;
import com.caliverse.admin.mongodb.service.DynamodbHistoryLogService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.enhanced.dynamodb.Key;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;

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


@Component
@Slf4j
public class ItemRepositoryImpl extends BaseDynamoDBRepository<ItemDoc> implements ItemRepository {
    public ItemRepositoryImpl(DynamoDBOperations operations, DynamodbHistoryLogService dynamodbHistoryLogService, ObjectMapper objectMapper) {
        super(operations, ItemDoc.class, dynamodbHistoryLogService, objectMapper);
    }

    @Override
    public PageResult<ItemDoc> getItemListWithPaging(
            String userGuid,
            String sortKeyPrefix,
            String filterAttributeName,
            EFilterOperator filterOperator,
            String filterAttributeValue,
            Map<String, AttributeValue> exclusiveStartKey,
            boolean sortIndex
    ) {

        String pk = DynamoDBConstants.PK_KEY_ITEM + userGuid;;

        return findByPaging(
                pk,
                sortKeyPrefix,
                filterAttributeName,
                filterOperator,
                filterAttributeValue,
                exclusiveStartKey,
                sortIndex
        );
    }

    @Override
    public void updateItemStack(String guid, String itemGuid, int stackCount) {
        try {
            Key key = Key.builder()
                    .partitionValue(DynamoDBConstants.PK_KEY_ITEM + guid)
                    .sortValue(itemGuid)
                    .build();

            ItemDoc beforeDoc = findById(key);

            if (beforeDoc != null) {
                ItemDoc afterDoc = deepCopy(beforeDoc, ItemDoc.class);

                ItemAttrib attrib = CommonUtils.stringByObject(afterDoc.getAttribValue(), ItemAttrib.class);
                attrib.setItemStackCount(stackCount);

                afterDoc.setAttribValue(CommonUtils.objectByString(attrib));
                afterDoc.setUpdatedDateTime(CommonUtils.convertUTCDate(LocalDateTime.now()));

                update(afterDoc);

                log.info("updateItemStack Update Success: {}", CommonUtils.objectByString(afterDoc));

            }
        }catch (Exception e){
            log.error("Update Item Error: {}", e.getMessage());
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DYNAMODB_ITEM_UPDATE_ERROR.getMessage());
        }
    }

    @Override
    public void deleteItem(String guid, String itemGuid) {
        try {
            Key key = Key.builder()
                    .partitionValue(DynamoDBConstants.PK_KEY_ITEM + guid)
                    .sortValue(itemGuid)
                    .build();

            ItemDoc beforeDoc = findById(key);

            if (beforeDoc != null) {
                delete(key);

                log.info("ItemDoc Delete Success: {}", CommonUtils.objectByString(beforeDoc));

            }
        }catch (Exception e){
            log.error("Update LandAuctionRegistry Error: {}", e.getMessage());
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DYNAMODB_ITEM_DELETE_ERROR.getMessage());
        }
    }
}
