var commandResult = function (input) {
  if (typeof input === 'string') {
    $('#notification .text').html(input.escape().replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br>$2'));
  } else {
    var data = _.map(input, function (value) {
      return '<a class="channel-name" href="/channel/spam">#' + value + '</a>';
    });

    data = data.join(', ');
    $('#notification .text').html(data);
  }
  $('#notification').show();
  scrollToBottom('commandResult');
};

var gifify = function (text, channel, hash) {
  var query = encodeURIComponent(text).replace(/%20/g, '+');
  var gifs;

  jQuery.ajax({
    url: 'https://api.giphy.com/v1/gifs/search?limit=10&q=' + query + '&api_key=l41lW0nBrao1EhPuo',
    success: function (result) {
      gifs = result;
      if (gifs.data && gifs.data.length) {
        var rand = Math.round(Math.random() * gifs.data.length);

        createMessage({
          'img': gifs.data[rand].images.fixed_width_downsampled.url,
          'url': gifs.data[rand].images.original.url,
          'alt': text
        }, channel, hash);
      } else {
        commandResult('Sorry, we did not find a gif matching your query.');
      }
    }
  });
};

// commands
var emoji = function (channel, hash, rest) {
  var emo = _.map(emojis, function (value) {
    return value + ' ' + emojione.toImage(value);
  });

  $('#notification .text').html('Emojis available: ' + emo.join(', '));
  $('#notification').show();
  scrollToBottom('commandResult');
  return true;
};

var flip = function (channel, hash, rest) {
  createMessage(flipText(rest), channel, hash);
  return true;
};

var gif = function (channel, hash, rest) {
  rest = rest.slice(0, 30);
  gifify(rest, channel, hash);
  return true;
};

var help = function (channel, hash, rest) {
  if (!rest) {
    commandResult('Commands available: /emoji, /j, /join, /list, /muted');
  } else {
    if (rest in commands) {
      commandResult('SYNOPSIS: ' + commands[rest][1] + '\nUSAGE: ' + commands[rest][2]);
    } else {
      commandResult('Unknown command /' + rest);
    }
  }
  return true;
};

var hide = function (channel, hash, rest) {
  Meteor.call('hide');
  $('#input').toggleClass('red-border');
  return true;
};

var invite = function (channel, hash, rest) {
  match = rest.match(/@([^ ]*) #([^ ]*)/);
  if (!match) {
    commandResult('/invite @username #channel');
    return false;
  }
  if (!/^\w{1}[^\n\r#<>&' ]{1,17}$/g.test(match[2])) {
    commandResult('Invalid channel');
    return false;
  }
  if (Meteor.user().username === match[1]) {
    commandResult('You cannot invite yourself.');
    return false;
  }
  Meteor.call('invite', match[1], match[2]);
  return true;
};

var join = function (channel, hash, rest) {
  if (/^\w{1}[^\n\r#<>&' ]{1,17}$/g.test(rest)) {
    Router.go('/channel/' + rest);
    return true;
  } else if (/^#\w{1}[^\n\r#<>&' ]{1,17}$/g.test(rest)) {
    Router.go('/channel/' + rest.substring(1));
    return true;
  } else {
    commandResult('/join [#]channel');
    return false;
  }
};

var list = function (channel, hash, rest) {
  Meteor.call('channelList', function (err, data) {
    commandResult(data);
  });
  return true;
};

var me = function (channel, hash, rest) {
  createMessage('/me ' + rest, channel, hash);
  return true;
};

var merge = function (channel, hash, rest) {
  var channels = rest;

  channels = _.compact(_.map(channels.split(','), function (c) {
    c = $.trim(c);
    if (/^\w{1}[^\n\r#<>&' ]{1,17}$/g.test(c)) {
      return c;
    } else if (/^#\w{1}[^\n\r#<>&' ]{1,17}$/g.test(c)) {
      return c.substring(1);
    }
  })).join(',');
  Router.go('/merge/' + channels);
  return true;
};

var muted = function (channel, hash, rest) {
  Meteor.call('mutedList', function (err, data) {
    if (data.length) {
      commandResult(data);
    } else {
      commandResult('No muted channels.');
    }
  });
  return true;
};

var notice = function (channel, hash, rest) {
  match = rest.match(/@([^ ]*) (.*)$/);
  if (!match) {
    commandResult('/notice @username message');
    return false;
  }
  if (match[2].length > 200) {
    commandResult('You cannot notice more than 200 characters');
    return false;
  }
  if (Meteor.user().username === match[1]) {
    commandResult('You cannot notice yourself.');
    return false;
  }
  Meteor.call('notice', match[1], match[2]);
  return true;
};

var split = function (channel, hash, rest) {
  var channels = rest;

  channels = _.compact(_.map(channels.split(',').slice(0, 2), function (c) {
    c = $.trim(c);
    if (/^\w{1}[^\n\r#<>&' ]{1,17}$/g.test(c)) {
      return c;
    } else if (/^#\w{1}[^\n\r#<>&' ]{1,17}$/g.test(c)) {
      return c.substring(1);
    }
  })).join(',');
  Router.go('/split/' + channels);
  return true;
};

var whois = function (channel, hash, rest) {
  match = rest.match(/@([^ ]*)/);
  if (!match) {
    commandResult('/whois @username');
    return false;
  }
  Meteor.call('whois', match[1], function (err, output) {
    if (output) {
      commandResult(output);
    }
  });
  return true;
};

var commands = {
  // command [function, synopsis, usage]
  emoji:  [emoji, 'Displays a list of available emojis', '/emoji'],
  flip:   [flip, 'Flips some text', '/flip text'],
  gif:    [gif, 'Finds a gif based on a keyword', '/gif keyword'],
  help:   [help, 'Displays available commands or help about a command', '/help [command]'],
  hide:   [hide, 'Toggles anonymode', '/hide'],
  invite: [invite, 'Invites a user to a channel', '/invite @username #channel'],
  j:      [join, 'Creates or joins a channel', '/j [#]channel'],
  join:   [join, 'Creates or joins a channel', '/join [#]channel'],
  list:   [list, 'Lists all current channels', '/list'],
  me:     [me, 'The infamous /me', '/me'],
  merge:  [merge, 'Merges two or more channels into a single view', '/merge chan1,chan2[,chan3,...]'],
  muted:  [muted, 'Lists your muted channels', '/muted'],
  notice: [notice, 'Sends a notice to a user', '/notice @username message'],
  split:  [split, 'Displays two channels in split view', '/split chan1,chan2'],
  whois:  [whois, 'Displays informations about a user', '/whois @username'],
};

var treatMessage = function ($input, text, channel, hash) {
  var merge = !$('#current-channel').length;
  var match;

  text = $.trim(text);
  if (text === '') {
    return;
  }

  if (text.length > characterLimit) {
    return;
  }

  if (text.substring(0, 2) === '//' && channel !== 'gif') {
    createMessage(text, channel, hash);
    analytics.track('Message new', { channel: channel });
    clearAndFocus($input);
    return;
  }

  if (text.substring(0, 1) === '/') {
    var command;
    var rest;
    var end = text.indexOf(' ');

    if (end === -1) {
      command = $.trim(text.substring(1));
      rest = null;
    } else {
      command = $.trim(text.substring(1, end));
      rest = $.trim(text.substring(end));
    }

    if (channel === 'gif') {
      delete commands.flip;
    }
    if (command in commands) {
      if (commands[command][0](channel, hash, rest)) {
        clearAndFocus($input);
      }
      analytics.track('command', { command: '/' + command });
    } else {
      commandResult('Unknown command /' + command);
    }
    return;
  }

  if (channel !== 'gif') {
    createMessage(text, channel, hash);
    analytics.track('Message new', { channel: channel });
    clearAndFocus($input);
  } else {
    commandResult('Only gifs on #gif. /gif keyword to post a gif.');
  }
};

var treatOc = function ($input, url, text, channel, hash) {
  var merge = !$('#current-channel').length;
  var matched;
  var id;
  var endpoint;
  var parsedURL;
  var unsup = false;

  if (url !== '') {
    parsedURL = getLocation(url);
    console.log(parsedURL.hostname, parsedURL.pathname);
    switch (parsedURL.hostname) {
      case 'news.ycombinator.com':
      case 'news.ycombinator.org':
        if (parsedURL.pathname === '/item') {
          var matched = parsedURL.search.match(/\?id=([0-9]+)/);

          if (matched) {
            id = matched[1];
            endpoint = 'https://hacker-news.firebaseio.com/v0/item/' + id + '.json';
            jQuery.ajax({
              url: endpoint,
              success: function (result) {
                story = result;
                if (story.title && (story.url || story.text)) {
                  text = story.title + '\n\n' + (story.url || story.text);
                  text = text.replace(/\&#x27;/gi, '\'').replace(/\&#x2F;/gi, '/');
                  createMessage(text, channel, hash, 'oc');
                  analytics.track('OC new', { channel: channel, source: 'HN' });
                  return;
                }
              }
            });
          } else {
            unsup = true;
          }
          unsup = true;
        }
        break;

      case 'reddit.com':
      case 'www.reddit.com':
        endpoint = 'http://www.reddit.com/.json?url=' + encodeURIComponent(url);
        jQuery.ajax({
          url: endpoint,
          success: function (result) {
            story = result;
            if (story && story.data && story.data.children[0] && story.data.children[0].data) {
              console.log(story.data);
              story = story.data.children[0].data;
              console.log(story);
              if (story.over_18) {
                unsup = true;
              } else {
                text = story.title + '\n\n' + (story.thumbnail || story.text);
                console.log(text);
                // createMessage(text, channel, hash, 'oc');
                // analytics.track('OC new', { channel: channel, source: 'Reddit' });
                return;
              }
            }
          }
        });
        break;
    }
  }

  if (unsup) {
    commandResult('Sorry, we do not support this kind of story.');
  }

  text = $.trim(text);

  if (text === '') {
    return;
  }

  if (text.length > characterLimit) {
    return;
  }

  createMessage(text, channel, hash, 'oc');
  analytics.track('OC new', { channel: channel });
  clearAndFocus($input);
};

var clearAndFocus = function ($input) {
  $input.val('');
  $input.focus();
};

var submitFormOnRendered = function () {
  if (!Meteor.isCordova) {
    $('#input').history().tab(complete, { hint: false });
    $('#inputA').history().tab(complete, { hint: false });
    $('#inputB').history().tab(complete, { hint: false });
    $('#input-oc').history().tab(complete, { hint: false });
  }

  $('#form').resizable({
    direction: ['top'],
    resize: function () {
      $('#windows').css('bottom', $(this).height());
      if (Session.equals('profile.scrolling', true)) {
        _.debounce(function () {
          scrollToBottom('submitForm.onRendered');
        }, 250);
      }
    },
  });

  function complete(word) {
    var words = emojis.slice();
    var $users = $('.users');
    var nicks = '';

    if (!nicks) {
      nicks = [];
      $users.find('.user').each(function () {
        var nick = $(this).text();

        nicks.push('@' + nick);
      });
      $users.data('nicks', nicks);
    }

    for (var i in nicks) {
      words.push(nicks[i]);
    }

    var channels = $('#sidebar').find('.chan').each(function () {
      var channelName = $(this).find('a').text();

      words.push('#' + channelName);
    });

    return $.grep(words, function (w) {return !w.toLowerCase().indexOf(word.toLowerCase());});
  }
};

Template.submitForm.onRendered(submitFormOnRendered);
Template.submitFormA.onRendered(submitFormOnRendered);
Template.submitFormB.onRendered(submitFormOnRendered);
Template.submitOc.onRendered(submitFormOnRendered);

Template.submitForm.events({
  'click #submit': function () {
    if (Meteor.user()) {
      var $input = $('#input');
      var text = $input.val();

      treatMessage($input, text, $('#current-channel').text(), $('#current-hash').text());
    }
  },
  'keyup #input': function (event) {
    var $input = $('#input');

    countChar($input, $('div#char-count'));
  },
  'keydown #input': function (event) {
    var ctrl = event.ctrlKey;
    var shift = event.shiftKey;

    if (Meteor.user()) {
      var $input = $('#input');
      var text = $input.val();
      var enter = Meteor.user().profile.enter;

      if ((event.which === 13 && (enter && !ctrl && !shift)) || (event.which === 13 && (!enter && ctrl))) {
        event.preventDefault();
        treatMessage($input, text, $('#current-channel').text(), $('#current-hash').text());
        return true;
      }

      countChar($input, $('div#char-count'));
      return true;
    } else {
      if (event.which === 13 && !shift) {
        event.preventDefault();
        showNotification(10002);
        return true;
      }
    }
  },
  'click #enter-switch': function () {
    Meteor.users.update({ '_id': Meteor.userId() }, { $set: { 'profile.enter': !Meteor.user().profile.enter } });
  },
});

Template.submitFormA.events({
  'click #submitA': function () {
    if (Meteor.user()) {
      var $input = $('#inputA');
      var text = $input.val();

      treatMessage($input, text, $('#channelA').text(), $('#current-hash').text());
    }
  },
  'keyup #inputA': function (event) {
    var $input = $('#inputA');

    countChar($input, $('div#char-countA'));
  },
  'keydown #inputA': function (event) {
    var ctrl = event.ctrlKey;
    var shift = event.shiftKey;

    if (Meteor.user()) {
      var $input = $('#inputA');
      var text = $input.val();
      var enter = Meteor.user().profile.enter;

      if ((event.which === 13 && (enter && !ctrl && !shift)) || (event.which === 13 && (!enter && ctrl))) {
        event.preventDefault();
        treatMessage($input, text, $('#channelA').text(), $('#current-hash').text());
        return true;
      }

      countChar($input, $('div#char-countA'));
      return true;
    } else {
      if (event.which === 13 && !shift) {
        event.preventDefault();
        showNotification(10002);
        return true;
      }
    }
  },
  'click #enter-switch': function () {
    Meteor.users.update({ '_id': Meteor.userId() }, { $set: { 'profile.enter': !Meteor.user().profile.enter } });
  },
});

Template.submitFormB.events({
  'click #submitB': function () {
    if (Meteor.user()) {
      var $input = $('#inputB');
      var text = $input.val();

      treatMessage($input, text, $('#channelB').text(), $('#current-hash').text());
    }
  },
  'keyup #inputB': function (event) {
    var $input = $('#inputB');

    countChar($input, $('div#char-countB'));
  },
  'keydown #inputB': function (event) {
    var ctrl = event.ctrlKey;
    var shift = event.shiftKey;

    if (Meteor.user()) {
      var $input = $('#inputB');
      var text = $input.val();
      var enter = Meteor.user().profile.enter;

      if ((event.which === 13 && (enter && !ctrl && !shift)) || (event.which === 13 && (!enter && ctrl))) {
        event.preventDefault();
        treatMessage($input, text, $('#channelB').text(), $('#current-hash').text());
        return true;
      }

      countChar($input, $('div#char-countB'));
      return true;
    } else {
      if (event.which === 13 && !shift) {
        event.preventDefault();
        showNotification(10002);
        return true;
      }
    }
  },
  'click #enter-switch': function () {
    Meteor.users.update({ '_id': Meteor.userId() }, { $set: { 'profile.enter': !Meteor.user().profile.enter } });
  },
});

Template.submitOc.events({
  'click #submit-oc': function () {
    if (Meteor.user()) {
      var $input = $('#input-oc');
      var text = $input.val();

      treatOc($input, $('#url-oc').val(), text, $('#current-channel').text(), $('#current-hash').text());
    }
  },
  'keyup #input-oc': function (event) {
    var $input = $('#input-oc');

    countChar($input, $('div#char-count-oc'));
  },
  'keydown #input-oc': function (event) {
    var ctrl = event.ctrlKey;
    var shift = event.shiftKey;

    if (Meteor.user()) {
      var $input = $('#input-oc');
      var text = $input.val();

      if (event.which === 13 && ctrl) {
        event.preventDefault();
        treatOc($input, $('#url-oc').val(), text, $('#current-channel').text(), $('#current-hash').text());
        return true;
      }

      countChar($input, $('div#char-count-oc'));
      return true;
    } else {
      if (event.which === 13 && !shift) {
        event.preventDefault();
        showNotification(10002);
        return true;
      }
    }
  },
});

Template.submitForm.helpers({
  'hidden': function () {
    return Meteor.user() ? Meteor.user().hidden : false;
  },
});
