__init__.py
from otree.api import (
    Page,
    WaitPage,
    models,
    BaseConstants,
    BaseSubsession,
    BaseGroup,
    BasePlayer,
    Currency as c,
    currency_range,
)

doc = """ 
In a second price auction game, players simultaneously bid on the item being 
auctioned.<br/> 
Prior to bidding, they are given their personal value of the item. 
The winner of the auction is the player who places the highest bid, but the price payed by the winner is equal to the  
value of the second highest bid.<br/> 
Bids are private. The payoff depends on the value of the item for the winner and the price payed by the winner.<br/> 
The first half of rounds utilizes a fixed grouping and grouping is random for the second half. <br/> 
"""


# Defining constants
class Constants(BaseConstants):
    name_in_url = 'second_price_auction'
    players_per_group = 3
    num_rounds = 6
    instructions_template = 'common_value_auction/instructions.html'
    min_allowable_bid = c(0)
    max_allowable_bid = c(100)
    # Error margin for the value estimates shown to the players
    estimate_error_margin = c(1)


class Subsession(BaseSubsession):
    pass


# Define group based terms
class Group(BaseGroup):
    highest_bid = models.CurrencyField()
    second_highest_bid = models.CurrencyField()
    winner = models.IntegerField()
    item_value = models.CurrencyField()


# Define player based terms
class Player(BasePlayer):
    # Define each player's personal value
    value = models.CurrencyField()
    price = models.CurrencyField()

    # Create a field for the bid placed by each player
    bid = models.CurrencyField(
        min=Constants.min_allowable_bid,
        max=Constants.max_allowable_bid,
        doc="""Amount bidded by the player""",
        label="Bid amount",)

    # Define whether or not the are winner
    is_winner = models.BooleanField()

    # Define price
    price = models.CurrencyField()


# Functions
# Establishes a total earnings variable for each participant and initiate to 0 at the beginning of session.
def creating_session(subsession):
    import random

    # group randomly halfway through the rounds
    if subsession.round_number >= 4:
        subsession.group_randomly()

    print('in creating session')
    for p in subsession.get_players():
        p.value = random.uniform(0, 1) * 100
        p.is_winner = False
        if subsession.round_number == 1:
            p.participant.vars['totalEarnings'] = 0
    # How to get into groups.
    # for g in subsession.get_groups():
    # if subsession.round_number <=3

    # stable group?
    # else
    # import random


def auction_outcome(group: Group):
    # Get players in the group
    players = group.get_players()

    # Get bids from the players
    bids = [p.bid for p in players]

    # Now we have to sort the bids in descending order (largest is first)
    bids.sort(reverse=True)

    # Define the highest and second highest bids to their respective group variables

    group.highest_bid = bids[0]
    group.second_highest_bid = bids[1]
    group.item_value = bids[1]

    for p in group.get_players():
        p.price = group.second_highest_bid

    # TIE BREAKER CONDITION
    # The first get the set of players IDs who bid the highest for the round.
    highest_bidders = []
    for p in players:
        if p.bid == group.highest_bid:
            highest_bidders.append(p.id_in_group)

    # Next randomly select one of the players in the tie
    import random
    group.winner = random.choice(highest_bidders)

    # Finally get the player model of the winning bidder and flag as the winner
    winning_player = group.get_player_by_id(group.winner)
    winning_player.is_winner = True

    # Set payoffs for round
    for p in players:
        if p.is_winner:
            p.payoff = p.value - group.second_highest_bid
            if p.payoff < 0:
                p.payoff = 0
        else:
            p.payoff = 0



# PAGES
class Introduction(Page):
    def is_displayed(player):
        return player.round_number == 1



# Page for placing bids of the rounds with randomly selected players
class PlaceBid(Page):
    form_model = 'player'
    form_fields = ['bid']

    @staticmethod
    def get_timeout_seconds(player: Player):
        return 120

    def before_next_page(player, timeout_happened):
        if timeout_happened:
            player.bid = 0


# Page for placing bids of the rounds with same players
#class PlaceBid2(Page):
   # form_model = 'player'
   # form_fields = ['bid']


# waiting page between rounds
class ResultsWaitPage(WaitPage):
    after_all_players_arrive = 'auction_outcome'
    body_text = "Please wait for everyone to submit their bids."


class Results(Page):
    @staticmethod
    def vars_for_template(player: Player):
        group = player.group
        return dict(is_greedy = player.bid - group.item_value < 0)



# def vars_for_template(player: Player):
# group = player.group




page_sequence = [Introduction, PlaceBid, ResultsWaitPage, Results]