import Ember from 'ember';
import Component from 'ember-component';
import injectService from 'ember-service/inject';
import { assign } from 'ember-platform';
const { testing: isEmberTesting } = Ember;

const MESSAGES = {
  initial: {
    short: 'Download'
  },

  preparing: {
    short: 'Preparing…',
    header: 'Preparing Download',
    long: 'Download will automatically begin if you remain on this page.'
  },

  ready: {
    short: 'Begin Download',
    header: 'Download Ready',
    long: 'Click to begin your download.'
  },

  rateLimited: {
    short: 'Error',
    long: 'Please wait for your current downloads to finish',
    header: 'Too many downloads'
  },

  error: {
    short: 'Error',
    header: 'Error Reaching Server'
  },

  failed: {
    short: 'Failed',
    header: 'Our Bad',
    long: "We couldn't make a download file for this video."
  }
};

const POLL_INTERVAL = 5000;

export default Component.extend({
  classNames: ['balloon-wrapper'],
  videoDownloader: injectService(),
  videoId: null,
  download: null,

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

    this.currentMessage = MESSAGES.initial;
    this._fetchDownload = this._fetchDownload.bind(this);
  },

  willDestroyElement() {
    if (this.get('videoId')) {
      this.get('videoDownloader').finishedDownload(this.get('videoId'));
    }
  },

  onDownloadStatusUpdate(response) {
    if (this.isDestroyed) {
      return;
    }

    let download = new Download(response);
    this.set('download', download);

    if (download.isReady) {
      this.set('currentMessage', MESSAGES.ready);
      downloadURL(download.url);
    } else if (download.isFailed) {
      this.set('currentMessage', MESSAGES.failed);
    } else if (download.isRateLimited) {
      this.set('currentMessage', MESSAGES.rateLimited);
    } else {
      this.runTask(this._fetchDownload, POLL_INTERVAL);
    }
  },

  onServerError(response) {
    if (this.isDestroyed) {
      return;
    }

    let details;
    if (response && response.responseJSON) {
      details = response.responseJSON.message;
    }

    this.set('currentMessage', assign({ long: details }, MESSAGES.error));
  },

  _fetchDownload() {
    this.get('videoDownloader').fetchDownload(this.get('videoId')).then((response) => {
      this.onDownloadStatusUpdate(response);
    }, (response) => {
      this.onServerError(response);
    });
  },

  actions: {
    clickLink(event) {
      if (this.get('download.isReady')) {
        return true;
      }

      event.preventDefault();

      // No-op link if in preparing state
      if (this.get('download.isPreparing')) {
        return;
      }

      this.set('currentMessage', MESSAGES.preparing);

      this._fetchDownload();
    }
  }
});

class Download {
  constructor(response) {
    this.response = response;
  }

  get isReady() {
    return this.response.status === 'complete';
  }

  get isFailed() {
    return this.response.status === 'failed';
  }

  get isRateLimited() {
    return this.response.status === 'rate_limited';
  }

  get isPreparing() {
    return !this.isReady && !this.isFailed && !this.isRateLimited;
  }

  get url() {
    return this.response.download_url;
  }
}

function downloadURL(url) {
  if (!isEmberTesting) {
    window.location.href = url;
  }
}
