<?php

namespace Modules\Payment\Contracts;

use Modules\Payment\Data\PaymentRequestData;
use Modules\Payment\Data\PaymentResultData;
use Modules\Payment\Data\RefundResultData;
use Modules\Payment\Exceptions\InvalidWebhookSignatureException;

/**
 * Contract every payment gateway strategy implements (e.g. KbzMiniAppGateway).
 *
 * Strategies are deliberately ignorant of Payment/Booking Eloquent models —
 * they only take/return DTOs, so booking-status changes stay in listeners
 * reacting to PaymentCompleted/PaymentFailed/RefundProcessed (domain.md §6).
 */
interface PaymentGatewayInterface
{
    /**
     * Start a payment attempt with the gateway.
     */
    public function initiate(PaymentRequestData $data): PaymentResultData;

    /**
     * Re-check a payment's current status with the gateway (defense-in-depth
     * re-verification, and used inside webhook processing — domain.md §6).
     */
    public function verify(string $gatewayTransactionId): PaymentResultData;

    /**
     * Reverse (all or part of) a successful payment.
     */
    public function refund(string $gatewayTransactionId, string $amount, string $reason): RefundResultData;

    /**
     * Handle an inbound webhook notification — verifies the payload is
     * genuinely from the gateway (throwing InvalidWebhookSignatureException
     * if not) and maps it to a PaymentResultData. Every gateway implements
     * this itself since the notification shape and signing scheme are
     * gateway-specific; the webhook controller only routes by PaymentMethod
     * and never branches on gateway (domain.md §6).
     *
     * @param  array<string, mixed>  $payload  The raw, as-posted webhook body.
     *
     * @throws InvalidWebhookSignatureException
     */
    public function handleWebhook(array $payload): PaymentResultData;
}
