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

import com.banesco.common.domain.model.Device;
import com.banesco.common.infrastructure.context.RequestContext;
import com.banesco.module.instruction.domain.model.Instruction;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.netty.util.internal.StringUtil;
import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.*;

import java.util.Map;
import java.util.Objects;

import static java.util.Map.entry;

@Getter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@RegisterForReflection
public class ServiceOrderPaymentSearchRequest {
    @NonNull
    @JsonIgnore
    private String customerReferenceFintechId;
    @NonNull
    @JsonIgnore
    private String appId;
    @NonNull
    private Instruction procedureRequest;
    @NonNull
    private Device device;

    @JsonIgnore
    public String getPartyId() {
        return procedureRequest
            .getInstructionInvolvement()
            .getPartyReference()
            .getPartyIdentification()
            .get(0)
            .getPartyIdentification()
            .getIdentifierValue();
    }

    @JsonIgnore
    public String getInitiatedDate() {
        return procedureRequest
            .getInstructionDate()
            .get(0)
            .getDate();
    }

    @JsonIgnore
    public String getInstructionRequestId() {
        return procedureRequest
            .getInstructionIdentifier()
            .getIdentification()
            .getIdentifierValue();
    }

    @JsonIgnore
    public String getChannelCode() {
        return procedureRequest
            .getInstructionPurposeType();
    }

    @JsonIgnore
    public boolean isBole() {
        return Objects.equals(procedureRequest
            .getInstructionPurposeType().toUpperCase(), "BOLE");
    }

    @JsonIgnore
    public Map<String, String> toParams() {
        return Map.ofEntries(
            entry("partyReferenceId", Objects.toString(getPartyId(), "")),
            entry("channelCode", Objects.toString(getChannelCode(), ""))
        );
    }

    @JsonIgnore
    public Map<String, String> toQueryString() {
        return Map.ofEntries(
            entry("appId", Objects.toString(getAppId(), "")),
            entry("customerReferenceFintechId", Objects.toString(getCustomerReferenceFintechId(), "")),
            entry("initiatedDate", Objects.toString(getInitiatedDate(), "")),
            entry("instructionRequestId", Objects.toString(getInstructionRequestId(), "")),
            entry("deviceType", Objects.toString(getDevice().getDeviceType(), "")),
            entry("deviceDescription", Objects.toString(getDevice().getDeviceDescription(), "")),
            entry("deviceIp", Objects.toString(getDevice().getDeviceIp(), "")),
            entry("deviceSessionReference", (!StringUtil.isNullOrEmpty(getDevice().getDeviceSessionReference()))
                ? getDevice().getDeviceSessionReference()
                : RequestContext.getRequestId()
            )
        );
    }
}