# Rule cards
# Angel Protection
# Demon Haunting
# Advanced Angel & Demon Rules
# Advanced Witch Rules

# Alignment cards
# Village Clergy
# Witch x 4
# Village Peasant x 11

require './player.rb'

class Game

  MINIMUM_PLAYERS = 8

  attr_reader :hangings, :kills, :players, :deaths

  def initialize(names:)
    raise "Not enough Players!" if names.size < MINIMUM_PLAYERS
    @log = []
    @players = names.map { |n| Player.new(name: n) }
    @day        = false
    @hangings   = []
    @kills      = []
    @num_nights = 0
    @nights     = [{}]
  end

  def start!
    _assign_teams!
    _assign_characters!
  end

  # Villagers Hang
  def hang!(player)
    raise "Villagers hang during the day" if night?
    @log << "The Village Hangs #{player}..."
    player.lose_life!
    if player.dead?
      @log << "and #{player} is dead"
      @kills << player
    else
      @log << "and #{player} survived!"
    end
    @hangings << player
  end

  # Witches Kill
  def kill!(player)
    raise "Witches kill during night" if day?
    @log << "Witches tried to kill #{player}..."
    unless protected?(player)
      player.lose_life!
      if player.dead?
        @log << "and #{player} is dead"
        @kills << player
      else
        @log << "and #{player} survived!"
      end
    else
      @log << "and #{player} survived!"
    end
  end

  def record_vote(player_voting, player_voted_for)
    player.increase_hanging_vote!
    @votes[player.name] += 1
  end

  def day?
    @day
  end

  def night?
    !day?
  end

  def start_night!
    @day = false
    @num_nights += 1
    @nights << {}
    players.each(&:sleep!)
  end

  def end_night!
    players.each(&:wake_up!)
  end

  def protect!(player)
    @protected << player
    @log << "Angels protected #{player.name}"
    player.protect!
  end

  def curse!(player)
    @log << "Demons cursed #{player.name}"
    @cursed << player
    player.curse!
  end

  def deaths
    players.select{ |p| p.dead? }
  end

  def current_day
    days.last
  end

  def current_night
    nights.last
  end

  def witches
    players.select{ |p| p.witch? }
  end


  private

  def _assign_teams!
    _build_teams.zip(@players).each do |team, player|
      player.team = team
    end
  end

  def _assign_characters!
    core_characters = Character.core_characters.shuffle
    optional_characters = Character.optional_characters.shuffle

    @players.each do |player|
      if player.team == 'clergy'
        player.assign_character Character.priest
      else
        if core_characters.count > 0
          player.assign_character core_characters.pop
        else
          player.assign_character optional_characters.pop
        end
      end
    end
  end

  def _number_of_witches
    case @players.count
      when 0..8  then 2
      when 9..13 then 3
      else            4
    end
  end

  def _number_of_villagers
    @players.count - _number_of_witches - 1
  end

  def _build_teams
    clergy = ['clergy']
    witches = Array.new(_number_of_witches, 'witch')
    villagers = Array.new(_number_of_villagers, 'villager')
    (clergy + witches + villagers).flatten.shuffle
  end
end

# Imagined Interface.
# class Player

#   # team_name = 'Witch' / 'Villager'
#   def set_team!(team_name)
#   end

#   def set_character!(character_name)
#   end

# end
