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

import com.caliverse.admin.domain.entity.HISTORYTYPE;
import com.caliverse.admin.dynamodb.domain.atrrib.OwnedBuildingAttrib;
import com.caliverse.admin.dynamodb.domain.doc.OwnedBuildingDoc;
import com.caliverse.admin.dynamodb.entity.EOwnedType;
import com.caliverse.admin.dynamodb.entity.DynamodbOperationResult;
import com.caliverse.admin.dynamodb.repository.BaseDynamoDBRepository;
import com.caliverse.admin.dynamodb.repository.OwnedBuildingRepository;
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.history.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 java.time.LocalDateTime;

import static com.caliverse.admin.global.common.utils.CommonUtils.convertUTCDate;

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

    @Override
    public OwnedBuildingDoc findOwnedBuilding(String guid, Integer buildingId) {
        Key key = Key.builder()
                .partitionValue(DynamoDBConstants.PK_KEY_OWNED_BUILDING + guid)
                .sortValue(String.valueOf(buildingId))
                .build();

        return findById(key);
    }

    @Override
    public void insert(String guid, Integer buildingId) {
        OwnedBuildingDoc ownedBuilding = findOwnedBuilding(guid, buildingId);
        if (ownedBuilding != null){
            log.warn("OwnedBuilding guid: {}, buildingId: {} Exist", guid, buildingId);
            return;
        }

        try {
            LocalDateTime nowDate = LocalDateTime.now();

            String pk = DynamoDBConstants.PK_KEY_OWNED_BUILDING + guid;

            OwnedBuildingAttrib attrib = new OwnedBuildingAttrib();
            attrib.setAttribType(DynamoDBConstants.ATTRIB_OWNED_BUILDING);
            attrib.setBuildingMetaId(buildingId);
            attrib.setOwnedType(EOwnedType.Own.getValue());

            OwnedBuildingDoc doc = new OwnedBuildingDoc();
            doc.setPK(pk);
            doc.setSK(String.valueOf(buildingId));
            doc.setDocType(DynamoDBConstants.DOC_OWNED_BUILDING);
            doc.setAttribValue(objectMapper.writeValueAsString(attrib));
            doc.setCreatedDateTime(convertUTCDate(nowDate));
            doc.setUpdatedDateTime(convertUTCDate(nowDate));
            doc.setDeletedDateTime(DynamoDBConstants.MIN_DATE);
            doc.setRestoredDateTime(DynamoDBConstants.MIN_DATE);

            save(doc);

            log.info("OwnedBuildingDoc Insert Success: {}", objectMapper.writeValueAsString(doc));

            dynamodbHistoryLogService.insertHistoryLog(
                    HISTORYTYPE.LAND_OWNER_CHANGE_ADD,
                    HISTORYTYPE.LAND_OWNER_CHANGE_ADD.name(),
                    doc
            );

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

    @Override
    public void delete(String guid, Integer buildingId) {
        try{
            Key key = Key.builder()
                    .partitionValue(DynamoDBConstants.PK_KEY_OWNED_BUILDING + guid)
                    .sortValue(String.valueOf(buildingId))
                    .build();

            OwnedBuildingDoc doc = findById(key);

            delete(key);

            log.info("OwnedBuildingDoc Delete Success: {}", objectMapper.writeValueAsString(doc));

            dynamodbHistoryLogService.deleteHistoryLog(
                    HISTORYTYPE.LAND_OWNER_CHANGE_UPDATE,
                    HISTORYTYPE.LAND_OWNER_CHANGE_UPDATE.name(),
                    doc
            );
        }catch (Exception e){
            log.error("delete Error: {}", e.getMessage());
            throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DYNAMODB_CONNECTION_ERROR.getMessage());
        }
    }

    @Override
    public DynamodbOperationResult initOwnedBuilding(String guid, Integer buildingId) {
        try{
            Key key = Key.builder()
                    .partitionValue(DynamoDBConstants.PK_KEY_OWNED_BUILDING + guid)
                    .sortValue(String.valueOf(buildingId))
                    .build();

            OwnedBuildingDoc doc = findById(key);

            delete(key);

            log.info("OwnedBuildingDoc Delete Success: {}", objectMapper.writeValueAsString(doc));

            dynamodbHistoryLogService.deleteHistoryLog(
                    HISTORYTYPE.LAND_OWNED_INITIALIZE,
                    HISTORYTYPE.LAND_OWNED_INITIALIZE.name(),
                    doc
            );

            return new DynamodbOperationResult(true, "", doc);
        }catch (Exception e){
            log.error("Init OwnedBuilding Error: {}", e.getMessage());
            return new DynamodbOperationResult(false, e.getMessage(), null);
        }
    }

}
