syntax = "proto3";

package payments.orchestration.v2;

option go_package = "github.com/tech/sendico/pkg/proto/payments/orchestration/v2;orchestrationv2";

import "google/protobuf/timestamp.proto";
import "api/proto/common/gateway/v1/gateway.proto";
import "api/proto/common/money/v1/money.proto";
import "api/proto/common/pagination/v1/cursor.proto";
import "api/proto/payments/shared/v1/shared.proto";
import "api/proto/payments/quotation/v2/quotation.proto";
import "api/proto/payments/quotation/v2/interface.proto";

// PaymentOrchestratorService executes quotation-backed payments and exposes
// orchestration-focused read APIs.
//
// Notes:
// - Execution input is quotation_ref (not an execution plan).
// - Returned Payment contains immutable quote/intent snapshots, so reads remain
//   meaningful after quote storage TTL expiry.
service PaymentOrchestratorService {
  // ExecutePayment creates/starts payment execution from an accepted quote.
  rpc ExecutePayment(ExecutePaymentRequest) returns (ExecutePaymentResponse);

  // ExecuteBatchPayment creates/starts execution for all intents in a quoted batch.
  rpc ExecuteBatchPayment(ExecuteBatchPaymentRequest) returns (ExecuteBatchPaymentResponse);

  // GetPayment returns one payment by reference.
  rpc GetPayment(GetPaymentRequest) returns (GetPaymentResponse);

  // ListPayments returns payments filtered by orchestration lifecycle.
  rpc ListPayments(ListPaymentsRequest) returns (ListPaymentsResponse);
}

// ExecutePaymentRequest starts orchestration for one accepted quote.
message ExecutePaymentRequest {
  // Organization and trace context; idempotency should be supplied via
  // meta.trace.idempotency_key.
  payments.shared.v1.RequestMeta meta = 1;

  // Required accepted quotation reference.
  string quotation_ref = 2;

  // Optional caller-side correlation key.
  string client_payment_ref = 3;
}

// ExecutePaymentResponse returns the created or deduplicated payment.
message ExecutePaymentResponse {
  Payment payment = 1;
}

// ExecuteBatchPaymentRequest starts orchestration for all intents resolved by
// one accepted quotation_ref.
message ExecuteBatchPaymentRequest {
  // Organization and trace context; idempotency should be supplied via
  // meta.trace.idempotency_key.
  payments.shared.v1.RequestMeta meta = 1;

  // Required accepted quotation reference.
  string quotation_ref = 2;

  // Optional caller-side correlation key.
  string client_payment_ref = 3;
}

// ExecuteBatchPaymentResponse returns created or deduplicated payments for
// grouped batch execution.
message ExecuteBatchPaymentResponse {
  repeated Payment payments = 1;
}

// GetPaymentRequest fetches one payment by payment_ref.
//
// If meta.organization_ref is provided, the lookup is scoped to that
// organization. If it is omitted, the service resolves the payment globally by
// payment_ref and returns the resolved organization_ref in the response.
message GetPaymentRequest {
  payments.shared.v1.RequestMeta meta = 1;
  string payment_ref = 2;
}

// GetPaymentResponse returns one orchestration payment aggregate.
message GetPaymentResponse {
  Payment payment = 1;
  string organization_ref = 2;
}

// ListPaymentsRequest lists payments within the caller organization scope.
message ListPaymentsRequest {
  payments.shared.v1.RequestMeta meta = 1;

  // Optional state filter. Empty means all states.
  repeated OrchestrationState states = 2;

  // Optional filter by source quotation.
  string quotation_ref = 3;

  // Optional creation-time range filter.
  // Semantics: created_from is inclusive, created_to is exclusive.
  google.protobuf.Timestamp created_from = 4;
  google.protobuf.Timestamp created_to = 5;

  // Cursor pagination controls.
  common.pagination.v1.CursorPageRequest page = 6;
}

// ListPaymentsResponse returns one cursor page of payments.
message ListPaymentsResponse {
  repeated Payment payments = 1;
  common.pagination.v1.CursorPageResponse page = 2;
}

// Payment is the orchestration runtime aggregate.
// It is designed to be self-contained for post-factum analysis and support.
message Payment {
  // Stable payment reference.
  string payment_ref = 1;

  // Quote used to initiate the payment.
  string quotation_ref = 2;

  // Immutable snapshot of the execution intent used to create this payment.
  payments.quotation.v2.QuoteIntent intent_snapshot = 3;

  // Immutable quote snapshot used for execution pricing/route context.
  payments.quotation.v2.PaymentQuote quote_snapshot = 4;

  string client_payment_ref = 5;

  // Current orchestration runtime state.
  OrchestrationState state = 6;

  // Monotonic aggregate version for optimistic concurrency control.
  uint64 version = 7;

  // Step-level execution telemetry.
  repeated StepExecution step_executions = 8;

  // Aggregate timestamps.
  google.protobuf.Timestamp created_at = 9;
  google.protobuf.Timestamp updated_at = 10;
}

// Kept local on purpose: payments.shared.v1.PaymentState models product-level
// payment lifecycle and does not cover orchestration runtime states.
enum OrchestrationState {
  // Default zero value.
  ORCHESTRATION_STATE_UNSPECIFIED = 0;
  // Payment record created, execution not started yet.
  ORCHESTRATION_STATE_CREATED = 1;
  // Runtime is actively executing steps.
  ORCHESTRATION_STATE_EXECUTING = 2;
  // Runtime requires operator/system attention.
  ORCHESTRATION_STATE_NEEDS_ATTENTION = 3;
  // Execution finished successfully.
  ORCHESTRATION_STATE_SETTLED = 4;
  // Execution reached terminal failure.
  ORCHESTRATION_STATE_FAILED = 5;
}

// StepExecution is telemetry for one orchestration step attempt stream.
message StepExecution {
  // Stable step reference inside orchestration runtime.
  string step_ref = 1;
  // Logical step code/type label (planner/executor-defined).
  string step_code = 2;
  // Current state of this step.
  StepExecutionState state = 3;
  // Monotonic attempt number, starts at 1.
  uint32 attempt = 4;
  // Step timing.
  google.protobuf.Timestamp started_at = 5;
  google.protobuf.Timestamp completed_at = 6;
  // Failure details when state is FAILED/NEEDS_ATTENTION.
  Failure failure = 7;
  // External references produced by the step.
  repeated ExternalReference refs = 8;
  // Reporting visibility for user/backoffice/audit projections.
  ReportVisibility report_visibility = 9;
  // Optional user-facing operation label.
  string user_label = 10;
  // Structured money envelope for this step lifecycle.
  StepExecutionMoney money = 11;

  // Former flat money fields intentionally removed.
  reserved 12, 13, 14, 15;
  reserved "executed_money", "converted_money", "planned_money", "planned_converted_money";
}

// StepExecutionMoney groups planned and executed monetary snapshots.
message StepExecutionMoney {
  // Monetary instruction bound by planner before execution.
  StepExecutionMoneySnapshot planned = 1;
  // Monetary outcome observed/confirmed after execution.
  StepExecutionMoneySnapshot executed = 2;
}

// StepExecutionMoneySnapshot captures base and converted amounts.
message StepExecutionMoneySnapshot {
  // Base amount for the step.
  common.money.v1.Money amount = 1;
  // Converted amount for FX-like steps.
  common.money.v1.Money converted_amount = 2;
}

// Kept local on purpose: no shared enum exists for orchestration step runtime.
enum StepExecutionState {
  // Default zero value.
  STEP_EXECUTION_STATE_UNSPECIFIED = 0;
  // Not started yet.
  STEP_EXECUTION_STATE_PENDING = 1;
  // Currently running.
  STEP_EXECUTION_STATE_RUNNING = 2;
  // Finished successfully.
  STEP_EXECUTION_STATE_COMPLETED = 3;
  // Finished with terminal error.
  STEP_EXECUTION_STATE_FAILED = 4;
  // Blocked and requires attention/intervention.
  STEP_EXECUTION_STATE_NEEDS_ATTENTION = 5;
  // Not executed because it became irrelevant/unreachable.
  STEP_EXECUTION_STATE_SKIPPED = 6;
}

// ReportVisibility determines which audience should see the step.
enum ReportVisibility {
  // Default zero value.
  REPORT_VISIBILITY_UNSPECIFIED = 0;
  // Hidden from all external reports.
  REPORT_VISIBILITY_HIDDEN = 1;
  // Visible to end users.
  REPORT_VISIBILITY_USER = 2;
  // Visible to backoffice operators.
  REPORT_VISIBILITY_BACKOFFICE = 3;
  // Visible only for audit/compliance review.
  REPORT_VISIBILITY_AUDIT = 4;
}

// Failure describes a normalized step failure.
message Failure {
  // Broad, shared failure category.
  payments.shared.v1.PaymentFailureCode category = 1;
  // Machine-readable, executor-specific code.
  string code = 2;
  // Human-readable message.
  string message = 3;
}

// ExternalReference links step execution to external systems/operations.
message ExternalReference {
  // Rail where external side effect happened.
  common.gateway.v1.Rail rail = 1;
  // Gateway instance that owns the referenced operation/entity.
  // This is the discovery key for fetching details on demand.
  string gateway_instance_id = 2;
  // Reference classifier. Keep values stable and namespaced:
  // e.g. "ledger.journal", "ledger.hold", "chain.tx", "provider.payout".
  string kind = 3;
  // External operation/entity reference id in the owner system.
  string ref = 4;
}
