// Description:
//   Help your team to find a place to drink a coffee !
//   Coffeepoll will create poll with random coffee shops nearby.
//
// Commands:
//   hubot coffeepoll near <text> - Configure the place for next polls
//   hubot coffeepoll start - Start the poll
//   hubot coffeepoll vote <number> - Vote in one of poll options
//   hubot coffeepoll partial - Show the partial results
//   hubot coffeepoll finish - Finish the poll

var _ = require('lodash')
var messages = require('../lib/messages')
var foursquare = require('node-foursquare-venues')(process.env.FOURSQUARE_CLIENT_ID,
                                                   process.env.FOURSQUARE_CLIENT_SECRET)

module.exports = function (bot) {
  var brain = bot.brain
  var options = []
  var votes = []
  var participants = {}

  brain.set('near', 'Berlin')
  brain.set('radius', 500)
  brain.set('participants', participants)
  brain.set('options', options)
  brain.set('votes', votes)

  var clearPoll = function () {
    options.length = 0
    votes.length = 0
    _.mapKeys(participants, function (v, k) {
      delete participants[k]
    })
  }

  var isPollNotStarted = function () {
    return _.isEmpty(options)
  }

  var isUserAlreadyVoted = function (username) {
    return participants[username]
  }

  var isVoteNotValid = function (vote) {
    return typeof votes[vote] === 'undefined'
  }

  var isRadiusNotValid = function (radius) {
    return !(radius > 0)
  }

  bot.respond(/coffeepoll near (.*)/i, function (res) {
    var place = res.match[1]

    brain.set('near', place)

    return res.send(messages.places(place))
  })

  bot.respond(/coffeepoll start/i, function (res) {
    if (!isPollNotStarted()) return res.send(messages.errorAlreadyStarted)

    var near = brain.get('near')
    var radius = brain.get('radius')

    var params = {
      near: near,
      categoryId: messages.category,
      radius: radius
    }

    return foursquare.venues.search(params, function (error, payload) {
      if (error === 400) return res.send(messages.errorPlaceNotFound(near))
      if (error) return res.send(error)

      var message = messages.hello(bot.name)
      var coffeeShops = _.sample(payload.response.venues, 3)

      for (var i = 0; i < coffeeShops.length; i++) {
        var cs = coffeeShops[i]
        message += i + ': ' + cs.name + ' (' + messages.url + cs.id + ')\n'
        message += cs.location.address + '\n\n'
        options[i] = cs
        votes[i] = 0
      }

      return res.send(message)
    })
  })

  bot.respond(/coffeepoll radius (.*)/i, function (res) {
    var radius = res.match[1]

    if (isRadiusNotValid(radius)) return res.send(messages.errorRadiusNotValid)

    brain.set('radius', parseInt(radius))
    return res.send(messages.radiusUpdated(brain.get('radius')))
  })

  bot.respond(/coffeepoll vote (.*)/i, function (res) {
    var username = res.message.user.name.toLowerCase()
    var number = res.match[1]

    if (isUserAlreadyVoted(username)) return res.send(messages.errorAlreadyVoted(username))
    if (isPollNotStarted()) return res.send(messages.errorStart(bot.name))
    if (isVoteNotValid(number)) return res.send(messages.errorVoteNotFound)

    votes[number] += 1
    participants[username] = true

    return res.send(messages.thanks)
  })

  bot.respond(/coffeepoll finish/i, function (res) {
    if (isPollNotStarted()) return res.send(messages.errorStart(bot.name))

    var greater = _.last(votes.slice().sort())
    var winner = options[_.indexOf(votes, greater)]
    clearPoll()

    return res.send(messages.win(winner))
  })

  bot.respond(/coffeepoll help/i, function (res) {
    return res.send(messages.help)
  })

  bot.respond(/coffeepoll partial/i, function (res) {
    if (isPollNotStarted()) return res.send(messages.errorStart(bot.name))

    var message = messages.partial

    for (var i = 0; i < options.length; i++) {
      message += options[i].name + ': ' + votes[i] + ' vote(s)\n'
    }

    return res.send(message)
  })
}

@@ -1455,32 +1455,35 @@
 %0A  bot.respond(/
+(?:
 coffeepoll near 
@@ -1472,24 +1472,35 @@
 ?:coffeepoll
+%7Ccoffepoll)
  near (.*)/i
@@ -1635,32 +1635,35 @@
 %0A  bot.respond(/
+(?:
 coffeepoll start
@@ -1652,24 +1652,35 @@
 ?:coffeepoll
+%7Ccoffepoll)
  start/i, fu
@@ -2553,32 +2553,35 @@
 %0A  bot.respond(/
+(?:
 coffeepoll radiu
@@ -2574,16 +2574,27 @@
 ffeepoll
+%7Ccoffepoll)
  radius 
@@ -2850,32 +2850,35 @@
 %0A  bot.respond(/
+(?:
 coffeepoll vote 
@@ -2867,24 +2867,35 @@
 ?:coffeepoll
+%7Ccoffepoll)
  vote (.*)/i
@@ -3351,32 +3351,35 @@
 %0A  bot.respond(/
+(?:
 coffeepoll finis
@@ -3368,24 +3368,35 @@
 ?:coffeepoll
+%7Ccoffepoll)
  finish/i, f
@@ -3658,32 +3658,35 @@
 %0A  bot.respond(/
+(?:
 coffeepoll help/
@@ -3679,16 +3679,27 @@
 ffeepoll
+%7Ccoffepoll)
  help/i,
@@ -3772,16 +3772,19 @@
 espond(/
+(?:
 coffeepo
@@ -3777,32 +3777,43 @@
 d(/(?:coffeepoll
+%7Ccoffepoll)
  partial/i, func

Accept misstyped command as valid