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

import com.caliverse.admin.domain.entity.BlackList;
import com.caliverse.admin.domain.entity.HISTORYTYPE;
import com.caliverse.admin.dynamodb.domain.atrrib.AccountBaseAttrib;
import com.caliverse.admin.dynamodb.domain.atrrib.LandAuctionRegistryAttrib;
import com.caliverse.admin.dynamodb.domain.atrrib.UserNicknameRegistryAttrib;
import com.caliverse.admin.dynamodb.domain.doc.AccountBaseDoc;
import com.caliverse.admin.dynamodb.domain.doc.LandAuctionRegistryDoc;
import com.caliverse.admin.dynamodb.domain.doc.UserNicknameRegistryDoc;
import com.caliverse.admin.dynamodb.repository.AccountBaseRepository;
import com.caliverse.admin.dynamodb.repository.BaseDynamoDBRepository;
import com.caliverse.admin.dynamodb.repository.UserNicknameRegistryRepository;
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.CommonConstants;
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.history.service.DynamodbHistoryLogService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.enhanced.dynamodb.Key;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.caliverse.admin.global.common.utils.DateUtils.getDynamodbDateFormat;

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

    @Override
    public boolean isBlockUser(String account_id) {
        Key key = Key.builder()
                .partitionValue(DynamoDBConstants.PK_KEY_ACCOUNT_BASE + account_id)
                .sortValue(DynamoDBConstants.EMPTY)
                .build();

        AccountBaseDoc doc = findById(key);

        try {
            AccountBaseAttrib attrib =  objectMapper.readValue(doc.getAttribValue(), AccountBaseAttrib.class);
            List<String> block_policy = attrib.getBlockPolicy();
            return !block_policy.isEmpty();
        } catch (JsonProcessingException e) {
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DYNAMODB_CONNECTION_ERROR.getMessage());
        }
    }

    @Override
    public void updateBlockUserStart(String account_id, BlackList blackList) {
        try {
            Key key = Key.builder()
                    .partitionValue(DynamoDBConstants.PK_KEY_ACCOUNT_BASE + account_id)
                    .sortValue(DynamoDBConstants.EMPTY)
                    .build();

            AccountBaseDoc beforeDoc = findById(key);

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

                List<String> block_policy = new ArrayList<>();
                block_policy.add(blackList.getType().toString());

                AccountBaseAttrib attrib = objectMapper.readValue(afterDoc.getAttribValue(), AccountBaseAttrib.class);
                attrib.setBlockStartDateTime(getDynamodbDateFormat(blackList.getStartDt()));
                attrib.setBlockEndDateTime(getDynamodbDateFormat(blackList.getEndDt()));
                attrib.setBlockPolicy(block_policy);
                attrib.setBlockReason(blackList.getSanctions().toString());

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

                update(afterDoc);

                log.info("updateBlockUserStart Update Success: {}", objectMapper.writeValueAsString(afterDoc));

                dynamodbHistoryLogService.updateHistoryLog(
                        HISTORYTYPE.BLACKLIST_UPDATE,
                        HISTORYTYPE.BLACKLIST_UPDATE.name(),
                        beforeDoc,
                        afterDoc
                );
            }
        }catch (Exception e){
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DYNAMODB_CONNECTION_ERROR.getMessage());
        }
    }

    @Override
    public void updateBlockUserEnd(String account_id) {
        try {
            Key key = Key.builder()
                    .partitionValue(DynamoDBConstants.PK_KEY_ACCOUNT_BASE + account_id)
                    .sortValue(DynamoDBConstants.EMPTY)
                    .build();

            AccountBaseDoc beforeDoc = findById(key);

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

                String max_date = getDynamodbDateFormat(LocalDateTime.of(9999, 12, 31, 23, 59, 59, 999999900));

                AccountBaseAttrib attrib = objectMapper.readValue(afterDoc.getAttribValue(), AccountBaseAttrib.class);
                attrib.setBlockStartDateTime(max_date);
                attrib.setBlockEndDateTime(max_date);
                attrib.setBlockPolicy(new ArrayList<>());
                attrib.setBlockReason("");

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

                update(afterDoc);

                log.info("updateBlockUserEnd Update Success: {}", objectMapper.writeValueAsString(afterDoc));

                dynamodbHistoryLogService.updateHistoryLog(
                        HISTORYTYPE.BLACKLIST_UPDATE,
                        HISTORYTYPE.BLACKLIST_UPDATE.name(),
                        beforeDoc,
                        afterDoc
                );
            }
        }catch (Exception e){
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DYNAMODB_CONNECTION_ERROR.getMessage());
        }
    }

    @Override
    public AccountBaseAttrib findUser(Long account_id) {
        Key key = Key.builder()
                .partitionValue(DynamoDBConstants.PK_KEY_ACCOUNT_BASE + account_id)
                .sortValue(DynamoDBConstants.EMPTY)
                .build();

        AccountBaseDoc doc = findById(key);

        try {
            return objectMapper.readValue(doc.getAttribValue(), AccountBaseAttrib.class);
        } catch (JsonProcessingException e) {
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DYNAMODB_CONNECTION_ERROR.getMessage());
        }
    }
}
