syntax = "proto3";

package wix.dealerBackoffice.api.v1;

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


import "wix/api/annotations.proto";
import "wix/api/validations.proto";
import "wix/api/entity.proto";

import "wix/dealerBackoffice/api/v1/managers.proto";
import "wix/dealerBackoffice/api/v1/frequency-caps.proto";
import "wix/personalize/targeting/v1/targeting.proto";

option java_package = "com.wix.dealerBackoffice.api.v1";



// Offer is a specific asset (payload) intended to be served to a user + targeting rules (to allow dealer
// to decide if offer is eligible for given user).
//
// Targeting is a set of conditions (rules) a user must satisfy to get an offer (offer is called "eligible"
// for the user). Asset is the actual content returned to the user.
// Offer always belongs to single dealer Placement (real estate). Offer can be standalone or part of dealer Campaign.
message Offer {
  option (wix.api.entity) = {fqdn:"wix.dealer.v1.backoffice_offer", segment: USERS};

  // Unique offer guid
  google.protobuf.StringValue guid = 1 [(wix.api.format) = GUID, (wix.api.readOnly) = true];

  // Dealer placement id. Required.
  string placement_id = 2 [(wix.api.format) = GUID];

  // Dealer campaign id. Optional.
  // To update — use connect/disconnect campaign endpoints.
  google.protobuf.StringValue campaign_id = 3 [(wix.api.format) = GUID];

  // Audience ids derived from targeting of the offer.
  // All audiences found in the offer (meaning user will be checked to belong to one of them when dealer
  // runtime is called)
  // Default "empty" value (also on partial projection responses) is always empty array [] (protobuff
  // feature).
  // Readonly.
  repeated string audience_ids = 4 [(wix.api.format) = GUID, (wix.api.readOnly) = true];

  // Backoffice name of offer. Required (may be null on partial projection response)
  google.protobuf.StringValue name = 5 [(wix.api.minLength) = 1];

  // Backoffice description of an offer. Optional.
  google.protobuf.StringValue description = 6;

  // Personalized user content - can be more then one in case of ab test
  Asset asset = 8;

  // Offer should be available to users starting from this time
  google.protobuf.Timestamp start_date = 9;

  // Offer should stop being available to users after this time
  google.protobuf.Timestamp stop_date = 10;

  // Derived status from start_date, stop_date and offer lifecycle state.
  // Default "empty" value (also on partial projection responses) is UNKNOWN (protobuff feature)
  Status status = 12 [(wix.api.readOnly) = true];

  // Readonly priority of the offer within a placement. Can be changed using prioritize endpoint.
  // Higher value means higher priority (10 should be on top of 1)
  // Archived offers dont have priority.
  google.protobuf.Int32Value priority_in_placement = 13 [(wix.api.readOnly) = true];

  // KPI id from wix bi bank https://bo.wix.com/wix-docs/rest/drafts/bibank
  google.protobuf.StringValue kpi_id = 14 [(wix.api.format) = GUID];

  // The user id who created this offer. Readonly.
  google.protobuf.StringValue created_by = 15 [(wix.api.format) = GUID, (wix.api.readOnly) = true];

  // The last user id who last updated this offer. Readonly.
  google.protobuf.StringValue updated_by = 16 [(wix.api.format) = GUID, (wix.api.readOnly) = true];

  // The creation date of the offer. Readonly.
  google.protobuf.Timestamp created_date = 17 [(wix.api.readOnly) = true];

  // The last update date of the offer. Readonly.
  google.protobuf.Timestamp updated_date = 18 [(wix.api.readOnly) = true];

  // Current frequency caps config of the offer (if own offer frequency_caps_config is empty - offer's
  // placement frequency_caps_config is returned)
  FrequencyCapsConfig frequency_caps_config = 19;

  // Wix users responsible for the offer (PMMs usually).
  ManagerIdsWrapper managers_ids = 20;

  // Unique human and URL friendly shortname of the offer
  google.protobuf.StringValue slug = 21 [(wix.api.readOnly) = true];

  // Unique targeting id
  google.protobuf.StringValue targeting_id = 22 [(wix.api.format) = GUID, (wix.api.readOnly) = true];

  ExperimentFilter experiment_criteria = 24;

  wix.personalize.targeting.v1.TargetingTree targeting_entity = 25;

  reserved 26;

  google.protobuf.StringValue exposure_id = 27 [(wix.api.format) = GUID, (wix.api.readOnly) = true];

  // Current offer state in lifecycle
  enum Status {
    UNKNOWN = 0;

    // Offer has internal status PAUSED (not being served by dealer runtime)
    PAUSED = 1;

    // Offer has internal status WIX_EMPLOYEE (served by runtime to employees only)
    WIX_EMPLOYEE = 2;

    // Offer has internal status READY, start_date and start_date is in the future
    // (not being served by dealer runtime until start_date)
    SCHEDULED = 3;

    // Offer has internal status READY and neither start_date in the future, nor stop_date in the past
    // (being served by dealer runtime)
    LIVE = 4;

    // Offer has internal status READY, stop_date and stop_date is in the past
    // (not being served by dealer runtime)
    ENDED = 5;

    // Offer has internal status ARCHIVED (not being served by dealer runtime)
    ARCHIVED = 6;

    // Offer has internal status IN_REVIEW (not being served by dealer runtime)
    IN_REVIEW = 7;
  }

  message FrequencyCapsConfig {
    FrequencyCaps frequency_caps = 1;
  }
}

// Asset content wrapper for A/B test offers
message AbTestAsset {
  // A variant payload
  AssetContent a = 1;
  // B variant payload
  AssetContent b = 2;

  // Petri spec name for this A/B test
  string spec = 3 [(wix.api.minLength) = 1, (wix.api.readOnly) = true];
}

// Actual payload of the offer
message AssetContent {
  // the personlized content for the user - json string
  google.protobuf.StringValue payload_json = 1 [(wix.api.minLength) = 1];
}

// Offer payload data wrapper
message Asset {
  // The asset type in that placement. It's a readonly field derived from offer placement.
  // i.e: Asset type for the placement "Dashboard Main - Top Right" is "banner"
  google.protobuf.StringValue asset_type = 1 [(wix.api.minLength) = 1, (wix.api.readOnly) = true];

  oneof asset_content {
    // A/B assets (only for "banner" asset type)
    AbTestAsset abtest = 2;
    // actual asset payload
    AssetContent content = 3;
  }

  reserved 4;

  // Dynamic params of the offer
  DynamicParamsWrapper dynamic_params_wrapper = 5;

  // Localized content of the offer is an arbitrary JSON like payload for specific locale value
  map<string, LocalizedContentData> localized_content = 6;
}

message TranslationMetadata {
  TranslationStatus translation_status = 1;
  google.protobuf.Timestamp translation_request_date = 2;
  google.protobuf.Timestamp translation_completed_date = 3;
  repeated string localization_managers_ids = 4;

  enum TranslationStatus {
    PENDING = 0;
    TRANSLATED = 1;
    OUTDATED = 2;
    PENDING_TRANSLATION = 3;
    PENDING_UPDATES = 4;
    UP_TO_DATE = 5;
  }
}

message LocalizedContentData {
  google.protobuf.Struct content = 1;
  TranslationMetadata metadata = 2 [(wix.api.readOnly) = true];
}

message DynamicParamsWrapper {
  repeated DynamicParam dynamic_params = 1;
}

// Type of dynamic param, what kind of data [interpolation_key] represents. Wether it's a domain name, user
// email etc.
message DynamicParamType {
  enum Enum {
    UNKNOWN = 0;
    DOMAIN_NAME = 1;
    SITE_NAME = 2;
    USER_EMAIL = 3;
    SEASONAL_SALE_END_DATE = 4;
    BI_PROFILE = 5;
    BUSINESS_NAME = 6;
    USER_FIRST_NAME = 7;
    USER_LAST_NAME = 8;
  }
}

message RoundFormat {
  // required field default is 0
  int32 decimal_places = 1 [(wix.api.min) = 0];
}

message RangeLimitFormat {
  google.protobuf.Int32Value min = 1 ;
  google.protobuf.Int32Value max = 2 ;
}

message PercentageFormat {
  bool active = 1;
}

message DynamicParamFormatting {
  // will round a number to X decimal places
  // fro example when dynamic param value is 15.88 and round.decimal_places is 1 the result is 15.9
  RoundFormat round = 2;

  // dont return dynamic param value if value out of range
  RangeLimitFormat range_limit = 3;

  // multiply the dynamic param value by 100
  PercentageFormat percentage = 4;
}

// Individual dynamic parameter of the offer.
// Value that should be interpolated by dealer at runtime and instead of [interpolation_key]
// actual value from BI profile should be inserted everywhere in payload returned to client.
message DynamicParam {
  string interpolation_key = 1 [(wix.api.minLength) = 1];

  DynamicParamType.Enum type = 2;

  oneof metadata {
    BiMetadata bi = 3;
  }

  // formatting for dynamic param value
  // when using multiple formatting together the order is round then range then percentage
  DynamicParamFormatting formatting = 4;
}

message BiMetadata {
  string bi_profile_key = 1;

  enum Level {
    UNKNOWN_LEVEL = 0;
    SITE = 1;
    USER = 2;
  }

  Level level = 2;
}

message KeyValue {
  string key = 1 [(wix.api.minLength) = 1];
  string value = 2 [(wix.api.minLength) = 1];
}

message OfferOperationEvent {
  Offer offer = 1;
  Operation operation = 2;

  enum Operation {
    UNKNOWN = 0;
    CREATED = 1;
    UPDATED = 2;
    ARCHIVED = 3;
  }
}

message ExperimentFilter {
  google.protobuf.StringValue spec = 1 [(.wix.api.maxLength) = 256];
  google.protobuf.StringValue value = 2 [(.wix.api.maxLength) = 256];
}