"""Base address properties"""
interface Address {
  """City"""
  city: String

  """Company"""
  company: String

  """Fax"""
  fax: String

  """First Name"""
  firstname: String

  """Last Name"""
  lastname: String

  """Middle Name/Initial"""
  middlename: String

  """Zip/Postal Code"""
  postcode: String

  """Prefix"""
  prefix: String

  """Suffix"""
  suffix: String

  """Telephone"""
  telephone: String

  """VAT number"""
  vatId: String

  """Street"""
  street: [String!]!

  """Region"""
  region: AddressRegion

  """Country"""
  country: Country!
}

"""An address region"""
type AddressRegion {
  """Region code, ISO 3166-2"""
  code: String!

  """Region name"""
  name: String!
}

"""Enum representing possible validation errors for an address"""
enum AddressValidationError {
  """City is missing a value"""
  errorMissingCity

  """Country is missing a value"""
  errorMissingCountry

  """Firstname is missing a value"""
  errorMissingFirstname

  """Lastname is missing a value"""
  errorMissingLastname

  """Postcode is missing a value"""
  errorMissingPostcode

  """Region is missing a value"""
  errorMissingRegion

  """Street is missing a value"""
  errorMissingStreet

  """Telephone is missing a value"""
  errorMissingTelephone
}

"""A country in an address"""
type Country {
  """Country code, ISO 3166-2"""
  code: ID!

  """Country name for the current locale"""
  name: String!
}

"""Type containing the result of createCustomerAddress"""
type CreateCustomerAddressResult {
  """The type of result"""
  result: CreateCustomerAddressResultType!

  """The customer result, if no error occurred"""
  customer: Customer

  """
  The set address customer address, if no error occurred or if address failed to validate
  """
  address: CustomerAddress

  """List of validation errors if the address failed to validate"""
  validationErrors: [AddressValidationError!]!
}

"""Type of result from removeCustomerAddress mutation"""
enum CreateCustomerAddressResultType {
  """Address"""
  success

  """Customer is not logged in."""
  errorNotLoggedIn

  """The supplied address id is invalid."""
  errorInvalidAddress
}

"""Type containing customer information"""
type Customer {
  """Date Of Birth"""
  dob: String

  """First Name"""
  firstname: String!

  """Gender"""
  gender: String

  """Last Name"""
  lastname: String!

  """Middle Name/Initial"""
  middlename: String

  """Prefix"""
  prefix: String

  """Suffix"""
  suffix: String

  """List of addresses for the customer."""
  addresses: [CustomerAddress!]!

  """Customer email"""
  email: String!

  """Customer created date"""
  createdAt: String!
}

"""A customer address"""
type CustomerAddress implements Address {
  """City"""
  city: String

  """Company"""
  company: String

  """Fax"""
  fax: String

  """First Name"""
  firstname: String

  """Last Name"""
  lastname: String

  """Middle Name/Initial"""
  middlename: String

  """Zip/Postal Code"""
  postcode: String

  """Prefix"""
  prefix: String

  """Suffix"""
  suffix: String

  """Telephone"""
  telephone: String

  """VAT number"""
  vatId: String

  """Street"""
  street: [String!]!

  """Region"""
  region: AddressRegion

  """Country"""
  country: Country!

  """Address id, used to update/delete"""
  id: ID!

  """If the address is the default billing address"""
  isDefaultBilling: Boolean!

  """If the address is the default shipping address"""
  isDefaultShipping: Boolean!
}

"""Object containing a partially or fully populated address"""
input CustomerAddressInput {
  """Prefix"""
  prefix: String

  """First Name"""
  firstname: String

  """Middle Name/Initial"""
  middlename: String

  """Last Name"""
  lastname: String

  """Suffix"""
  suffix: String

  """Company"""
  company: String

  """City"""
  city: String

  """Zip/Postal Code"""
  postcode: String

  """Telephone"""
  telephone: String

  """Fax"""
  fax: String

  """VAT number"""
  vatId: String

  """Street, one line per array item"""
  street: [String!]

  """Region code"""
  regionCode: ID

  """Country code"""
  countryCode: ID
}

"""Type containing the result of a login operation"""
type LoginCustomerResult {
  """The result type"""
  result: LoginCustomerResultType!

  """Present if it is a success"""
  customer: Customer
}

"""Type indicating the result of a login operation"""
enum LoginCustomerResultType {
  """A successful login"""
  success

  """Invalid email or password."""
  errorInvalidEmailOrPassword

  """The account is not yet confirmed by email."""
  errorUserNotConfirmed

  """Login mutation is not enabled"""
  errorLoginNotEnabled
}

"""Root mutation type."""
type Mutation {
  """Attempts to log in a customer"""
  loginCustomer(
    """The email of the customer account"""
    email: String!

    """The password"""
    password: String!
  ): LoginCustomerResult!

  """Attempts to log out a customer"""
  logoutCustomer: Boolean!

  """Updates the customer information for the currently logged in customer"""
  updateCustomer(
    """The new customer information"""
    customer: UpdateCustomerInput!
  ): UpdateCustomerResult!

  """
  Updates the email for the currently logged in customer, this will also propagate to any quote.
  """
  updateCustomerEmail(
    """The new email for the account"""
    email: String!
  ): UpdateCustomerEmailResult!

  """
  Attempts to set the given address id as the default billing address for the currently logged in customer
  """
  setCustomerDefaultBillingAddress(
    """The id of the customer address to use as default billing address"""
    id: ID!
  ): SetCustomerDefaultAddressResult!

  """
  Attempts to set the given address id as the default shipping address for the currently logged in customer
  """
  setCustomerDefaultShippingAddress(
    """The id of the customer address to use as default shipping address"""
    id: ID!
  ): SetCustomerDefaultAddressResult!

  """Creates a customer address"""
  createCustomerAddress(
    """The new address data"""
    address: CustomerAddressInput!

    """
    If the newly created address should be set as the default billing address
    """
    setDefaultBilling: Boolean = false

    """
    If the newly created address should be set as the default shipping address
    """
    setDefaultShipping: Boolean = false
  ): CreateCustomerAddressResult!

  """Updates a customer address with new data"""
  updateCustomerAddress(
    """The id of the customer address to update"""
    id: ID!

    """Address data to update"""
    address: CustomerAddressInput!
  ): UpdateCustomerAddressResult!

  """Attempts to delete a customer address"""
  removeCustomerAddress(
    """The id of the customer address"""
    id: ID!
  ): RemoveCustomerAddressResult!

  """Attempts to subscribe to newsletter"""
  subscribeToNewsletter(
    """The subscriber email"""
    email: String

    """The subscriber firstname"""
    firstname: String

    """The subscriber lastname"""
    lastname: String
  ): SubscribeToNewsletterResult!
}

"""Price information which carries tax information"""
interface Price {
  """Price excluding VAT"""
  exVat: Float!

  """Price including VAT"""
  incVat: Float!

  """VAT amount"""
  vat: Float!
}

"""Root query type."""
type Query {
  """Information about the current store"""
  info: StoreInfo!

  """Attempt to fetch a resource by its route"""
  route(
    """Path to resource"""
    path: String!
  ): Route

  """Customer information if a customer is logged in"""
  customer: Customer
}

"""Type containing the result of a customer address removal."""
type RemoveCustomerAddressResult {
  """The type of result from removeCustomerAddress"""
  result: RemoveCustomerAddressResultType!
}

"""Type of result from removeCustomerAddress mutation"""
enum RemoveCustomerAddressResultType {
  """Address was successfully removed."""
  success

  """Customer is not logged in."""
  errorNotLoggedIn

  """The supplied address id is invalid."""
  errorInvalidAddressId
}

"""Response from a route"""
interface Route {
  """Type of route resource"""
  type: RouteType!
}

"""A response containing a category"""
type RouteRedirect implements Route {
  """If the redirect is a permanent redirect"""
  isPermanent: Boolean!

  """Type of route"""
  type: RouteType!

  """Redirect to"""
  url: String!
}

"""Type indicating variant of route resource"""
enum RouteType {
  """A category"""
  category

  """A CMS page"""
  cms_page

  """A product"""
  product

  """A redirect to another path"""
  redirect
}

"""
Result of setCustomerDefaultShippingAddress or setCustomerDefaultBillingAddress.
"""
type SetCustomerDefaultAddressResult {
  """The type of result"""
  result: SetCustomerDefaultAddressResultType!

  """The customer result, if no error occurred"""
  customer: Customer

  """The set address customer address, if no error occurred"""
  address: Address
}

"""Type of result from updateCustomerEmail mutation"""
enum SetCustomerDefaultAddressResultType {
  """Default address was successfully updated."""
  success

  """Default address was not modified."""
  notModified

  """Customer is not logged in."""
  errorNotLoggedIn

  """The supplied address id is invalid."""
  errorInvalidAddressId
}

"""Basic store information"""
type StoreInfo {
  """Base currency code"""
  baseCurrencyCode: String!

  """Base URL"""
  baseUrl: String!

  """Store code"""
  code: String!

  """Currency codes"""
  currencyCodes: [String!]!

  """List of available countries for the store"""
  countries: [Country!]!

  """Default country for the store"""
  defaultCountry: Country!

  """Default page description"""
  defaultDescription: String

  """Default page title"""
  defaultTitle: String

  """Locale code for the store"""
  locale: String!

  """Name"""
  name: String!

  """Price lock"""
  pricelock: Boolean

  """Page title prefix"""
  titlePrefix: String

  """Page title suffix"""
  titleSuffix: String
}

"""Type containing the result of subscribing to newsletters"""
type SubscribeToNewsletterResult {
  """The type of result"""
  result: SubscribeToNewslettersResultType!
}

"""Type of result from subscribeToNewsletter mutation"""
enum SubscribeToNewslettersResultType {
  """Email was successfully subcribed."""
  success

  """Subscription not modified."""
  notModified

  """Invalid email."""
  invalidEmail

  """Customer not logged in."""
  notLoggedIn
}

"""Result of updateCustomerAddress mutation"""
type UpdateCustomerAddressResult {
  """The type of result"""
  result: UpdateCustomerAddressResultType!

  """The customer result, if no error occurred"""
  customer: Customer

  """The updated customer address, if no error occurred"""
  address: CustomerAddress

  """List of validation errors if the address failed to validate"""
  validationErrors: [AddressValidationError!]!
}

"""Type of result from updateCustomerAddress mutation"""
enum UpdateCustomerAddressResultType {
  """Address was successfully updated"""
  success

  """Address was not modified"""
  notModified

  """Customer is not logged in."""
  errorNotLoggedIn

  """The supplied address id is invalid."""
  errorInvalidAddressId

  """The supplied address id is invalid."""
  errorInvalidAddress
}

"""Result of updateCustomerEmail mutation"""
type UpdateCustomerEmailResult {
  """The type of result"""
  result: UpdateCustomerEmailResultType!

  """The customer result, if no error occurred"""
  customer: Customer
}

"""Type of result from updateCustomerEmail mutation"""
enum UpdateCustomerEmailResultType {
  """Email was successfully updated."""
  success

  """Email was not modified."""
  notModified

  """Customer is not logged in."""
  errorNotLoggedIn

  """The supplied email address is invalid."""
  errorInvalidEmail

  """The supplied email is used by another customer"""
  errorEmailExists

  """The updateCustomerEmail mutation is disabled"""
  errorDisabled
}

"""New data for customer"""
input UpdateCustomerInput {
  """Prefix"""
  prefix: String

  """First Name"""
  firstname: String

  """Middle Name/Initial"""
  middlename: String

  """Last Name"""
  lastname: String

  """Suffix"""
  suffix: String

  """Date Of Birth"""
  dob: String

  """Tax/VAT Number"""
  taxvat: String

  """Gender"""
  gender: String
}

"""Result of updateCustomer mutation"""
type UpdateCustomerResult {
  """The result type"""
  result: UpdateCustomerResultType!

  """Present if it is a success"""
  customer: Customer
}

"""Type of result from updateCustomer mutation"""
enum UpdateCustomerResultType {
  """Address was successfully updated"""
  success

  """Address was not modified"""
  notModified

  """Customer is not logged in."""
  errorNotLoggedIn
}
