require 'rails_helper'
include Warden::Test::Helpers
Warden.test_mode!

feature 'Play a hand', type: :feature, js: true do
  before(:each) do
    @game = setup_game
    @game.reload
    @player = @game.controlling_player
    signin(@player.user.email,'password')
    visit game_path @game
  end

  after(:each) do
    Warden.test_reset!
  end

  scenario 'player only sees own cards' do
    #expect to see own cards
    #expect not to see other players cards
  end

  scenario 'player only sees own controls' do
    #expect to see own controls
    #expect not to see other players controls
  end

  scenario 'first play does not contain lowest card' do
    # controlling_player plays hand not containing lowest card
    # expect unsuccessful play message hand MUST contain lowest card

    # Play the highest card
    @card_to_play = @player.inventory.last
    find_card(@card_to_play).click
    #click_button 'Play Hand'
    click_button "play_hand_button_#{@player.id}"

    # No play to beat, because play was invalid
    expect(@game.play_to_beat).to eq(nil)
    # TODO: This scenario is causing other scenarios to fail unless we slow down here
    sleep 1
    # TODO: Flash messages
    #expect(page).to have_content "First hand must contain the lowest card: #{@game.lowest_card.to_s}"
  end

  # Scenario: The first play must be the lowest dealt card
  #   Given: A new game and I am the holder of the lowest card
  #   When I play a hand containing the lowest card
  #   Then I see the hand to beat is this play
  scenario 'first play contains lowest card' do
    @card_to_play = @game.lowest_card
    find_card(@card_to_play).click
    #click_button 'Play Hand'
    click_button "play_hand_button_#{@player.id}"
    expect(cards_to_beat).to eq @game.lowest_card.to_s
  end

  # Scenario: Played cards leave the players inventory
  #   Given I am the current player
  #   When I play a hand
  #   Then the cards played should leave my inventory
  scenario 'played cards are removed from the players inventory' do
    # Store initial state of players inventory
    @player_inventory = @player.inventory.join(' ')
    @card_to_play = @player.inventory.first
    find_card(@card_to_play).click
    click_button 'Play Hand'
    #wait_for_ajax
    expect(page).to have_content " "
    # Played hand is rendered
    expect(cards_to_beat).to eq @game.lowest_card.to_s
    # Player inventory is rendered without played cards
    #TODO: Deprecated have_content for inventory. Write new expectation.
    expect(page.find("#player_controls_#{@player.id}")).to_not have_content(@card_to_play.to_s)
  end

  # Scenario: Invalid cards do not leave the players inventory
  #   Given I am the current player
  #   When I play an invalid hand
  #   Then the cards played should not leave my inventory
  scenario 'invalid hand played cards are not removed from the players inventory' do
    #@game.reload
    # Store initial state of players inventory
    @initial_player_inventory = @player.inventory

    # Create invalid hand
    @cards_to_play  = []
    @cards_to_play << @player.inventory.last
    @cards_to_play << @player.inventory.first

    # Select each card to play
    @cards_to_play.map {|card| find("[data-card-name='#{card.to_s}'] ~ img").click }
    #click_button 'Play Hand'
    click_button "play_hand_button_#{@player.id}"

    # Played hand is rendered
    # TODO: Flash messages
    #expect(page).to have_content("Invalid pair")
    # Player inventory is rendered with played cards
    @initial_player_inventory.each do |card|
      expect(page).to have_selector("[data-card-name='#{card.to_s}'] ~ img")
    end
    # TODO: This scenario is causing other scenarios to fail unless we slow down here
    sleep 1
    # Player inventory method still returns played cards because the play was invalid
    # TODO: Flash messages
    #expect(@game.controlling_player.inventory.order(:value).join(' ')).to have_content(@card_to_play.to_s)
  end

  # Scenario: Current player status updates after successful play
  #   Given I am the current player
  #   When I play a hand
  #   Then the next player becomes the current player
  scenario 'active player rotates after a valid hand' do
    @game.reload
    @player = @game.controlling_player
    @next_player_id = @game.next_player_id
    @controlling_player_id = @game.controlling_player.id
    @controlling_player_index = @game.player_ids_by_seat_order.index(@game.controlling_player_id)

    @card_to_play = @player.inventory.first
    find_card(@card_to_play).click
    click_button 'Play Hand'
    expect(page).to have_content "Hand to beat"
    expect(cards_to_beat).to eq @card_to_play.to_s
    expect(page).to have_selector("#player-#{@next_player_id}.has-control")
  end

  # Scenario: Player can not play an invalid hand on their turn
  #   Given I am the active player
  #   When I play an invalid hand
  #   Then I see an invalid hand message
  scenario 'active player can not play an invalid hand' do
    #@game.reload
    @cards_to_play = [@game.controlling_player.player_cards.order(:value).first.to_s, @game.controlling_player.player_cards.order(:value).last.to_s]
    @cards_to_play.each do |card|
      find("[data-card-name='#{card.to_s}'] ~ img").click
    end
    #click_button 'Play Hand'
    click_button "play_hand_button_#{@player.id}"
    # controlling_player plays an invalid hand
    # expect invalid hand message
    #:TODO: Flash messages
    #expect(page).to have_content("Invalid pair.")
    # expect inventory to remain unchanged
    @game.controlling_player.inventory.each do |card|
      expect(page).to have_selector("[data-card-name='#{card.to_s}'] ~ img")
    end
    # TODO: This scenario is causing other scenarios to fail unless we slow down here
    sleep 1
  end

  # Scenario: Player can not play a hand when it is not their turn
  #   Given I am not the active player
  #   When I play a hand
  #   Then I see an unsuccessful play message
  scenario 'non-controlling player can not play a hand' do
    # create game with players
    # not_controlling_player plays a valid hand
    # expect not to be able to submit a play
    @non_controlling_player = @game.players.where.not(id: @game.controlling_player_id).first
    login_as(@non_controlling_player.user, scope: :user)
    visit game_path @game
    #expect(page).to_not have_button 'Play Hand'
    elem = page.find "input#play_hand_button_#{@non_controlling_player.id}"
    expect(elem.disabled?).to be true
    # TODO: Submit a POST request
  end

  # Scenario: Player can pass when it is their turn
  #   Given I am the active player
  #   When I pass
  #   Then I see an successful pass message
  scenario 'active player can pass' do
    @current_user = @game.controlling_player
    #click_button 'Pass'
    click_button "pass_hand_button_#{@player.id}"
    ## TODO: Flash messages
    #expect(page).to have_content 'Successfully passed.'
    # Expect active player should rotate
    #expect(page).to_not have_button 'Play Hand'
    elem = page.find "input#play_hand_button_#{@player.id}"
    expect(elem.disabled?).to be false

    @new_controlling_player = @game.controlling_player
    expect(@game.controlling_player).to_not eq(@controlling_player)
    # TODO: This scenario is causing other scenarios to fail unless we slow down here
    sleep 1
  end

  # Scenario: Player can play any hand when they are the player to beat
  #   Given I am the active player
  #   And I am the player to beat
  #   Then I see an open table
  scenario 'active player to beat has open table' do
    # play a card
    @game.reload
    @player = @game.controlling_player
    @card_to_play = @player.inventory.first
    find("[data-card-name='#{@card_to_play.to_s}'] ~ img").click
    #click_button 'Play Hand'
    click_button "play_hand_button_#{@player.id}"

    #TODO: Fix race condition
    sleep 4
    expect(page).to have_content "Hand to beat"
    expect(cards_to_beat).to eq @card_to_play.to_s
    @game.reload
    expect(@game.player_to_beat).to eq @player

    # set control player to player to beat
    @game.controlling_player_id = @player.id
    @game.save
    @game.reload
    visit game_path @game

    # Expect active player should rotate
    #expect(page).to have_button 'Play Hand'
    expect(page).to have_button "play_hand_button_#{@player.id}"
    #expect(@game.player_to_beat).to eq(@game.controlling_player)
    expect(page).to have_content 'Hand to beat: None'
  end

  # Scenario: Player wins the game
  #   Given I am the active player
  #   And I play my last card(s)
  #   And I am the first player to do so
  #   Then I see a 1st place winner message
  scenario 'first place winner' do
    # play last card
    pending "TBD"
    expect(@player.inventory.count).to eq 0
    expect(page).to have_content "Winner: #{@player.display_name}"
  end


end
