package com.banesco.module.legal_customer_product_directory.domain.dto.request;

import com.banesco.common.domain.model.AppIdConfig;
import com.banesco.common.domain.model.Device;
import com.banesco.common.infrastructure.context.RequestContext;
import io.netty.util.internal.StringUtil;
import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.*;

import java.util.LinkedHashMap;
import java.util.Map;

@Getter
@Setter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@RegisterForReflection
public class LegalCustomerProductDirectoryRequest {
    @NonNull
    private String customerReferenceFintechId;  // Header obligatorio
    @NonNull
    private String appId;                       // Header obligatorio
    @NonNull
    private String customerId;             // VCUSCUN - Obligatorio (Numero de cliente IBS)
    @NonNull
    private Device device;

    private String bankNumber;             // VACMBNK - Numero de Banco (filtro)
    private String currencyCode;           // VACMCCY - Moneda (filtro)
    private String accountStatus;          // VACMAST - Estatus de Cuenta (filtro)
    private String productCvCode;          // VACMPROCV - Codigo de Producto Cuenta Verde (filtro)
    private String productCode;            // VACMPRO - Codigo de Producto (filtro)
    private String channelCode;            // VAFILICANAL - Codigo de Canal (filtro)
    private String serviceType;            // VAFILICOSER - Tipo de Servicio (filtro)
    private String affiliationStatus;      // VAFILISTATU - Estatus de afiliacion (filtro)
    private String limitType;              // VALIMIT - Pagador/Receptor (PAG/REC) (filtro)
    private String casheaIndicator;        // VCASHEA - SI/NO (filtro)

    public Map<String, String> toQueryString() {
        Map<String, String> queryParams = new LinkedHashMap<>();

        addIfNotEmpty(queryParams, "appId", getAppId());
        addIfNotEmpty(queryParams, "customerReferenceFintechId", getCustomerReferenceFintechId());
        addIfNotEmpty(queryParams, "serviceType", getServiceType());
        addIfNotEmpty(queryParams, "limitType", getLimitType());
        addIfNotEmpty(queryParams, "casheaIndicator", getCasheaIndicator());
        addIfNotEmpty(queryParams, "bankNumber", getBankNumber());
        addIfNotEmpty(queryParams, "currencyCode", getCurrencyCode());
        addIfNotEmpty(queryParams, "accountStatus", getAccountStatus());
        addIfNotEmpty(queryParams, "productCvCode", getProductCvCode());
        addIfNotEmpty(queryParams, "productCode", getProductCode());
        addIfNotEmpty(queryParams, "channelCode", getChannelCode());
        addIfNotEmpty(queryParams, "affiliationStatus", getAffiliationStatus());

        addIfNotEmpty(queryParams, "deviceType", getDevice().getDeviceType());
        addIfNotEmpty(queryParams, "deviceDescription", getDevice().getDeviceDescription());
        addIfNotEmpty(queryParams, "deviceIp", getDevice().getDeviceIp());

        queryParams.put("deviceSessionReference", (!StringUtil.isNullOrEmpty(getDevice().getDeviceSessionReference()))
            ? getDevice().getDeviceSessionReference()
            : RequestContext.getRequestId()
        );

        return queryParams;
    }

    public LegalCustomerProductDirectoryRequest fromAppIdConfig(
        LegalCustomerProductDirectoryRequest request,
        AppIdConfig appIdConfig
    ) {
        return LegalCustomerProductDirectoryRequest.builder()
            .customerId(this.getCustomerId())
            .appId(this.getAppId())
            .customerReferenceFintechId(this.getCustomerReferenceFintechId())
            .serviceType(appIdConfig.getRequest().getServiceType())
            .limitType(appIdConfig.getRequest().getLimitType())
            .casheaIndicator(appIdConfig.getRequest().getCasheaIndicator())
            .bankNumber(appIdConfig.getRequest().getBankNumber())
            .currencyCode(appIdConfig.getRequest().getCurrencyCode())
            .accountStatus(appIdConfig.getRequest().getAccountStatus())
            .productCvCode(appIdConfig.getRequest().getProductCvCode())
            .productCode(appIdConfig.getRequest().getProductCode())
            .channelCode(appIdConfig.getRequest().getChannelCode())
            .affiliationStatus(appIdConfig.getRequest().getAffiliationStatus())
            .device(request.getDevice())
            .build();
    }

    public boolean hasValidRequestParameters(AppIdConfig appIdConfig) {
        if (appIdConfig == null || appIdConfig.getRequest() == null) {
            return false;
        }

        LegalCustomerProductDirectoryRequest configRequest = appIdConfig.getRequest();

        return hasValue(configRequest.getBankNumber()) ||
            hasValue(configRequest.getCurrencyCode()) ||
            hasValue(configRequest.getAccountStatus()) ||
            hasValue(configRequest.getProductCvCode()) ||
            hasValue(configRequest.getProductCode()) ||
            hasValue(configRequest.getChannelCode()) ||
            hasValue(configRequest.getServiceType()) ||
            hasValue(configRequest.getAffiliationStatus()) ||
            hasValue(configRequest.getLimitType()) ||
            hasValue(configRequest.getCasheaIndicator());
    }

    private void addIfNotEmpty(
        Map<String, String> map,
        String key,
        String value
    ) {
        if (hasValue(value)) {
            map.put(key, value);
        }
    }

    private boolean hasValue(String field) {
        return field != null && !field.trim().isEmpty();
    }
}