/* globals URI, Twitch, i18n */
import { assign } from 'ember-platform';
import Component from 'ember-component';
import injectService from 'ember-service/inject';
import computed from 'ember-computed';
import $ from 'jquery';
import { assert } from 'ember-metal/utils';
import { isPresent } from 'ember-utils';

const TIME_TO_CLOSE_ADD_FRIEND_CONFIRM = 3500;

export default Component.extend({
  feeds: injectService(),
  store: injectService(),
  session: injectService(),
  friends: injectService('twitch-friends-list/friends'),

  showControls: false,
  notification: '',
  showCopyNotification: false,
  reportReason: null,
  showFriendButton: false,
  canDeleteMessage: computed.alias('message.permissions.can_delete'),
  canBanUser: computed('type', 'post', function () {
    let type = this.get('type');
    let canModerate = this.get('post.permissions.can_moderate');
    return type === 'comment' && canModerate;
  }),
  deleteMessageString: computed('type', function () {
    let type = this.get('type');
    return `Are you sure you want to delete this ${type}?`;
  }),
  reportMessageString: computed('type', function () {
    let type = this.get('type');
    return `Report this ${type} for`;
  }),
  deleteCommentsString: computed('message.user.prettyName', function () {
    let userId = this.get('message.user.prettyName');
    return i18n(`Delete all of ${userId}'s comments from this post?`);
  }),
  userIsAuthor: computed('session.userData', 'message.user.login', function () {
    let userData = this.get('session.userData');
    let author = this.get('message.user.login');
    if (userData) {
      return author === userData.login;
    }
    return null;
  }),
  showFriendStatus: computed('userIsAuthor', 'showFriendButton', function () {
    let userIsAuthor = this.get('userIsAuthor');
    let showFriendButton = this.get('showFriendButton');
    return !userIsAuthor && showFriendButton;
  }),

  init() {
    this._super(...arguments);
    let message = this.get('message');
    let login = message.get('user.login');
    let store = this.get('store');

    this.set('type', message.constructor.modelName);
    assert(`{{twitch-feed/controls}} requires argument "deleteAction"`, isPresent(this.get('deleteAction')));

    if (this.get('showFriendButton')) {
      let messageAuthorFriendStatus = store.peekRecord('friends-list-user', message.get('user.id'));
      if (messageAuthorFriendStatus) {
        this.set('messageAuthorFriendStatus', messageAuthorFriendStatus);
      } else {
        store.queryRecord('friends-list-user', {
          type: 'friend-status',
          login
        }).then((user) => {
          if (this.isDestroyed) { return; }
          this.set('messageAuthorFriendStatus', user);
        });
      }
    }
  },

  showCopyButton: computed(function () {
    return document.queryCommandSupported('copy');
  }),

  sharePostUrl: computed('post', 'post.id', function () {
    let post = this.get('post');
    let user = post.get('user');

    let login = user.get('login');
    let postId = post.get('id');
    let uri = new URI();
    uri.path(`${login}/p/${postId}`);

    return uri.toString();
  }),

  hideControls() {
    this.set('showControls', false);
  },

  hideNotice() {
    if (this.get('notification') === 'report') {
      this.$('.js-report select').val('default');
    }
    this.set('notification', '');
    this.hideControls();
  },

  didInsertElement() {
    this._super(...arguments);
    this.addEventListener(window, 'click', (e) => {
      let target = $(e.target);
      if (!this.$('.js-activity-menu').is(target.parents('.js-activity-menu'))) {
        this.hideNotice();
      }
    });
  },

  actions: {
    toggleControls() {
      this.toggleProperty('showControls');
    },

    hideNotice() {
      this.hideNotice();
    },

    showDeleteNotice() {
      this.set('notification', 'delete');
    },

    showReportNotice() {
      if (!this.get('feeds.meAsFeedUser')) {
        let isModal = this.get('isModal');
        if (!isModal && $.login instanceof Function) {
          $.login();
        }
        return;
      }
      this.set('notification', 'report');
    },

    showShareNotice() {
      let feeds = this.get('feeds');
      let post = this.get('post');

      this.set('notification', 'share');
      feeds.trackEvent('feed_update_share', this.get('trackingInfo'), {
        status_update_id: post.get('id'),
        channel: post.get('user.login'),
        channel_live: this.get('broadcasterIsLive')
      });
    },

    showBanNotice() {
      this.set('notification', 'ban');
    },

    showDeleteCommentsNotice() {
      this.set('notification', 'delete-comments');
    },

    showFriendNotice() {
      this.set('notification', 'friend-status');
    },

    addFriend() {
      let store = this.get('store');
      let authorId = this.get('message.user.id');
      let authorLogin = this.get('message.user.login');
      let messageAuthorFriendStatus = this.get('messageAuthorFriendStatus');

      store.createRecord('friends-list-request', {
        friendId: authorId,
        friendLogin: authorLogin
      }).save().then(() => {
        if (this.isDestroyed) { return; }
        messageAuthorFriendStatus.set('isRequested', true);
        this.set('notification', 'friend-status');
      }).finally(() => {
        this.runTask(() => {
          if (this.get('showControls') === true) {
            this.hideNotice();
          }
        }, TIME_TO_CLOSE_ADD_FRIEND_CONFIRM);
      });
    },

    removeFriend() {
      let store = this.get('store');
      let authorLogin = this.get('message.user.login');
      let authorId = this.get('message.user.id');
      let messageAuthorFriendStatus = this.get('messageAuthorFriendStatus');

      store.queryRecord('friends-list-user', {
        type: 'unfriend',
        id: authorId,
        login: authorLogin
      }).then(() => {
        if (this.isDestroyed) { return; }
        this.hideNotice();
        messageAuthorFriendStatus.set('isFriend', false);
      });
    },

    deleteMessage() {
      let feeds = this.get('feeds');
      let message = this.get('message');
      let post = this.get('post');

      this.get('deleteAction')(message).finally(() => {
        if (this.isDestroyed) { return; }
        let commonProperties = {
          status_update_id: post.get('id'),
          is_moderator: this.get('post.permissions.can_moderate'),
          action: "delete"
        };
        let eventName;
        let uniqueProperties = {};

        if (this.get('type') === 'post') {
          eventName = 'feed_update_moderation';
          uniqueProperties.channel = post.get('user.login');
        } else {
          eventName = 'feed_comment_moderation';
          uniqueProperties.comment_id = message.get('id');
        }
        feeds.trackEvent(eventName, assign(commonProperties, uniqueProperties));
      }, () => {
        Twitch.notify.error(i18n("There was a problem updating your channel feed. Please try again."));
      });
    },

    deleteComments() {
      let feeds = this.get('feeds');
      let comment = this.get('message');
      let post = this.get('post');

      feeds.deleteUserCommentsFromPost(comment).then(() => {
        if (this.isDestroyed) { return; }
        feeds.trackEvent('feed_comment_moderation', this.get('trackingInfo'), {
          status_update_id: post.get('id'),
          is_moderator: post.get('permissions.can_moderate'),
          action: 'delete_user_comments',
          comment_id: comment.get('id')
        });
      }, (e) => {
        if (!this.isDestroyed) {
          Twitch.notify.error(i18n("There was a problem updating this channel feed. Please try again."));
        }
        throw e;
      });
    },

    reportMessage() {
      let feeds = this.get('feeds');
      let message = this.get('message');
      let post = this.get('post');
      let postId = post.get('id');
      let channelName = post.get('user.login');
      let reportReason = this.get('reportReason');

      if (!reportReason || reportReason === "default") {
        Twitch.notify.error(i18n('Please select a reason.'));
        return;
      }

      feeds.reportMessage({reportReason, channelName, message}).then(() => {
        if (this.isDestroyed) { return; }
        let commonProperties = {
          status_update_id: postId,
          reason: reportReason,
          is_moderator: this.get('post.permissions.can_moderate')
        };
        let eventName;
        let uniqueProperties = {};

        this.hideNotice();
        Twitch.notify.success(i18n('Thank you for your report.'));

        if (this.get('type') === 'post') {
          eventName = 'feed_update_report';
          uniqueProperties.channel = channelName;
        } else {
          eventName = 'feed_comment_report';
          uniqueProperties.comment_id = message.get('id');
        }
        feeds.trackEvent(eventName, this.get('trackingInfo'), assign(commonProperties, uniqueProperties));
      }, (e) => {
        if (this.isDestroyed) { return; }
        Twitch.notify.error(i18n('There was a problem reporting this post. Please try again.'));
        throw e;
      });
    },

    banUser() {
      let feeds = this.get('feeds');
      let message = this.get('message');
      let user = message.get('user.login');
      let channelName = this.get('post.user.login');

      feeds.banUser(user, channelName).then(() => {
        if (this.isDestroyed) { return; }
        this.hideNotice();
        feeds.trackEvent('feed_comment_moderation', this.get('trackingInfo'), {
          status_update_id: this.get('post.id'),
          channel: channelName,
          is_moderator: this.get('post.permissions.can_moderate'),
          action: 'ban',
          comment_id: message.get('id')
        });
      });
    },

    selectReportReason(value) {
      this.set("reportReason", value);
    },

    copyUrl() {
      $(this.element).find('.js-share-url').select();
      document.execCommand('copy');
      this.set('showCopyNotification', true);
      this.runTask(() => {
        this.set('showCopyNotification', false);
      }, 1500);
    }
  }
});
