package com.ruoyi.app.omgpay.dto;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Controller DTO containing the exact callback body and every decoded field.
 * Unknown and empty fields are retained because OMG includes them in CheckMacValue.
 */
public class OmgNotifyRequest {
    private final String sourceIp;
    private final String rawForm;
    private final List<OmgNotifyField> fields;
    private final String invalidReason;

    public OmgNotifyRequest(String sourceIp, String rawForm, List<OmgNotifyField> fields, String invalidReason) {
        this.sourceIp = sourceIp;
        this.rawForm = rawForm == null ? "" : rawForm;
        this.fields = fields == null ? List.of() : List.copyOf(fields);
        this.invalidReason = invalidReason;
    }

    public String getSourceIp() {
        return sourceIp;
    }

    public String getRawForm() {
        return rawForm;
    }

    public List<OmgNotifyField> getFields() {
        return fields;
    }

    public boolean isValid() {
        return invalidReason == null;
    }

    public String getInvalidReason() {
        return invalidReason;
    }

    public boolean contains(String name) {
        return fields.stream().anyMatch(field -> field.name().equals(name));
    }

    public String value(String name) {
        return fields.stream().filter(field -> field.name().equals(name))
                .map(OmgNotifyField::value).findFirst().orElse(null);
    }

    /** Builds the signer input only after the request has crossed the Controller boundary. */
    public Map<String, String> signingFields() {
        LinkedHashMap<String, String> result = new LinkedHashMap<>();
        for (OmgNotifyField field : fields) {
            if (!"CheckMacValue".equals(field.name())) {
                result.put(field.name(), field.value());
            }
        }
        return Collections.unmodifiableMap(result);
    }
}
