package com.banesco.application.helper;


import com.banesco.common.application.exception.BanRuntimeException;
import com.banesco.common.application.helper.DeviceHelper;
import com.banesco.common.domain.dto.bian.device.StringHelper;
import com.banesco.common.infraestructure.utils.PatternValidator;
import com.banesco.commons.config.StatusCodes;
import com.banesco.domain.bian.request.RecUpdateCardStatusRequest;
import jakarta.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
import org.eclipse.microprofile.config.inject.ConfigProperty;

import java.util.List;

@ApplicationScoped
public class UpdateCardStatusRequestValidator {

    private final PatternValidator CUSTOMER_NUMBER_PATTERN;
    private final PatternValidator CARD_NUMBER_PATTERN;

    private final PatternValidator CARD_STATUS_CODE_PATTERN;
    private final PatternValidator CARD_STATUS_ACTION_PATTERN;
    private final PatternValidator CARD_STATUS_REASON_PATTERN;

    @ConfigProperty(name = "api.allowed.customer.types")
    List<String> CUSTOMER_TYPES;
    @ConfigProperty(name = "api.allowed.card.types")
    List<String> CARD_TYPES;

    public UpdateCardStatusRequestValidator() {
        Config configEnv = ConfigProvider.getConfig();

        CUSTOMER_NUMBER_PATTERN = PatternValidator.withRegex(configEnv.getValue("api.allowed.customer.number-pattern", String.class));
        CARD_NUMBER_PATTERN = PatternValidator.withRegex(configEnv.getValue("api.allowed.card.number-pattern", String.class));
        CARD_STATUS_CODE_PATTERN = PatternValidator.withRegex(configEnv.getValue("api.allowed.card.status-code-pattern", String.class));
        CARD_STATUS_ACTION_PATTERN = PatternValidator.withRegex(configEnv.getValue("api.allowed.card.status-action-pattern", String.class));
        CARD_STATUS_REASON_PATTERN = PatternValidator.withRegex(configEnv.getValue("api.allowed.card.status-reason-pattern", String.class));

    }


    // Function to check invalid fields
    public void validatedRequest(
            String customerReferenceFintechId,
            String appId,
            RecUpdateCardStatusRequest request
    ) {
        //check header
        if (StringHelper.isEmpty(customerReferenceFintechId)) {
            throw new BanRuntimeException(StatusCodes.INVALID_HEADER, "customerReferenceFintechId");
        }

        if (StringHelper.isEmpty(appId)) {
            throw new BanRuntimeException(StatusCodes.INVALID_HEADER, "appId");
        }


        if (request == null) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "body");
        }

        // VLI Device
        if (request.getDevice() == null) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "device");
        }

        if (StringHelper.isEmpty(request.getDevice().getDeviceType())) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "device.deviceType");
        }

        boolean isValidDevice = DeviceHelper.isValidDeviceType(request.getDevice().getDeviceType());
        if (!isValidDevice) {
            throw new BanRuntimeException(StatusCodes.INVALID_FORMAT, "device.deviceType");
        }

        if (StringHelper.isEmpty(request.getDevice().getDeviceDescription())) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "device.deviceDescription");
        }

        if (request.getDevice().getDeviceDescription().length() > 255) {
            throw new BanRuntimeException(StatusCodes.INVALID_FORMAT, "device.deviceDescription");
        }

        if (StringHelper.isEmpty(request.getDevice().getDeviceSessionReference())) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "device.deviceSessionReference");
        }
        if (request.getDevice().getDeviceSessionReference().length() > 255) {
            throw new BanRuntimeException(StatusCodes.INVALID_FORMAT, "device.deviceSessionReference");
        }

        // Customer

        var customerReference = request.getCustomerReference();
        if (customerReference == null) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "customerReference");
        }

        if (StringHelper.isEmpty(customerReference.getCustomerIdType())) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "customerReference.customerIdType");
        }

        if (!CUSTOMER_TYPES.contains(customerReference.getCustomerIdType())) {
            throw new BanRuntimeException(StatusCodes.INVALID_FORMAT, "customerReference.customerIdType");
        }

        if (StringHelper.isEmpty(customerReference.getCustomerId())) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "customerReference.customerId");
        }

        if (!CUSTOMER_NUMBER_PATTERN.isValid(customerReference.getCustomerId())) {
            throw new BanRuntimeException(StatusCodes.INVALID_FORMAT, "customerReference.customerId");
        }

        // Card


        var paymentCard = request.getCardReference();
        if (paymentCard == null) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "cardReference.paymentCard");
        }

        if (StringHelper.isEmpty(paymentCard.getCardType())) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "cardReference.cardType");
        }

        if (!CARD_TYPES.contains(paymentCard.getCardType())) {
            throw new BanRuntimeException(StatusCodes.INVALID_FORMAT, "cardReference.cardType");
        }

        if (StringHelper.isEmpty(paymentCard.getCardNumber())) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "cardReference.cardNumber");
        }

        if (!CARD_NUMBER_PATTERN.isValid(paymentCard.getCardNumber())) {
            throw new BanRuntimeException(StatusCodes.INVALID_FORMAT, "cardReference.cardNumber");
        }

        if (StringHelper.isEmpty(paymentCard.getCardStatusCode())) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "cardReference.cardStatusCode");
        }

        if (!CARD_STATUS_CODE_PATTERN.isValid(paymentCard.getCardStatusCode())) {
            throw new BanRuntimeException(StatusCodes.INVALID_FORMAT, "cardReference.cardStatusCode");
        }

        if (StringHelper.isEmpty(paymentCard.getCardStatusAction())) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "cardReference.cardStatusAction");
        }

        if (!CARD_STATUS_ACTION_PATTERN.isValid(paymentCard.getCardStatusAction())) {
            throw new BanRuntimeException(StatusCodes.INVALID_FORMAT, "cardReference.cardStatusAction");
        }

        if (StringHelper.isEmpty(paymentCard.getCardStatusReason())) {
            throw new BanRuntimeException(StatusCodes.FIELD_REQUIRED, "cardReference.cardStatusReason");
        }

        if (!CARD_STATUS_REASON_PATTERN.isValid(paymentCard.getCardStatusReason())) {
            throw new BanRuntimeException(StatusCodes.INVALID_FORMAT, "cardReference.cardStatusReason");
        }

    }

}
