package com.ruoyi.app.omgpay;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Clock;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Verifies one store's OMG credentials against the stage query endpoint.
 * Credentials are used only to sign and verify this probe; this boundary never logs or persists them.
 */
@Component
public class OmgStoreCredentialVerifier {
    private final OmgPaymentQueryGateway gateway;
    private final OmgQueryResponseParser parser;
    private final OmgCheckMacSigner signer;
    private final Clock clock;

    @Autowired
    public OmgStoreCredentialVerifier(OmgPaymentQueryGateway gateway,
                                      OmgQueryResponseParser parser,
                                      OmgCheckMacSigner signer) {
        this(gateway, parser, signer, Clock.systemUTC());
    }

    OmgStoreCredentialVerifier(OmgPaymentQueryGateway gateway,
                               OmgQueryResponseParser parser,
                               OmgCheckMacSigner signer,
                               Clock clock) {
        this.gateway = gateway;
        this.parser = parser;
        this.signer = signer;
        this.clock = clock;
    }

    public Map<String, String> verify(String merchantId, String hashKey, String hashIv) {
        requirePresent("MerchantID", merchantId);
        long epochSecond = clock.instant().getEpochSecond();
        LinkedHashMap<String, String> request = new LinkedHashMap<>();
        request.put("MerchantID", merchantId);
        request.put("MerchantTradeNo", "OMGVERIFY" + epochSecond);
        request.put("TimeStamp", String.valueOf(epochSecond));
        request.put("CheckMacValue", signer.sign(request, hashKey, hashIv));
        Map<String, String> response = parser.parse(gateway.query(request));
        verifyResponse(response, request, hashKey, hashIv);
        return response;
    }

    private void verifyResponse(Map<String, String> response, Map<String, String> request,
                                String hashKey, String hashIv) {
        String checkMacValue = response.get("CheckMacValue");
        if (checkMacValue == null || !checkMacValue.matches("(?i)[0-9a-f]{64}")) {
            throw new IllegalArgumentException("OMG credential verification signature is malformed");
        }
        LinkedHashMap<String, String> signingFields = new LinkedHashMap<>(response);
        signingFields.remove("CheckMacValue");
        String expected = signer.sign(signingFields, hashKey, hashIv);
        if (!OmgPaymentNotifyService.secureEquals(expected, checkMacValue)) {
            throw new IllegalArgumentException("OMG credential verification signature mismatch");
        }
        if (!request.get("MerchantID").equals(response.get("MerchantID"))
                || !request.get("MerchantTradeNo").equals(response.get("MerchantTradeNo"))) {
            throw new IllegalArgumentException("OMG credential verification identity mismatch");
        }
    }

    private static void requirePresent(String name, String value) {
        if (value == null || value.isBlank()) {
            throw new IllegalArgumentException(name + " is required");
        }
    }
}
