const { game, getUser, saveGame, petBoost, getCoins, updateAll, getCPS, addCoins, commas} = require('./utils')
const slack = require('../../slack')
const maxValue = 10

const makePet = () => ({
  food: 0,
  fun: 0,
})

const bad = (text = '') => `
   _^__^_
  / x  x \\${text && `  "${text}"`}
 >\\  o   /<
    ----
`

const normal = (text = '') => `
   _^__^_
  / o  o \\${text && `  "${text}"`}
 >\\  __  /<
    ----
`

const great = (text = '') => `
   _^__^_
  / ^  ^ \\${text && `  "${text}"`}
 >\\ \\__/ /<
    ----
`

const makeBar = (name, value) => {
  const left = '#'.repeat(value)
  const right = ' '.repeat(maxValue - value)
  return `${name}:`.padEnd(6) + `[${left}${right}]`
}

const buildBlocks = ({text}) => [
  {
    type: 'section',
    text: {
      type: 'mrkdwn',
      text
    }
  },
  {
    type: 'actions',
    elements: [
      buildBlock('Feed'),
      buildBlock('Play'),
    ]
}]

const buildBlock = actionName => (
  {
    type: 'button',
    text: {
      type: 'plain_text',
      text: actionName,
      emoji: true
    },
    value: actionName,
    action_id: actionName
  }
)

// game.channelPets ??= {}

const petToText = (pet, additional, say) => {
  const stats = Object.values(pet)
  const hasTerribleStat = stats.filter(value => value < 1).length > 0
  const averageStat = stats.reduce((total, current) => total + current, 0) / stats.length
  let pic
  if (hasTerribleStat && averageStat < 3) {
    pic = bad
  } else if (!hasTerribleStat && averageStat > 8) {
    pic = great
  } else {
    pic = normal
  }
  
  let speech
  if (pic === bad || Math.random() < 0.5) {
    speech = pic()
  } else {
    speech = pic('Mrow')
  }
  additional ??= ''
  if (additional) {
    additional = `\n${additional}\n`
  }
  
  const text =
    '```\n'
    + `Current HVAC Multiplier: ${petBoost()}x\n`
    + `${makeBar('Food', pet.food)}`
    + `\n${makeBar('Fun', pet.fun)}`
    + '\n'
    + speech
    + '```'
    + additional
  saveGame('pet generation')
  const ret = ({
    text,
    blocks: buildBlocks({text})
  })
  // If there's a say() this is a new message, otherwise, we're editing.
  if (say) {
    say(ret).then(({ channel, ts }) => {
      // game.channelPets[channel] = ts
      return updateAll({ name: 'pet', add: { channel, ts }})
    }).catch(console.error)
  }
  return ret
}

const updateEveryone = async additional =>
    updateAll({ name: 'pet', ...petToText(game.pet, additional) })

const statDown = () => {
  const pet = (game.pet ??= makePet())
  pet.food = Math.max(pet.food - 1, 0)
  pet.fun = Math.max(pet.fun - 1, 0)

  updateEveryone().catch(console.error)

  setTimeout(() => {
    Object.entries(game.users).forEach(([id, u]) => u.coins = getCoins(id))
    statDown()
  }, 1000 * 60 * 90) // Every 90 minutes
}

statDown()

const addInteraction = ({ actionId, perform }) =>
  slack.app.action(actionId, async ({ body, ack, say, payload }) => {
    try {
      await ack()
      game.pet ??= makePet()
      const [everyone, local] = perform(game.pet, await getUser(body.user.id))
      await updateEveryone(everyone)
      if (local) {
        await say(local)
      }
    } catch (e) {
      console.error(e)
    }
  })

const oneMinuteOfCps = user => Math.floor(getCPS(user) * 60)

addInteraction({ actionId: 'Feed', perform: (pet, user) => {
    if (pet.food >= 10) {
      return [`I'm too full to eat more, ${user.name}!`]
    }
    const oneMinute = oneMinuteOfCps(user)
    addCoins(user, oneMinute)
    pet.food += 1
    return [`Thanks for the grub, ${user.name}!`, `Earned ${commas(oneMinute)} HVAC for feeding our pet!`]
  } })

addInteraction({ actionId: 'Play', perform: (pet, user) => {
    if (pet.fun >= 10) {
      return [`I'm too tired for more games, ${user.name}.`]
    }
    const oneMinute = oneMinuteOfCps(user)
    addCoins(user, oneMinute)
    pet.fun += 1
    return [`Thanks for playing, ${user.name}!`, `Earned ${commas(oneMinute)} HVAC for playing with our pet!`]
  }})

module.exports = {
  makePet,
  petToText
}
