import { ajax } from 'discourse/lib/ajax';
import { default as computed, observes } from "ember-addons/ember-computed-decorators";

export default Ember.Controller.extend({
  isMultiple: Ember.computed.equal("poll.type", "multiple"),
  isNumber: Ember.computed.equal("poll.type", "number"),
  isClosed: Ember.computed.equal("poll.status", "closed"),
  isPublic: Ember.computed.equal("poll.public", "true"),

  // shows the results when
  //   - poll is closed
  //   - topic is archived
  //   - user wants to see the results
  showingResults: Em.computed.or("isClosed", "post.topic.archived", "showResults"),

  showResultsDisabled: Em.computed.equal("poll.voters", 0),
  hideResultsDisabled: Em.computed.or("isClosed", "post.topic.archived"),

  @observes("post.polls")
  _updatePoll() {
    this.set("model", this.get("post.pollsObject")[this.get("model.name")]);
  },

  @computed("model", "vote", "model.voters", "model.options", "model.status")
  poll(poll, vote) {
    if (poll) {
      const options = _.map(poll.get("options"), o => Em.Object.create(o));

      if (vote) {
        options.forEach(o => o.set("selected", vote.indexOf(o.get("id")) >= 0));
      }

      poll.set("options", options);
    }

    return poll;
  },

  @computed("poll.options.@each.selected")
  selectedOptions() {
    return _.map(this.get("poll.options").filterBy("selected"), o => o.get("id"));
  },

  @computed("poll.min")
  min(min) {
    min = parseInt(min, 10);
    if (isNaN(min) || min < 1) { min = 1; }
    return min;
  },

  @computed("poll.max", "poll.options.length")
  max(max, options) {
    max = parseInt(max, 10);
    if (isNaN(max) || max > options) { max = options; }
    return max;
  },

  @computed("poll.voters")
  votersText(count) {
    return I18n.t("poll.voters", { count });
  },

  @computed("poll.options.@each.votes")
  totalVotes() {
    return _.reduce(this.get("poll.options"), function(total, o) {
      return total + parseInt(o.get("votes"), 10);
    }, 0);
  },

  @computed("totalVotes")
  totalVotesText(count) {
    return I18n.t("poll.total_votes", { count });
  },

  @computed("min", "max", "poll.options.length")
  multipleHelpText(min, max, options) {
    if (max > 0) {
      if (min === max) {
        if (min > 1) {
          return I18n.t("poll.multiple.help.x_options", { count: min });
        }
      } else if (min > 1) {
        if (max < options) {
          return I18n.t("poll.multiple.help.between_min_and_max_options", { min, max });
        } else {
          return I18n.t("poll.multiple.help.at_least_min_options", { count: min });
        }
      } else if (max <= options) {
        return I18n.t("poll.multiple.help.up_to_max_options", { count: max });
      }
    }
  },

  @computed("isClosed", "showResults", "loading", "isMultiple", "selectedOptions.length", "min", "max")
  canCastVotes(isClosed, showResults, loading, isMultiple, selectedOptionCount, min, max) {
    if (isClosed || showResults || loading) {
      return false;
    }

    if (isMultiple) {
      return selectedOptionCount >= min && selectedOptionCount <= max;
    } else {
      return selectedOptionCount > 0;
    }
  },

  castVotesDisabled: Em.computed.not("canCastVotes"),

  @computed("castVotesDisabled")
  castVotesButtonClass(castVotesDisabled) {
    return `cast-votes ${castVotesDisabled ? '' : 'btn-primary'}`;
  },

  @computed("loading", "post.user_id", "post.topic.archived")
  canToggleStatus(loading, userId, topicArchived) {
    return this.currentUser &&
           (this.currentUser.get("id") === userId || this.currentUser.get("staff")) &&
           !loading &&
           !topicArchived;
  },

  actions: {

    toggleOption(option) {
      if (this.get("isClosed")) { return; }
      if (!this.currentUser) { return this.send("showLogin"); }

      const wasSelected = option.get("selected");

      if (!this.get("isMultiple")) {
        this.get("poll.options").forEach(o => o.set("selected", false));
      }

      option.toggleProperty("selected");

      if (!this.get("isMultiple") && !wasSelected) { this.send("castVotes"); }
    },

    castVotes() {
      if (!this.get("canCastVotes")) { return; }
      if (!this.currentUser) { return this.send("showLogin"); }

      this.set("loading", true);

      ajax("/polls/vote", {
        type: "PUT",
        data: {
          post_id: this.get("post.id"),
          poll_name: this.get("poll.name"),
          options: this.get("selectedOptions"),
        }
      }).then(results => {
        const poll = results.poll;
        const votes = results.vote;

        this.setProperties({ vote: votes, showResults: true });
        this.set("model", Em.Object.create(poll));
      }).catch(() => {
        bootbox.alert(I18n.t("poll.error_while_casting_votes"));
      }).finally(() => {
        this.set("loading", false);
      });
    },

    toggleResults() {
      this.toggleProperty("showResults");
    },

    toggleStatus() {
      if (!this.get("canToggleStatus")) { return; }

      const self = this,
            confirm = this.get("isClosed") ? "poll.open.confirm" : "poll.close.confirm";

      bootbox.confirm(
        I18n.t(confirm),
        I18n.t("no_value"),
        I18n.t("yes_value"),
        function(confirmed) {
          if (confirmed) {
            self.set("loading", true);

            ajax("/polls/toggle_status", {
              type: "PUT",
              data: {
                post_id: self.get("post.id"),
                poll_name: self.get("poll.name"),
                status: self.get("isClosed") ? "open" : "closed",
              }
            }).then(results => {
              self.set("model", Em.Object.create(results.poll));
            }).catch(() => {
              bootbox.alert(I18n.t("poll.error_while_toggling_status"));
            }).finally(() => {
              self.set("loading", false);
            });
          }
        }
      );

    },
  }

});
