syntax = "proto3";

package common.gateway.v1;

option go_package = "github.com/tech/sendico/pkg/proto/common/gateway/v1;gatewayv1";

import "api/proto/common/money/v1/money.proto";
import "api/proto/payments/endpoint/v1/endpoint.proto";

// Operation enumerates gateway-level operations that can be performed on a
// payment method.
enum Operation {
  OPERATION_UNSPECIFIED     = 0;
  OPERATION_AUTHORIZE       = 1;
  OPERATION_CAPTURE         = 2;
  OPERATION_REFUND          = 3;
  OPERATION_VOID            = 4;
  OPERATION_PAYOUT          = 5;
  OPERATION_TOKENIZE        = 6;
  OPERATION_VERIFY          = 7; // zero-amount verification
  OPERATION_GET_BALANCE     = 8;
  OPERATION_CREATE_ACCOUNT  = 9;
}

// Rail identifiers for orchestration. Extend with new rails as needed.
enum Rail {
  RAIL_UNSPECIFIED = 0;
  RAIL_CRYPTO = 1;
  RAIL_SETTLEMENT = 2;
  RAIL_LEDGER = 3;
  RAIL_CARD = 4;
  RAIL_ONRAMP = 5;
  RAIL_OFFRAMP = 6;
}

// Operations supported in a payment plan.
enum RailOperation {
  RAIL_OPERATION_UNSPECIFIED = 0;
  RAIL_OPERATION_DEBIT = 1;
  RAIL_OPERATION_CREDIT = 2;
  RAIL_OPERATION_SEND = 3;
  RAIL_OPERATION_FEE = 4;
  RAIL_OPERATION_OBSERVE_CONFIRM = 5;
  RAIL_OPERATION_FX_CONVERT = 6;
  RAIL_OPERATION_BLOCK = 7;
  RAIL_OPERATION_RELEASE = 8;
  RAIL_OPERATION_MOVE = 9;
}

// Limits in minor units, e.g. cents
message AmountLimits {
  int64 min_minor = 1;
  int64 max_minor = 2;
}

// Capabilities of a particular operation (e.g. "authorize")
message OperationCapabilities {
  // If false or absent in the map -> operation not supported
  bool supported        = 1;
  bool partial_allowed  = 2; // partial capture/refund
  bool supports_3ds     = 3; // relevant mostly for AUTHORIZE/VERIFY
  bool synchronous      = 4; // true = immediate result, false = async/poll
}

// Per-method matrix entry
message MethodCapability {
  payments.endpoint.v1.PaymentMethod method  = 1; 

  // ISO 4217 currency codes, e.g. "EUR", "USD"
  repeated string currencies   = 2;

  // ISO 3166-1 alpha-2 country codes where this method is available
  repeated string countries    = 3;

  // Can the gateway tokenize this method (card token, wallet token, etc.)
  bool tokenization_supported  = 4;

  // Optional per-method limits; if unset, use global amount_limits
  AmountLimits amount_limits   = 5;
}

// Payout capabilities of this gateway
message PayoutCapabilities {
  bool enabled                  = 1;
  repeated string currencies    = 2;
  repeated string countries     = 3;
  AmountLimits amount_limits    = 4;
}

// High-level capability descriptor for a gateway
message GatewayCapabilities {
  // For each operation, describe what exactly it can do.
  // Map key uses the Operation enum name (e.g. "OPERATION_AUTHORIZE").
  map<string, OperationCapabilities> operations = 1;

  // For each payment method, list where and how it works
  repeated MethodCapability methods = 2;

  // Global amount limits (fallback if per-method limits not set)
  AmountLimits amount_limits = 3;

  // Payout-related capabilities (if any)
  PayoutCapabilities payouts = 4;

  // Free-form metadata / escape hatch
  map<string, string> extra = 10;
}

// A specific gateway instance or config variant (e.g. stripe_eu_prod)
message GatewayDescriptor {
  string id          = 1; // "stripe_eu", "adyen_br", "local_bank_pl"
  string provider    = 2; // "stripe", "adyen", "local_bank"
  string label       = 3; // human-readable name
  string version     = 4; // config or integration version
  string environment = 5; // "prod", "sandbox", "test"

  GatewayCapabilities capabilities = 6;
}

// Capabilities declared per gateway instance for orchestration.
message RailCapabilities {
  bool can_pay_in = 1;
  bool can_pay_out = 2;
  bool can_read_balance = 3;
  bool can_send_fee = 4;
  bool requires_observe_confirm = 5;
  bool can_block = 6;
  bool can_release = 7;
}

// LimitsOverride provides per-currency overrides for global limit settings.
message LimitsOverride {
  string max_volume = 1;
  string min_amount = 2;
  string max_amount = 3;
  string max_fee = 4;
  int32 max_ops = 5;
}

// Limits are decimal-safe string amounts unless otherwise noted.
message Limits {
  string min_amount = 1;
  string max_amount = 2;
  string per_tx_max_fee = 3;
  string per_tx_min_amount = 4;
  string per_tx_max_amount = 5;
  map<string, string> volume_limit = 6; // bucket -> max volume
  map<string, int32> velocity_limit = 7; // bucket -> max operations count
  map<string, LimitsOverride> currency_limits = 8;
}

// A specific gateway instance for a given rail/network pairing.
message GatewayInstanceDescriptor {
  string id = 1; // unique instance id
  Rail rail = 2;
  string network = 3;
  repeated string currencies = 4;
  RailCapabilities capabilities = 5;
  Limits limits = 6;
  string version = 7;
  bool is_enabled = 8;
}

// OperationResult represents the outcome status of an operation in a gateway
enum OperationResult {
  OPERATION_RESULT_UNSPECIFIED = 0;
  OPERATION_RESULT_SUCCESS     = 1;
  OPERATION_RESULT_FAILED      = 2;
  OPERATION_RESULT_CANCELLED   = 3;
}

// OperationError describes a failure returned by a gateway operation.
message OperationError {
  string code            = 1;
  string message         = 2;
  bool can_retry        = 3;
  bool should_rollback  = 4;
}

// OperationExecutionStatus reports the result of executing a single gateway
// operation, including the settled amount and any error.
message OperationExecutionStatus {
  string idempotency_key = 1;
  string operation_ref   = 2;
  common.money.v1.Money executed_money   = 3;
  OperationResult status = 4;
  OperationError error   = 5;
}
