import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;

public class Main {

    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }

    public static String phpJsonEncode(Object obj, Gson gson) {
        String json = gson.toJson(obj);
        return json.replace("/", "\\/");  // <-- dynamic PHP-style escaping
    }

    public static String generateSignature(
            String secret,
            String method,
            String path,
            String body,
            String timestamp
    ) {
        try {
            String message =
                    method + "\n" +
                    path + "\n" +
                    body + "\n" +
                    timestamp + "\n";

            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            sha256_HMAC.init(secret_key);

            return bytesToHex(sha256_HMAC.doFinal(message.getBytes(StandardCharsets.UTF_8)));

        } catch (Exception e) {
            throw new RuntimeException("Error generating signature", e);
        }
    }

    public static void main(String[] args) {

        String secret = "{{YOUR_SECRET_KEY}}";
        String method = "POST";
        String path = "api/v1/payin/transactions";

        Gson gson = new GsonBuilder()
                .serializeNulls()
                .disableHtmlEscaping()
                .create();

        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        
        map.put("order_id", "adsd-ewerz-23sdsd-ad234");

        String body = phpJsonEncode(map, gson);  // <-- dynamic JSON encoding

        String timestamp = String.valueOf(System.currentTimeMillis());

        String signature = generateSignature(secret, method, path, body, timestamp);

        System.out.println("Body: " + body);
        System.out.println("Signature: " + signature);
        System.out.println("Timestamp: " + timestamp);
    }
}
