syntax = "proto3";

package proto;

option csharp_namespace = "DysonNetwork.Shared.Proto";

option go_package = "git.solsynth.dev/goatworks/turbine/pkg/shared/proto/gen";

import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/duration.proto";

message Wallet {
  string id = 1;
  repeated WalletPocket pockets = 2;
  string account_id = 3;
}

message WalletPocket {
  string id = 1;
  string currency = 2;
  // Using string for decimal to avoid precision loss.
  string amount = 3;
  string wallet_id = 4;
}

enum FundSplitType {
  FUND_SPLIT_TYPE_UNSPECIFIED = 0;
  FUND_SPLIT_TYPE_EVEN = 1;
  FUND_SPLIT_TYPE_RANDOM = 2;
}

enum FundStatus {
  FUND_STATUS_UNSPECIFIED = 0;
  FUND_STATUS_CREATED = 1;
  FUND_STATUS_PARTIALLY_RECEIVED = 2;
  FUND_STATUS_FULLY_RECEIVED = 3;
  FUND_STATUS_EXPIRED = 4;
  FUND_STATUS_REFUNDED = 5;
}

message WalletFund {
  string id = 1;
  string currency = 2;
  string total_amount = 3;
  string remaining_amount = 10;
  FundSplitType split_type = 4;
  FundStatus status = 5;
  google.protobuf.StringValue message = 6;
  string creator_account_id = 7;
  google.protobuf.Timestamp expired_at = 8;
  repeated WalletFundRecipient recipients = 9;
}

message WalletFundRecipient {
  string id = 1;
  string fund_id = 2;
  string recipient_account_id = 3;
  string amount = 4;
  bool is_received = 5;
  optional google.protobuf.Timestamp received_at = 6;
}

enum SubscriptionStatus {
  // Using proto3 enum naming convention
  SUBSCRIPTION_STATUS_UNSPECIFIED = 0;
  SUBSCRIPTION_STATUS_UNPAID = 1;
  SUBSCRIPTION_STATUS_ACTIVE = 2;
  SUBSCRIPTION_STATUS_EXPIRED = 3;
  SUBSCRIPTION_STATUS_CANCELLED = 4;
}

enum GiftStatus {
  // Using proto3 enum naming convention
  GIFT_STATUS_UNSPECIFIED = 0;
  GIFT_STATUS_CREATED = 1;
  GIFT_STATUS_SENT = 2;
  GIFT_STATUS_REDEEMED = 3;
  GIFT_STATUS_EXPIRED = 4;
  GIFT_STATUS_CANCELLED = 5;
}

message Subscription {
  string id = 1;
  google.protobuf.Timestamp begun_at = 2;
  optional google.protobuf.Timestamp ended_at = 3;
  string identifier = 4;
  bool is_active = 5;
  bool is_free_trial = 6;
  SubscriptionStatus status = 7;
  string payment_method = 8;
  PaymentDetails payment_details = 9;
  // Using string for decimal to avoid precision loss.
  string base_price = 10;
  optional string coupon_id = 11;
  optional Coupon coupon = 12;
  optional google.protobuf.Timestamp renewal_at = 13;
  string account_id = 14;
  bool is_available = 15;
  // Using string for decimal to avoid precision loss.
  string final_price = 16;
  google.protobuf.Timestamp created_at = 17;
  google.protobuf.Timestamp updated_at = 18;
}

message SubscriptionReferenceObject {
  string id = 1;
  string identifier = 2;
  google.protobuf.Timestamp begun_at = 3;
  optional google.protobuf.Timestamp ended_at = 4;
  bool is_active = 5;
  bool is_available = 6;
  bool is_free_trial = 7;
  SubscriptionStatus status = 8;
  // Using string for decimal to avoid precision loss.
  string base_price = 9;
  // Using string for decimal to avoid precision loss.
  string final_price = 10;
  optional google.protobuf.Timestamp renewal_at = 11;
  string account_id = 12;
  optional string display_name = 13;
  google.protobuf.Timestamp created_at = 14;
  google.protobuf.Timestamp updated_at = 15;
}

message PaymentDetails {
  string currency = 1;
  optional string order_id = 2;
}

message Coupon {
  string id = 1;
  optional string identifier = 2;
  optional string code = 3;
  optional google.protobuf.Timestamp affected_at = 4;
  optional google.protobuf.Timestamp expired_at = 5;
  // Using string for decimal to avoid precision loss.
  optional string discount_amount = 6;
  optional google.protobuf.DoubleValue discount_rate = 7;
  optional google.protobuf.Int32Value max_usage = 8;
  google.protobuf.Timestamp created_at = 9;
  google.protobuf.Timestamp updated_at = 10;
}

message Gift {
  string id = 1;
  string gifter_id = 2;
  optional string recipient_id = 3;
  string gift_code = 4;
  optional string message = 5;
  string subscription_identifier = 6;
  string base_price = 7;
  string final_price = 8;
  GiftStatus status = 9;
  optional google.protobuf.Timestamp redeemed_at = 10;
  optional string redeemer_id = 11;
  optional string subscription_id = 12;
  google.protobuf.Timestamp expires_at = 13;
  bool is_open_gift = 14;
  string payment_method = 15;
  PaymentDetails payment_details = 16;
  optional string coupon_id = 17;
  optional Coupon coupon = 18;
  bool is_redeemable = 19;
  bool is_expired = 20;
  google.protobuf.Timestamp created_at = 21;
  google.protobuf.Timestamp updated_at = 22;
}

service WalletService {
  rpc GetWallet(GetWalletRequest) returns (Wallet);
  rpc CreateWallet(CreateWalletRequest) returns (Wallet);
  rpc GetOrCreateWalletPocket(GetOrCreateWalletPocketRequest) returns (WalletPocket);
}

message GetWalletRequest {
  string account_id = 1;
}

message CreateWalletRequest {
  string account_id = 1;
}

message GetOrCreateWalletPocketRequest {
  string wallet_id = 1;
  string currency = 2;
  optional string initial_amount = 3;
}

service PaymentService {
  rpc CreateOrder(CreateOrderRequest) returns (Order);
  rpc CreateTransactionWithAccount(CreateTransactionWithAccountRequest) returns (Transaction);
  rpc CreateTransaction(CreateTransactionRequest) returns (Transaction);
  rpc CancelOrder(CancelOrderRequest) returns (Order);
  rpc RefundOrder(RefundOrderRequest) returns (RefundOrderResponse);
  rpc Transfer(TransferRequest) returns (Transaction);
  rpc GetWalletFund(GetWalletFundRequest) returns (WalletFund);
}

message CreateOrderRequest {
  optional string payee_wallet_id = 1;
  string currency = 2;
  string amount = 3;
  optional google.protobuf.Duration expiration = 4;
  optional string app_identifier = 5;
  optional string product_identifier = 8;
  // Using bytes for meta to represent JSON.
  optional bytes meta = 6;
  optional string remarks = 9;
  bool reuseable = 7;
}

message Order {
  string id = 1;
  google.protobuf.StringValue payee_wallet_id = 2;
  google.protobuf.StringValue currency = 3;
  string amount = 4;
  google.protobuf.Timestamp expired_at = 5;
  google.protobuf.StringValue app_identifier = 6;
  google.protobuf.StringValue product_identifier = 12;
  // Using bytes for meta to represent JSON.
  optional bytes meta = 7;
  OrderStatus status = 8;
  google.protobuf.StringValue transaction_id = 9;
  optional Transaction transaction = 10;
  google.protobuf.StringValue  remarks = 11;
}

enum OrderStatus {
  ORDER_STATUS_UNSPECIFIED = 0;
  ORDER_STATUS_UNPAID = 1;
  ORDER_STATUS_PAID = 2;
  ORDER_STATUS_EXPIRED = 3;
  ORDER_STATUS_CANCELLED = 4;
  ORDER_STATUS_FINISHED = 5;
}

message Transaction {
  string id = 1;
  google.protobuf.StringValue payer_wallet_id = 2;
  google.protobuf.StringValue payee_wallet_id = 3;
  string currency = 4;
  string amount = 5;
  google.protobuf.StringValue remarks = 6;
  TransactionType type = 7;
  google.protobuf.Timestamp created_at = 8;
  google.protobuf.Timestamp updated_at = 9;
}

enum TransactionType {
  TRANSACTION_TYPE_UNSPECIFIED = 0;
  TRANSACTION_TYPE_SYSTEM = 1;
  TRANSACTION_TYPE_ORDER = 2;
  TRANSACTION_TYPE_TRANSFER = 3;
}

message CreateTransactionWithAccountRequest {
  google.protobuf.StringValue payer_account_id = 1;
  google.protobuf.StringValue payee_account_id = 2;
  string currency = 3;
  string amount = 4;
  google.protobuf.StringValue remarks = 5;
  TransactionType type = 6;
}

message CreateTransactionRequest {
  google.protobuf.StringValue payer_wallet_id = 1;
  google.protobuf.StringValue payee_wallet_id = 2;
  string currency = 3;
  string amount = 4;
  google.protobuf.StringValue remarks = 5;
  TransactionType type = 6;
}

message CancelOrderRequest {
  string order_id = 1;
}

message RefundOrderRequest {
  string order_id = 1;
}

message RefundOrderResponse {
  Order order = 1;
  Transaction refund_transaction = 2;
}

message TransferRequest {
  string payer_account_id = 1;
  string payee_account_id = 2;
  string currency = 3;
  string amount = 4;
}

message GetWalletFundRequest {
  string fund_id = 1;
}
