
import numpy as np
import settings
from otree.api import *



doc = """
Beauty Contest Game Program
"""

session_config_default = settings.SESSION_CONFIG_DEFAULTS


class C(BaseConstants):
#To be defined at the beginning of the experiment
    TOTAL_PLAYERS = 3 
    PLAYERS_PER_GROUP = 3
    NUM_ROUNDS = 10
    NAME_IN_URL = 'beauty_contest'
    GUESS_MIN = session_config_default['lower_bound']
    GUESS_MAX = session_config_default['upper_bound']
    MEAN = 0
    VARIANCE = 10



class Subsession(BaseSubsession):
    pass


class Group(BaseGroup):
    average_round = models.FloatField()


class Player(BasePlayer):
    guess = models.IntegerField(
        min=C.GUESS_MIN, max=C.GUESS_MAX, label="Please, enter your choice.",
    )
    target_number = models.IntegerField(initial=0)
    points = models.IntegerField(initial=0)
    questAnswer1 = models.IntegerField(label='If John can drink one barrel of water in 6 days, and Mary can drink one barrel of water in 12 days, how long would it take them to drink one barrel of water together? (in days)')
    questAnswer2 = models.IntegerField(label='Jerry received both the 15th highest and the 15th lowest mark in the class. How many students are in the class?')
    questAnswer3 = models.IntegerField(label='A man buys a pig for $60, sells it for $70, buys it back for $80, and sells it finally for $90. How much has he made?')
    demoAnswer1 = models.IntegerField(label='Age:')
    demoAnswer2 = models.IntegerField(
        label='Gender:',
        choices=[        
        [1, 'Male'],
        [2, 'Female'],
        [3, 'Non-binary'],
        [4, 'Other']
        ],
        widget=widgets.RadioSelect
        )
    demoAnswer3 = models.IntegerField(
        label='Personal annual income:',
        choices=[        
        [1, '$0-$25,000'],
        [2, '$25,001-$50,000'],
        [3, '$50,001-$75,000'],
        [4, '$75,001-$100,000'],
        [4, 'Greater than $100,000']
        ],
        widget=widgets.RadioSelect
        )
    demoAnswer4 = models.IntegerField(
        label='Highest level of schooling or degree completed:',
        choices=[        
        [1, 'Less than high school'],
        [2, 'High school'],
        [3, 'Some college'],
        [4, 'College degree'],
        [4, 'Post-college (graduate) degree']
        ],
        widget=widgets.RadioSelect
        )
    demoAnswer5 = models.StringField(label='Occupation:')

# Input variables from session table
    c = models.FloatField(initial=session_config_default['value_C'])
    p = models.FloatField(initial=session_config_default['value_P'])
    v = models.FloatField(initial=session_config_default['value_V'])
    set_e = models.FloatField(initial=session_config_default['set_E'])
    set_b = models.FloatField(initial=session_config_default['set_Bound'])

# Input variables for target function
#   c = models.IntegerField(initial=0)
#   p = models.IntegerField(initial=0.6666)

# if set_e is 0, e (normal distribution) is off, if set_e is 1, e is on.
#    set_e = models.IntegerField(initial=1)
    e = models.FloatField(initial=0)

# Prize value
#    v = models.IntegerField(initial=100)


# FUNCTIONS
def set_payoffs(group: Group):
    players = group.get_players()
    guesses = [p.guess for p in players]
    group.average_round = sum(guesses) / len(players)


#def normDistribution(player: Player):
#    variance = 10
#    mean = 0
#    player.e = np.random.normal(mean, np.sqrt(variance))


# PAGES
class Instructions(Page):
    @staticmethod
    def is_displayed(player: Player):
        return player.round_number == 1

    def vars_for_template(player: Player):
        return dict(
            totalPlayers = C.TOTAL_PLAYERS,
            otherPlayers = C.TOTAL_PLAYERS - 1,
            set_e = player.set_e,
            set_b = player.set_b,
            e = player.e,
            c = player.c,
            p = player.p,
            lb = C.GUESS_MIN,
            ub = C.GUESS_MAX
        )

class Guess_st1(Page):
    form_model = 'player'
    form_fields = ['guess']

    @staticmethod
    def vars_for_template(player: Player):
        group = player.group

        if(player.set_e == 1):
            player.e = round(np.random.normal(C.MEAN, np.sqrt(C.VARIANCE)),4)
        else:
            player.e = 0

        return dict(
            set_e = player.set_e,
            set_b = player.set_b,
            e = player.e,
            c = player.c,
            p = player.p,
            lb = C.GUESS_MIN,
            ub = C.GUESS_MAX
            )

class ResultsWaitPage(WaitPage):
    after_all_players_arrive = set_payoffs

class Guess_st2(Page):
    form_model = 'player'

    @staticmethod
    def vars_for_template(player: Player):
        group = player.group

        return dict(
            guess = player.guess,
            average_round = group.average_round,
            e = player.e,
            target_number = round((player.c + (player.p * group.average_round) + player.e),2),
            points = round(player.v / (1 + abs(player.guess - player.target_number)),2),
            c = player.c,
            p = player.p,
            set_e = player.set_e,
            v = player.v,
            )


class Final_Screen(Page):
    
    def is_displayed(player: Player):
        return player.round_number == C.NUM_ROUNDS


class Questionnaire(Page):
    form_model = 'player'
    form_fields = [
    'questAnswer1', 
    'questAnswer2', 
    'questAnswer3', 
    'demoAnswer1', 
    'demoAnswer2',
    'demoAnswer3',
    'demoAnswer4',
    'demoAnswer5',
    ]
    
    def is_displayed(player: Player):
        return player.round_number == C.NUM_ROUNDS


class Final_Screen_With_Results(Page):

    def is_displayed(player: Player):
        return player.round_number == C.NUM_ROUNDS

    @staticmethod
    def vars_for_template(player: Player):
        group = player.group

  #      sorted_guesses = sorted(p.guess for p in group.get_players())
  #      return dict(sorted_guesses=sorted_guesses)

page_sequence = [Instructions, Guess_st1, ResultsWaitPage, Guess_st2, Final_Screen, Questionnaire, Final_Screen_With_Results]
 