package com.banesco.common.application.helper;

import com.banesco.common.domain.exception.HttpStatusCodeException;
import com.banesco.module.msg_response_header.domain.model.AdditionalStatus;
import com.banesco.module.msg_response_header.domain.model.BlackList;
import com.banesco.module.msg_response_header.domain.model.BlackListRec;
import com.banesco.module.msg_response_header.domain.model.Status;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
public class PartyValidateHelper {

    private PartyValidateHelper() {}

    public static void validateBlackListStatus(
        BlackList blackList,
        Status status
    ) {
        if(!Objects.isNull(blackList)) {
            BlackListRec blackListRec = blackList.getBlackListRec();

            if(
                !Objects.isNull(blackListRec) &&
                !StringUtil.isNullOrEmpty(blackListRec.getBlackListBanesco()) &&
                !StringUtil.isNullOrEmpty(blackListRec.getBlackListCbn()) &&
                (
                    !blackListRec.getBlackListBanesco().equalsIgnoreCase("N") ||
                    !blackListRec.getBlackListCbn().equalsIgnoreCase("N")
                )
            ) {
                throw HttpStatusCodeException.unauthorized("VRN13");
            }
        }

        PartyValidateHelper.validateStatus(status);
    }

    public static void validateStatus(Status status) {
        if(Objects.isNull(status)) {
            return;
        }

        List<String> errors = extractErrorCodes(status);

        if(!errors.isEmpty()) {
            if(
                errors.size() == 1 &&
                (
                    Objects.equals(errors.get(0), "388") ||
                    errors.get(0).equalsIgnoreCase("AFPM388")
                )
            ) {
                log.error("Error del estatus controlado: {}", errors.get(0));
                throw HttpStatusCodeException.forbidden("VRN20");
            }

            AdditionalStatus additionalStatus = getFirstAdditionalStatus(status);
            String error = String.join("-", errors);
            String desc = (!Objects.isNull(additionalStatus))
                ? additionalStatus.getStatusDesc()
                : "";

            log.error(
                "Error asignado desde la lista concatenada de los errores: {} -> {}",
                error,
                desc
            );

            throw HttpStatusCodeException.badRequest(error, desc);
        } else {
            log.error(
                "Error asignado desde el status principal: {} -> {}",
                status.getStatusCode(),
                status.getStatusDesc()
            );

            throw HttpStatusCodeException.internalServer(
                status.getStatusCode(),
                status.getStatusDesc()
            );
        }
    }

    private static List<String> extractErrorCodes(Status status) {
        List<String> errors = new ArrayList<>();
        List<AdditionalStatus> additionalStatuses = status.getAdditionalStatus();

        if(Objects.isNull(additionalStatuses) || additionalStatuses.isEmpty()) {
            return errors;
        }

        for (AdditionalStatus item: additionalStatuses) {
            if (
                !Objects.equals(item.getStatusCode(), "000") &&
                !errors.contains(item.getStatusCode())
            ) {
                errors.add(item.getStatusCode());
            }
        }

        return errors;
    }

    private static AdditionalStatus getFirstAdditionalStatus(Status status) {
        List<AdditionalStatus> additionalStatuses = status.getAdditionalStatus();

        if(Objects.isNull(additionalStatuses) || additionalStatuses.isEmpty()) {
            return null;
        }

        for (AdditionalStatus item: additionalStatuses) {
            if (!Objects.equals(item.getStatusCode(), "000")) {
                return item;
            }
        }

        return null;
    }
}
