/* globals Twitch, i18n */
import Component from 'ember-component';
import computed from 'ember-computed';
import SendRouteActionMixin from 'web-client/mixins/send-route-action';
import VodAppeal from 'web-client/models/vod-appeal';
import computedEqualProperty from 'web-client/utilities/computed-equal-property';
import injectService from 'ember-service/inject';
import getOwner from 'ember-owner/get';
import YoutubeExporterMixin from 'web-client/mixins/youtube-exporter';
import { assert } from 'ember-metal/utils';
import RebroadcasterMixin from 'web-client/mixins/rebroadcaster';

const RECORDED_STATUS = 'recorded';

export default Component.extend(YoutubeExporterMixin, SendRouteActionMixin, RebroadcasterMixin, {
  globals: injectService(),
  session: injectService(),

  onEdit() {},
  onDelete() {},

  video: null,
  appealPending: computed.alias('vodAppeal.hasPendingAppeal'),
  isVodAppealsEnabled: computed.readOnly('globals.isVodAppealsEnabled'),
  isVodOwner: computedEqualProperty('session.userData.login', 'video.channelName'),

  canAppeal: computed.and('video.isMuted', 'isVodOwner', 'isVodAppealsEnabled'),
  /**
   * This property uses details of videoUpload and a video's status attribute from the
   * server to return an optimistic 'status' string.
   *
   * The possible user-facing states are 'uploading', 'transcoding',
   * 'processed', and 'error'.
   *
   * 'incomplete' is a likely future state (not implemented by the server yet)
   * where video transcoding is complete but users must add more attributes
   * before it can be published.
   *
   *  Server statuses:
   *
   *    StatusCreated           = "created"
   *    StatusUploading         = "uploading"
   *    StatusPendingTranscode  = "pending_transcode"
   *    StatusTranscoding       = "transcoding"
   *    StatusFailed            = "failed"
   *    StatusTranscodeComplete = "recorded"
   *
   * @returns String - state
   */
  currentStatus: computed('video.{status,currentStatus,isError}', 'video.videoUpload.{isSuccess,isError,isUploading}', function() {
    let video = this.get('video');
    let status = video.get('status');

    // In this case the video could not be created on the server.
    if (status === 'new' && video.get('isError')) {
      return 'error';
    }

    // If we can precisely derive the state from the status field, return that
    // value.
    let stateFromVideoStatus = VIDEO_STATUS_TO_USER_STATE[status];
    if (stateFromVideoStatus) {
      return stateFromVideoStatus;
    }

    // If we have a videoUpload we can use it to to eagerly determine the
    // user-facing state for a more responsive UI.
    let videoUpload = this.get('video.videoUpload');
    if (videoUpload) {
      if (videoUpload.get('isUploading')) {
        return 'uploading';
      } else if (videoUpload.get('isSuccess')) {
        return 'transcoding';
      } else if (videoUpload.get('isError')) {
        return 'error';
      }

      return 'queued';
    }

    if (status === 'recording') {
      return 'processed';
    }

    if (status === 'unprocessed') {
      return 'transcoding';
    }

    // Otherwise we have an error state.
    return 'error';
  }),

  durationString: computed('currentStatus', 'video.length', function(){
    let video = this.get('video');
    if (this.get('video.status') === 'recording') {
      return i18n("Recording");
    } else if (video.length) {
      return Twitch.display.lengthAsClock(this.get('video.length'));
    }

    return null;
  }),

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

    assert(`"video" is a required property for ${this}`, this.get('video'));

    if (this.get('video.status') === RECORDED_STATUS && this.get('canAppeal')) {
      this.set('vodAppeal', VodAppeal.find(getOwner(this), this.get('video.id')));
    }

    this.set('video.youtubeConnected', this.get('managerProperties.youtube_connected'));
    this.set('video.liveAnnotationsEnabled', this.get('managerProperties.live_annotations_enabled'));
  },

  showVodAppealsForm() {
      this.sendRouteAction('openInModal', 'video/appeals/appeal-modal', this, { model: this.get('video') });
  },

  actions: {
    closeModal() {
      this.sendRouteAction('closeModal');
    }
  }
});

/**
 * Sometimes the authoritative state of the video is determined only by the
 * state field of the uploader video model. Those cases are defined in this
 * object.
 */
const VIDEO_STATUS_TO_USER_STATE = {
  new: 'uploading',
  pending_transcode: 'transcoding',
  transcoding: 'transcoding',
  failed: 'error',
  recorded: 'processed'
};
