text: import Evented from '@ember/object/evented';
  import RSVP from 'rsvp';
  import Service, {inject as service} from '@ember/service';
  import {computed} from '@ember/object';
  
  export default Service.extend(Evented, {
  
      ghostPaths: service(),
      session: service(),
  
      // this service is responsible for managing tour item visibility and syncing
      // the viewed state with the server
      //
      // tour items need to be centrally defined here so that we have a single
      // source of truth for marking all tour items as viewed
      //
      // a {{gh-tour-item "unique-id"}} component can be inserted in any template,
      // this will use the tour service to grab content and determine visibility
      // with the component in control of rendering the throbber/controlling the
      // modal - this allows the component lifecycle hooks to perform automatic
      // display/cleanup when the relevant UI is visible.
  
      viewed: null,
  
      // IDs should **NOT** be changed if they have been part of a release unless
      // the re-display of the throbber should be forced. In that case it may be
      // useful to add a version number eg. `my-feature` -> `my-feature-v2`.
      // Format is as follows:
      //
      // {
      //     id: 'test',
      //     title: 'This is a test',
      //     message: 'This is a test of our <strong>feature tour</strong> feature'
      // }
      //
      // TODO: it may be better to keep this configuration elsewhere to keep the
      // service clean. Eventually we'll want apps to be able to register their
      // own throbbers and tour content
      throbbers: null,
  
      init() {
          this._super(...arguments);
          let adminUrl = `${window.location.origin}${this.get('ghostPaths.url').admin()}`;
          let adminDisplayUrl = adminUrl.replace(`${window.location.protocol}//`, '');
  
          this.viewed = [];
  
          this.throbbers = [{
              id: 'getting-started',
              title: 'Chào mừng bạn đến với trang quản trị',
              message: `Bạn có thể tìm thấy tất cả bài viết, thành viên cùng với các tùy chỉnh của bạn tại đây. Bạn có thể quay lại bất cứ lúc nào bằng cách truy cập <a href="${adminUrl}" target="_blank">${adminDisplayUrl}</a>`
          }, {
              id: 'using-the-editor',
              title: 'Sử dụng trình soạn thảo',
              message: 'Trình soạn thảo sử dụng Markdown giúp việc soạn thảo trở nên thuận tiện dễ dàng hơn. Có thể sử dụng thanh công cụ này hoặc chọn biểu tượng <strong>?</strong> để tìm hiểu thêm các phím tắt được hỗ trợ của trình soạn thảo.'
          }, {
              id: 'static-post',
              title: 'Chuyển bài viết thành Trang riêng',
              message: 'Các trang có nội dung cố định nằm ngoài luồng các bài đăng thông thường của bạn, ví dụ như trang \'Về chúng tôi\' hay \'Liên hệ\'.'
          }, {
              id: 'featured-post',
              title: 'Thiết lập bài viết tiêu điểm',
              message: 'Bài viết tiêu điểm sẽ hiển thị khác biệt với các bài viết thông thường như một tin quan trọng hay cần nhấn mạnh.'
          }, {
              id: 'upload-a-theme',
              title: 'Customising your publication',
              message: 'Using custom themes, you can completely control the look and feel of your site to suit your branch. Here\'s a full guide to help: <strong><a href="https://docs.ghost.org/api/handlebars-themes/" target="_blank">https://docs.ghost.org/api/handlebars-themes/</a></strong>'
          }];
      },
  
      _activeThrobbers: computed('viewed.[]', 'throbbers.[]', function () {
          // return throbbers that haven't been viewed
          let viewed = this.get('viewed');
          let throbbers = this.get('throbbers');
  
          return throbbers.reject(throbber => viewed.includes(throbber.id));
      }),
  
      // retrieve the IDs of the viewed throbbers from the server, always returns
      // a promise
      fetchViewed() {
          return this.get('session.user').then((user) => {
              let viewed = user.get('tour') || [];
  
              this.set('viewed', viewed);
  
              return viewed;
          });
      },
  
      // save the list of viewed throbbers to the server overwriting the
      // entire list
      syncViewed() {
          let viewed = this.get('viewed');
  
          return this.get('session.user').then((user) => {
              user.set('tour', viewed);
  
              return user.save();
          });
      },
  
      // returns throbber content for a given ID only if that throbber hasn't been
      // viewed. Used by the {{gh-tour-item}} component to determine visibility
      activeThrobber(id) {
          let activeThrobbers = this.get('_activeThrobbers');
          return activeThrobbers.findBy('id', id);
      },
  
      // when a throbber is opened the component will call this method to mark
      // it as viewed and sync with the server. Always returns a promise
      markThrobberAsViewed(id) {
          let viewed = this.get('viewed');
  
          if (!viewed.includes(id)) {
              viewed.pushObject(id);
              this.trigger('viewed', id);
              return this.syncViewed();
          } else {
              return RSVP.resolve(true);
          }
      },
  
      // opting-out will use the list of IDs defined in this file making it the
      // single-source-of-truth and allowing future client updates to control when
      // new UI should be surfaced through tour items
      optOut() {
          let allThrobberIds = this.get('throbbers').mapBy('id');
  
          this.set('viewed', allThrobberIds);
          this.trigger('optOut');
  
          return this.syncViewed();
      },
  
      // this is not used anywhere at the moment but it's useful to use via ember
      // inspector as a reset mechanism
      reEnable() {
          this.set('viewed', []);
          return this.syncViewed();
      }
  
  });
  