import moment from 'moment';
import computed from 'ember-computed';
import Component from 'ember-component';
import injectService from 'ember-service/inject';
import config from 'web-client/config/environment';
import urlParams from 'web-client/utilities/url-params';
import {
  SHOW_ALL_OFFERS_KEY as showAllOffersKey
} from 'web-client/utilities/samus/prime-tracking-keys';

export default Component.extend({
  session: injectService(),
  store: injectService(),
  storage: injectService(),
  tracking: injectService(),
  urlParams,

  tagName: 'dl',
  classNames: 'warp__list js-offers',
  offers: [],
  orderSortingAsc: ['priority:asc'],
  offersSorted: computed.sort('currentOffers', 'orderSortingAsc'),
  hasPrime: false,
  showAllOffers: false,

  _isPolling: false,

  hiddenOfferIds: computed(function() {
    let currentlyHiddenStorage = this.get('storage.hiddenOfferIds') || '[]';
    let currentlyHidden = JSON.parse(currentlyHiddenStorage);
    if (currentlyHidden.length === 0) {
      this.set('storage.hiddenOfferIds', JSON.stringify(currentlyHidden));
    }
    return currentlyHidden;
  }),

  claimedOfferIds: computed(function() {
    let currentlyClaimedStorage = this.get('storage.claimedOfferIds') || '[]';
    let currentlyClaimed = JSON.parse(currentlyClaimedStorage);
    if (currentlyClaimed.length === 0) {
      this.set('storage.claimedOfferIds', JSON.stringify(currentlyClaimed));
    }
    return currentlyClaimed;
  }),

  claimedOffers: computed('offersSorted', 'claimedOfferIds', function() {
    return this.get('offersSorted').filter((offer) => {
      let offerId = offer.id;
      let tuid = this.get('session.userData.id');
      let claimedOfferId = `${offerId}-${tuid}`;
      return !this.get('claimedOfferIds') || this.get('claimedOfferIds').includes(claimedOfferId);
    });
  }),

  unclaimedOffers: computed('offersSorted', 'claimedOfferIds', function() {
    return this.get('offersSorted').filter((offer) => {
      let offerId = offer.id;
      let tuid = this.get('session.userData.id');
      let claimedOfferId = `${offerId}-${tuid}`;
      return !this.get('claimedOfferIds') || !this.get('claimedOfferIds').includes(claimedOfferId);
    });
  }),

  navOffers: computed('isLeftColumnClosed', 'hiddenOfferIds', 'claimedOfferIds', 'claimedOffers', 'unclaimedOffers', 'showAllOffers', 'offersSorted.[]', function(){
    if(this.get('showAllOffers') && !this.get('isLeftColumnClosed')) {
      return this.get('unclaimedOffers').concat(this.get('claimedOffers'));
    }

    return this.get('offersSorted').filter((offer) => {
      let offerId = offer.id;
      let tuid = this.get('session.userData.id');
      let claimedOfferId = `${offerId}-${tuid}`;
      return this.get('hiddenOfferIds') && !this.get('hiddenOfferIds').includes(offerId) && !this.get('hiddenOfferIds').includes(claimedOfferId);
    }).slice(0,3);
  }),

  init(){
    this._super(...arguments);

    this._getOffers();

    let { isAuthenticated, userData } = this.get('session');
    if (isAuthenticated) {
      let premium = userData.has_premium || false;
      this.set('hasPrime', premium);
    }

    // Start scheduled task to filter expired offers
    this.pollTask('expiredOffersTask', 'offerList#expiredOffersTask');

    this._handleSamusTypAction();
  },

  expiredOffersTask(next) {
    if (!this._isPolling) {
      this._isPolling = true;
      next();
      return;
    }

    this._filterCurrentOffers();
    this.runTask(next, config.delay.currentOfferList.pollInterval);
  },

  actions: {
    toggleShowAllOffers() {
      this._showAllOffersClickTracking();
      this.toggleProperty('showAllOffers');
    },

    expandAllOffers() {
      this._showAllOffersClickTracking();
      this.set('showAllOffers', true);
    },

    expandToShowAll() {
      let showAllOffers = this.get('showAllOffers');
      if (!showAllOffers) {
        this.send('toggleShowAllOffers');
      }

      if (this.get('isLeftColumnClosed')) {
        this.get('handleLeftColumnToggleClick')();
      }
    }
  },

  _getOffers() {
    this.get('store').findAll('offer').then((offers) => {
      if (this.isDestroyed) { return; }
      this.set('offers', offers);

      let currentlyHiddenStorage = this.get('storage.hiddenOfferIds') || '[]';
      let currentlyHidden = JSON.parse(currentlyHiddenStorage);

      let currentlyClaimedStorage = this.get('storage.claimedOfferIds') || '[]';
      let currentlyClaimed = JSON.parse(currentlyClaimedStorage);

      //TODO do this using a Set instead of a map
      let newlyHiddenHash = {};
      currentlyHidden.forEach((offerId) => {
        newlyHiddenHash[offerId] = offerId;
      });
      currentlyClaimed.forEach((offerId) => {
        newlyHiddenHash[offerId] = offerId;
      });
      let newlyHidden = Object.keys(newlyHiddenHash);
      this.set('storage.hiddenOfferIds', JSON.stringify(newlyHidden));
      this._filterCurrentOffers();
    });
  },

  _filterCurrentOffers(){
    let dateNow = moment(Date.now());
    let currentOffers = this.get('offers').filter(offer => {
      return dateNow.isBefore(moment(offer.get('endTime')));
    });

    this.set('currentOffers', currentOffers);
  },

  _handleSamusTypAction() {
    if (this.get('urlParams').expandoffers) {
      this.send('expandToShowAll');
    }
  },

  _showAllOffersClickTracking() {
    let { userData } = this.get('session');

    this.get('tracking').trackEvent({
      event: showAllOffersKey,
      data: {
        time: Date.now(),
        userData: userData
      }
    });
  }
});
