####
# Custom data types for Surcharges data
####

"A list of the possible property types for surcharges"
enum SurchargePropertyType {
  "Boolean"
  bool

  "Float"
  float

  "Integer"
  int

  "String"
  string
}

###
# Types
###
"Defines a surcharge that has been applied to a Cart or Order"
type AppliedSurcharge implements Node {
  "The surcharge ID"
  _id: ID!

  "The amount of the surcharge"
  amount: Money!

  "The fulfillmentGroupId (for reference)"
  fulfillmentGroupId: ID

  "The message to explain the surchage to customers, translated (if available) based on shop language"
  message(
    """
    The language in which you want the message. If no translation is available for this language,
    it will be in the default language of the related shop.
    """
    language: String!
  ): String

  "The surchargeId from the surchages collection (for reference)"
  surchargeDefinitionId: ID!
}

"Defines a surcharge for surchargeById and surcharges query."
type Surcharge implements Node {
  "The surcharge ID."
  _id: ID!

  "Amount."
  amount: Money!

  "Attribute restrictions."
  attributes: [SurchargeAttributeRestrictions]

  "The date and time at which this surcharge was created"
  createdAt: DateTime!

  "Destination restrictions."
  destination: SurchargeDestinationRestrictions

  "Message translated into provided / default language."
  message(
    """
    The language in which you want the message. If no translation is available for this language,
    it will be in the default language of the related shop.
    """
    language: String!
  ): String!

  "Messages provided with content and all languages"
  messagesByLanguage: [SurchargeMessagesByLanguage]

  "Method IDs to apply this surcharge to."
  methodIds: [ID]

  "The shop ID"
  shopId: ID!

  """
  The type of this surcharge. Allowed types `surcharge`.
  """
  type: SurchargeTypeEnum!

  "The date and time at which this surcharge was last updated"
  updatedAt: DateTime
}

"Attribute Restrictions attached to a Surcharge"
type SurchargeAttributeRestrictions {
  "The operator to use for value comparison"
  operator: String

  "The property to check"
  property: String

  "The type of this property"
  propertyType: SurchargePropertyType

  "The value to check for"
  value: String
}

"""
Wraps a list of `Surcharge`s, providing pagination cursors and information.

For information about what Relay-compatible connections are and how to use them, see the following articles:
- [Relay Connection Documentation](https://facebook.github.io/relay/docs/en/graphql-server-specification.html#connections)
- [Relay Connection Specification](https://facebook.github.io/relay/graphql/connections.htm)
- [Using Relay-style Connections With Apollo Client](https://www.apollographql.com/docs/react/recipes/pagination.html)
"""
type SurchargeConnection {
  "The list of nodes that match the query, wrapped in an edge to provide a cursor string for each"
  edges: [SurchargeEdge]

  """
  You can request the `nodes` directly to avoid the extra wrapping that `NodeEdge` has,
  if you know you will not need to paginate the results.
  """
  nodes: [Surcharge]

  "Information to help a client request the next or previous page"
  pageInfo: PageInfo!

  "Total count for all pages"
  totalCount: Int!
}

"""
Destination restrictions attached to a surcharge. If multiple of `country`,
`region`, and `postal` are set, there is an AND relationship.
"""
type SurchargeDestinationRestrictions {
  "Restrict for any of these destination countries"
  country: [String]

  "Restrict for any of these destination postal codes"
  postal: [String]

  "Restrict for any of these destination regions"
  region: [String]
}

"A connection edge in which each node is a `Surcharge` object"
type SurchargeEdge {
  "The cursor that represents this node in the paginated results"
  cursor: ConnectionCursor!

  "The surcharge"
  node: Surcharge
}

"Object that includes translated content and language of translation"
type SurchargeMessagesByLanguage {
  "The message for this language"
  content: String!

  "The language code"
  language: String!
}

###
# Extensions of existing types
###
extend type Cart {
  "Surcharges applied to this cart"
  surcharges: [AppliedSurcharge]!
}

extend type Order {
  "Surcharges applied to this order"
  surcharges: [AppliedSurcharge]!
}

extend type CartSummary {
  """
  The combined total of all surcharges. This may be null, and there is a difference
  between null and 0. Null means `not able to calculate`, such as when no fulfillment method has
  been selected for some fulfillment groups.
  """
  surchargeTotal: Money
}

extend type OrderSummary {
  "The total of all suurcharges applied"
  surchargeTotal: Money
}

###
# Enums
###
"Allowed values for surcharge `sortBy` parameter"
enum SurchargeSortByField {
  "The date the surcharge definition was created"
  createdAt
}

"Allowed values for surcharge type"
enum SurchargeTypeEnum {
  "Surcharge"
  surcharge
}


###
# Inputs
###
"Input for the `CreateSurcharge` mutation"
input CreateSurchargeInput {
  "An optional string identifying the mutation call, which will be returned in the response payload"
  clientMutationId: String

  "The shop to create this surcharge for"
  shopId: ID!

  "This defines the surcharge that you want to create"
  surcharge: SurchargeInput!
}

"Input for the `deleteSurcharge` mutation"
input DeleteSurchargeInput {
  "An optional string identifying the mutation call, which will be returned in the response payload"
  clientMutationId: String

  "The shop that owns the method"
  shopId: ID!

  "The ID of the flat rate fulfillment method you want to delete"
  surchargeId: ID!
}

"Input to add a surcharge message with language"
input MessagesByLanguageInput {
  "The message for this language"
  content: String!

  "The language code"
  language: String!
}

"Input to add a surcharge attribute restriction"
input SurchargeAttributeRestrictionsInput {
  "The operator to use for value comparison"
  operator: String

  "The property to check"
  property: String

  "The type of this property"
  propertyType: SurchargePropertyType

  "The value to check for"
  value: String
}

"Input to add a surcharge destination restriction"
input SurchargeDestinationRestrictionsInput {
  "Restrict for any of these destination countries"
  country: [String]

  "Restrict for any of these destination postal codes"
  postal: [String]

  "Restrict for any of these destination regions"
  region: [String]
}

"Defines a surcharge."
input SurchargeInput {
  "Amount."
  amount: Float!

  "Attribute restrictions."
  attributes: [SurchargeAttributeRestrictionsInput]

  "Destination restrictions."
  destination: SurchargeDestinationRestrictionsInput

  "Messages by language."
  messagesByLanguage: [MessagesByLanguageInput]!

  "Method IDs to apply this surcharge to."
  methodIds: [ID]

  """
  The type of this surcharge. Allowed types are `surcharge`.
  """
  type: SurchargeTypeEnum!
}

"Input for the `updateSurcharge` mutation"
input UpdateSurchargeInput {
  "An optional string identifying the mutation call, which will be returned in the response payload"
  clientMutationId: String

  "The shop that owns the method"
  shopId: ID!

  "The updated surcharge. Pass the whole updated surcharge object without the ID."
  surcharge: SurchargeInput!

  "The ID of the flat rate fulfillment surcharge you want to update"
  surchargeId: ID!
}


####
# Queries
####
extend type Query {
  "Get the full list of surcharges."
  surcharges(
    "ID of shop to get surcharges for"
    shopId: ID!,

    "Return only results that come after this cursor. Use this with `first` to specify the number of results to return."
    after: ConnectionCursor,

    "Return only results that come before this cursor. Use this with `last` to specify the number of results to return."
    before: ConnectionCursor,

    "Return at most this many results. This parameter may be used with either `after` or `offset` parameters."
    first: ConnectionLimitInt,

    "Return at most this many results. This parameter may be used with the `before` parameter."
    last: ConnectionLimitInt,

    "Return only results that come after the Nth result. This parameter may be used with the `first` parameter."
    offset: Int,

    "Return results sorted in this order"
    sortOrder: SortOrder = desc,

    "By default, surcharges are sorted by when they were created, newest first. Set this to sort by one of the other allowed fields"
    sortBy: SurchargeSortByField = createdAt
  ): SurchargeConnection!

  "Get a single surcharge definition by its ID"
  surchargeById(
    "ID of shop that owns the surcharge definition"
    shopId: ID!,

    "The surcharge ID"
    surchargeId: ID!
  ): Surcharge
}


####
# Mutations
####
extend type Mutation {
  "Create a surcharge"
  createSurcharge(
    "Mutation input"
    input: CreateSurchargeInput!
  ): CreateSurchargePayload!

  "Delete a flat rate fulfillment restriction"
  deleteSurcharge(
    "Mutation input"
    input: DeleteSurchargeInput!
  ): DeleteSurchargePayload!

  "Update a flat rate fulfillment surcharge"
  updateSurcharge(
    "Mutation input"
    input: UpdateSurchargeInput!
  ): UpdateSurchargePayload!
}


####
# Payloads
####
"Response from the `CreateSurcharge` mutation"
type CreateSurchargePayload {
  "The same string you sent with the mutation params, for matching mutation calls with their responses"
  clientMutationId: String

  "The created surcharge"
  surcharge: Surcharge!
}

"Response from the `deleteSurcharge` mutation"
type DeleteSurchargePayload {
  "The same string you sent with the mutation params, for matching mutation calls with their responses"
  clientMutationId: String

  "The removed fulfillment method"
  surcharge: Surcharge!
}

"Response from the `updateFlatRateFulfillmentMethod` mutation"
type UpdateSurchargePayload {
  "The same string you sent with the mutation params, for matching mutation calls with their responses"
  clientMutationId: String

  "The updated fulfillment surcharge"
  surcharge: Surcharge!
}
