export type RawMessengerAttributes = {
  custom_launcher_selector?: string;
  alignment?: string;
  vertical_padding?: number;
  horizontal_padding?: number;
  hide_default_launcher?: boolean;
  session_duration?: number;
  action_color?: string;
  background_color?: string;
};

export type MessengerAttributes = {
  /** The CSS selector of an element to trigger Intercom("show") in order to activate the messenger
   *
   * @remarks To target an element by ID: "#id_of_element". To target elements by class ".classname_of_elements"
   * @see {@link https://docs.intercom.com/configure-intercom-for-your-product-or-site/customize-the-intercom-messenger/customize-the-intercom-messenger-technical}
   */
  customLauncherSelector?: string;
  /** Dictate the alignment of the default launcher icon to be on the left/right
   *
   * @remarks Possible values: "left" or "right" (any other value is treated as right)
   * @see {@link https://docs.intercom.com/configure-intercom-for-your-product-or-site/customize-the-intercom-messenger/customize-the-intercom-messenger-technical}
   */
  alignment?: string;
  /** Move the default launcher icon vertically
   *
   * @remarks Padding from bottom of screen. Minimum value: 20. Does not work on mobile
   * @see {@link https://docs.intercom.com/configure-intercom-for-your-product-or-site/customize-the-intercom-messenger/customize-the-intercom-messenger-technical}
   */
  verticalPadding?: number;
  /** Move the default launcher icon horizontally
   *
   * @remarks Padding from right side of screen. Minimum value: 20. Does not work on mobile
   * @see {@link https://docs.intercom.com/configure-intercom-for-your-product-or-site/customize-the-intercom-messenger/customize-the-intercom-messenger-technical}
   */
  horizontalPadding?: number;
  /** Hide the default launcher icon
   *
   * @remarks Setting to false will forcefully show the launcher icon
   * @see {@link https://docs.intercom.com/configure-intercom-for-your-product-or-site/customize-the-intercom-messenger/turn-off-show-or-hide-the-intercom-messenger}
   */
  hideDefaultLauncher?: boolean;
  /** Time in milliseconds for the Intercom session to be considered active
   *
   * @remarks A value of `5 * 60 * 1000` would set the expiry time to be 5 minutes
   */
  sessionDuration?: number;
  /** Used in button links and more to highlight and emphasise
   *
   * @remarks The color string can be any valid CSS: "color name", "hex" or "rgb"
   * @see {@link https://www.w3schools.com/cssref/css_colors.asp}
   */
  actionColor?: string;
  /** Used behind your team profile and other attributes
   *
   * @remarks The color string can be any valid CSS: "color name", "hex" or "rgb"
   * @see {@link https://www.w3schools.com/cssref/css_colors.asp}
   */
  backgroundColor?: string;
};

export type RawDataAttributesCompany = {
  company_id: string;
  name?: string;
  created_at?: string;
  plan?: string;
  monthly_spend?: number;
  user_count?: number;
  size?: number;
  website?: string;
  industry?: string;
};

export type DataAttributesCompany = {
  /** The company ID of the company */
  companyId: string;
  /** The name of the company */
  name?: string;
  /** The time the company was created in your system */
  createdAt?: string;
  /** The name of the plan the company is on */
  plan?: string;
  /** How much revenue the company generates for your business */
  monthlySpend?: number;
  /** Indicates the number of users in Intercom associated to the company
   *
   * @remarks Does not actually update the value but is a reserved keyword
   */
  userCount?: number;
  /** The number of employees in the company */
  size?: number;
  /** The URL for the company website */
  website?: string;
  /** The industry of the company */
  industry?: string;
  /** Custom attributes */
  customAttributes?: Record<string, any>;
};

export type RawDataAttributesAvatar = {
  type: string;
  image_url?: string;
};

export type DataAttributesAvatar = {
  /** The value is "avatar" */
  type: string;
  /** An avatar image URL
   *
   * @remarks Needs to be https */
  imageUrl?: string;
};

export type RawDataAttributes = {
  email?: string;
  user_id?: string;
  created_at?: string;
  name?: string;
  phone?: string;
  last_request_at?: string;
  unsubscribed_from_emails?: boolean;
  language_override?: string;
  utm_campaign?: string;
  utm_content?: string;
  utm_medium?: string;
  utm_source?: string;
  utm_term?: string;
  avatar?: RawDataAttributesAvatar;
  user_hash?: string;
  company?: RawDataAttributesCompany;
  companies?: RawDataAttributesCompany[];
  customAttributes?: Record<string, any>;
};

export type DataAttributes = {
  /** The email address of the currently logged in user
   *
  @remarks Only applicable to users
  */
  email?: string;
  /** The user ID of the currently logged in user
   *
  @remarks Only applicable to users
  */
  userId?: string;
  /** The Unix timestamp (in seconds) when the user signed up to your app
   *
   * @remarks Only applicable to users
   */
  createdAt?: string;
  /** Name of the current user/lead */
  name?: string;
  /** Name of the current user/lead */
  phone?: string;
  /** This value can't actually be set by the Javascript API
   *
   * @remarks It automatically uses the time of the last request but is a this is a reserved attribute
   */
  lastRequestAt?: string;
  /** Sets the unsubscribe status of the record
   *
   * @see {@link https://www.intercom.com/help/en/articles/270-how-do-i-unsubscribe-users-from-receiving-emails}
   */
  unsubscribedFromEmails?: boolean;
  /** Set the messenger language programmatically (instead of relying on browser language settings)
   *
   * @see {@link https://www.intercom.com/help/en/articles/180-localize-intercom-to-work-with-multiple-languages}
   */
  languageOverride?: string;
  /** @see {@link https://www.intercom.com/help/en/articles/908965-track-conversions-and-clicks-with-utm-parameters}
   *
   * @remarks All UTM parameters are updated automatically and can not be manually overidden
   */
  utmCampaign?: string;
  /** @see {@link https://www.intercom.com/help/en/articles/908965-track-conversions-and-clicks-with-utm-parameters}
   */
  utmContent?: string;
  /** @see {@link https://www.intercom.com/help/en/articles/908965-track-conversions-and-clicks-with-utm-parameters}
   */
  utmMedium?: string;
  /** @see {@link https://www.intercom.com/help/en/articles/908965-track-conversions-and-clicks-with-utm-parameters}
   */
  utmSource?: string;
  /** @see {@link https://www.intercom.com/help/en/articles/908965-track-conversions-and-clicks-with-utm-parameters}
   */
  utmTerm?: string;
  /** Set the avatar/profile image associated to the current record
   *
   * @remarks Typically gathered via social profiles via email address
   * @see {@link https://www.intercom.com/help/en/articles/277-where-do-the-social-profiles-come-from}
   */
  avatar?: DataAttributesAvatar;
  /** Used for identity verification
   *
   * @see {@link https://www.intercom.com/help/en/articles/183-enable-identity-verification-for-web-and-mobile}
   * @remarks Only applicable to users
   */
  userHash?: string;
  /** Current user's company
   *
   * @remarks Only applicable to users
   * @remarks Company ID and company name are the minimum requirements to pass a company into Intercom
   * @see {@link https://developers.intercom.com/installing-intercom/docs/javascript-api-attributes-objects#section-company-object}
   */
  company?: DataAttributesCompany;
  /** An array of companies the user is associated to
   *
   * @remarks Only applicable to users
   * @see {@link https://www.intercom.com/help/en/articles/186-group-your-users-by-company}
   */
  companies?: DataAttributesCompany[];
  /**
   * You can do this anytime by adding additional key/value pairs to your intercomSettings code snippet
   * These should be raw snake_cased
   *
   * @example
   * ```
   * customAttributes={
   *   my_custom_attibute: 'my attribute value'
   * }
   * ```
   *
   * @see {@link https://www.intercom.com/help/en/articles/179-send-custom-user-attributes-to-intercom}
   * @remarks The key is the attribute name. The value is a placeholder for the data you’ll track
   */
  customAttributes?: Record<string, any>;
};

export type IntercomMethod =
  | 'boot'
  | 'shutdown'
  | 'update'
  | 'hide'
  | 'show'
  | 'showMessages'
  | 'showNewMessage'
  | 'onHide'
  | 'onShow'
  | 'onUnreadCountChange'
  | 'trackEvent'
  | 'getVisitorId'
  | 'startTour'
  | 'showArticle';

export type RawIntercomProps = RawMessengerAttributes & RawDataAttributes;

export type RawIntercomBootProps = {
  app_id: string;
  api_base?: string;
} & RawIntercomProps;

export type IntercomProps = MessengerAttributes & DataAttributes;

export type IntercomBootProps = {
  /** The app ID of your Intercom app which will indicate where to store any data  */
  appId: string;
} & IntercomProps;

export type LogLevel = 'info' | 'error' | 'warn';

export type IntercomContextValues = {
  /**
   * If you'd like to control when Intercom is loaded, you can use the 'boot' method.
   *
   * @remarks This is useful in situations like a one-page Javascript based application
   * where the user may not be logged in when the page loads.
   * @param props the standard optional intercom props
   *
   * @see {@link https://developers.intercom.com/installing-intercom/docs/intercom-javascript#section-intercomboot-intercomsettings}

   */
  boot: (props?: IntercomProps) => void;
  /**
   * If you have the Inbox product (combined with another product like Messages)
   * you should call the Intercom shutdown method to clear your users’ conversations
   * anytime they logout of your application.
   *
   * Otherwise, the cookie we use to track who was most recently logged in on a
   * given device or computer  will keep these conversations in the Messenger for one week.
   *
   * @remarks This method will effectively clear out any user data that you have been passing through the JS API.

   * @see {@link https://developers.intercom.com/installing-intercom/docs/intercom-javascript#section-intercomshutdown}
   */
  shutdown: () => void;
  /**
   * Same functionality as `shutdown` but makes sure the Intercom cookies,
   * `window.Intercom` and `window.intercomSettings` are removed.
   *
   * @see {@link https://developers.intercom.com/installing-intercom/docs/intercom-javascript#section-intercomupdate}
   */
  hardShutdown: () => void;
  /**
   * Calling the update method with a JSON object of user details will update
   * those fields on the current user in addition to logging an impression at
   * the current URL and looking for new messages for the user.
   *
   * @remarks You will need to call `update` without `props` in order to initiate a "ping" every time the URL changes.
   * Calls Intercom with a auto generated `last_request_at` property
   */
  update: (props?: Partial<IntercomProps>) => void;
  /**
   * Hides the main Messenger panel if it is open. It will not hide the Messenger Launcher.
   *
   * @see {@link https://developers.intercom.com/installing-intercom/docs/intercom-javascript#section-intercomhide}
   */
  hide: () => void;
  /**
   * Shows the Messenger.
   *
   * @remarks If there are no new conversations, it will open to the Messenger Home.
   * If there are, it will open with the message list.
   *
   * @see {@link https://developers.intercom.com/installing-intercom/docs/intercom-javascript#section-intercomshow}
   */
  show: () => void;
  /**
   * Opens the Messenger with the message list.
   */
  showMessages: () => void;
  /**
   * Opens the Messenger as if a new conversation was just created.
   *
   * @remarks This function can also take an optional second parameter, used to pre-populate the message composer as shown in the code example below..
   *
   * @see {@link https://developers.intercom.com/installing-intercom/docs/intercom-javascript#section-intercomshownewmessage}
   *
   * @example
   * ```
   * showMessages();
   * ```
   * @example
   * ```
   * showMessages('pre-populated-content');
   * ```
   */
  showNewMessages: (prePopulatedContent?: string) => void;
  /**
   * A visitor is someone who goes to your site but does not use the messenger.
   * You can track these visitors via the visitor `user_id`.
   *
   * @remarks This `user_id` can be used to retrieve the visitor or lead through the REST API.
   *
   * @see {@link https://developers.intercom.com/installing-intercom/docs/intercom-javascript#section-intercomgetvisitorid}
   */
  getVisitorId: () => string;
  /**
   * Triggers a tour based on an action a user or visitor takes in your site or application,
   * You need to call this method with the id of the tour you wish to show.
   *
   * The id of the tour can be found in the “Use tour everywhere” section of the tour editor.
   *
   * @remarks Please note that tours shown via this API must be published and
   * the “Use tour everywhere” section must be turned on.
   * If you're calling this API using an invalid tour id, nothing will happen.
   *
   * @see {@link https://developers.intercom.com/installing-intercom/docs/intercom-javascript#section-intercomstarttour-tourid}
   */
  startTour: (tourId: number) => void;
  /**
   * Submits an event, this will associate the event with the currently
   * tracked visitor, lead or user and send it to Intercom
   *
   * The final parameter is an optional metadata object that can be used to send additional details about the event.
   *
   * @see {@link https://developers.intercom.com/installing-intercom/docs/intercom-javascript#section-intercomtrackevent}
   *
   * @example
   * ```
   * const metadata = {
   *   item: 'NES',
   *   price: {"amount": 2900, "currency": "usd"},
   *   catalog_img: "https://downloads.intercomcdn.com/128113c39a6a.jpg",
   * };
   *
   * trackEvent('purchased-item', metadata);
   * ```
   */
  trackEvent: (event: string, metaData?: object) => void;
  /**
   * Opens the messenger with the specified article
   *
   * @see {@link https://developers.intercom.com/installing-intercom/docs/intercom-javascript#intercomshowarticle-articleid}
   *
   * @remarks if an article with the given ID doesn't exits, Messenger Home is opened instead
   */
  showArticle: (articleId: number) => void;
};

export type IntercomProviderProps = {
  /** The app ID of your Intercom app which will indicate where to store any data  */
  appId: string;
  /**
   * Indicates if Intercom should be automatically booted
   *
   * @remarks if `true`, 'boot' does not need to be called manually
   * */
  autoBoot?: boolean;
  /**
   * React children
   */
  children: React.ReactNode;
  /**
   * When we hide the messenger, you can hook into the event. This requires a function argument.
   */
  onHide?: () => void;
  /**
   * When we show the messenger, you can hook into the event. This requires a function argument.
   */
  onShow?: () => void;
  /**
   * This method allows you to register a function that will be called immediately
   * when invoked, and again whenever the current number of unread messages changes.
   */
  onUnreadCountChange?: (unreadCount: number) => void;
  /**
   * Indicates if Intercom should be initialized. This will ping to the Intercom servers.
   *
   * @remarks can be used for multistaged environments
   */
  shouldInitialize?: boolean;

  /**
   * If you need to route your Messenger requests through a different endpoint than the default
   *
   * @remarks Generally speaking, this is not needed.
   * Format https://${INTERCOM_APP_ID}.intercom-messenger.com
   */
  apiBase?: string;
  /**
   * Indicates if the intercom initialization should be delayed, delay is in ms
   *
   * @remarks If not set delay is set to 0ms
   * */
  initializeDelay?: number;
  /**
   * Pass properties to `boot` method when `autoBoot` is `true`
   */
  autoBootProps?: IntercomProps;
};
