<?php

declare(strict_types=1);

namespace apexl\Io\modules\payment\Contract;

use apexl\Io\modules\payment\Dto\SubscriptionRequest;
use apexl\Io\modules\payment\Dto\SubscriptionResult;

/**
 * Gateway supports native recurring-billing primitives (Stripe Subscriptions,
 * PayPal Billing Plans, GoCardless mandates+subscriptions, Revolut Business
 * subscription-by-mandate). The gateway tracks billing cycles + retries
 * itself; the consumer just listens for state-change webhooks.
 *
 * Without this interface a gateway can still support hosted-checkout for
 * one-off payments — it just can't drive recurring charges natively.
 * (Consumers can fall back to driving recurring charges manually via a
 * billing-cycle scheduler + saved payment methods + one-off charges.)
 */
interface SubscriptionGatewayInterface
{
    /**
     * Create a recurring subscription at the gateway, returning its
     * provider-side ref + lifecycle state.
     */
    public function createSubscription(SubscriptionRequest $request): SubscriptionResult;

    /**
     * Cancel a subscription immediately, or at-period-end if `$atPeriodEnd`.
     */
    public function cancelSubscription(string $gatewaySubscriptionRef, bool $atPeriodEnd = true): SubscriptionResult;

    /**
     * Swap the plan / price on an active subscription. `$prorate` controls
     * gateway-side proration (Stripe: behavior=create_prorations; others:
     * map onto whatever the gateway offers).
     */
    public function changeSubscriptionPlan(
        string $gatewaySubscriptionRef,
        string $newPlanRef,
        bool   $prorate = true,
    ): SubscriptionResult;

    /**
     * Re-fetch + return the current state of a subscription. Used to
     * reconcile after a webhook miss or for the customer-portal UI.
     */
    public function lookupSubscription(string $gatewaySubscriptionRef): SubscriptionResult;
}
