from otree.api import *
import random

author = 'Nishtha'

doc = """
This is the symmetric contest with beta=1
"""

class Constants(BaseConstants):
    name_in_url = 'Sym'
    players_per_group = 2
    num_rounds = 5
    endowment = 100
    A_multiplier = 1
    Prize = 100

class Subsession(BaseSubsession):
    def creating_session(subsession):
        subsession.group_randomly(fixed_id_in_group=True)  # Group players randomly while keeping ID in group fixed

class Group(BaseGroup):
    total_investment = models.FloatField()
    effective_investment_A = models.FloatField()
    effective_investment_B = models.FloatField()
    total_effective_investment = models.FloatField()
    pwin_A = models.FloatField()
    pwin_B = models.FloatField()
    chance_A = models.FloatField()
    chance_B = models.FloatField()
    Winner_A = models.BooleanField()
    guess_A = models.BooleanField()
    guess_B = models.BooleanField()

    # Payoff in period 1
    def set_payoffs_1(group):
        A = group.get_player_by_id(1)
        B = group.get_player_by_id(2)
        group.effective_investment_A = Constants.A_multiplier * A.investment
        group.effective_investment_B = B.investment
        group.total_investment = A.investment + B.investment
        group.total_effective_investment = group.effective_investment_A + group.effective_investment_B

        if group.total_effective_investment > 0:
            group.pwin_A = group.effective_investment_A / group.total_effective_investment
            group.pwin_B = group.effective_investment_B / group.total_effective_investment
        else:
            group.pwin_A = 0.5
            group.pwin_B = 0.5

        group.Winner_A = random.random() < group.pwin_A

        group.chance_A = round(100 * group.pwin_A, 2)
        group.chance_B = round(100 * group.pwin_B, 2)

        group.guess_A = abs(A.Perceived_investment - B.investment) <= 5
        group.guess_B = abs(B.Perceived_investment - A.investment) <= 5

        A.is_guess = group.guess_A
        B.is_guess = group.guess_B

        for player in [A, B]:
            player.guesspayoff1 = 25 if player.is_guess else 0

        A.is_winner = group.Winner_A
        B.is_winner = not group.Winner_A

        for player in [A, B]:
            player.payoff1 = 200 - player.investment if player.is_winner else 100 - player.investment
            player.Totalpayoff1 = player.payoff1 + player.guesspayoff1

    effective_investment_A_2 = models.FloatField()
    effective_investment_B_2 = models.FloatField()
    total_effective_investment_2 = models.FloatField()
    pwin_A_2 = models.FloatField()
    pwin_B_2 = models.FloatField()
    chance_A_2 = models.FloatField()
    chance_B_2 = models.FloatField()
    Winner_A_2 = models.BooleanField()
    guess_A_2 = models.BooleanField()
    guess_B_2 = models.BooleanField()

    # Payoff in period 2
    def set_payoffs_2(group):
        A = group.get_player_by_id(1)
        B = group.get_player_by_id(2)

        group.effective_investment_A_2 = Constants.A_multiplier * A.investment_2 if group.Winner_A else A.investment_2
        group.effective_investment_B_2 = B.investment_2
        group.total_effective_investment_2 = group.effective_investment_A_2 + group.effective_investment_B_2

        if group.total_effective_investment_2 > 0:
            group.pwin_A_2 = group.effective_investment_A_2 / group.total_effective_investment_2
            group.pwin_B_2 = group.effective_investment_B_2 / group.total_effective_investment_2
        else:
            group.pwin_A_2 = 0.5
            group.pwin_B_2 = 0.5

        group.Winner_A_2 = random.random() < group.pwin_A_2

        group.chance_A_2 = round(100 * group.pwin_A_2, 2)
        group.chance_B_2 = round(100 * group.pwin_B_2, 2)

        group.guess_A_2 = abs(A.Perceived_investment_2 - B.investment_2) <= 5
        group.guess_B_2 = abs(B.Perceived_investment_2 - A.investment_2) <= 5

        A.is_guess_2 = group.guess_A_2
        B.is_guess_2 = group.guess_B_2

        for player in [A, B]:
            player.guesspayoff2 = 25 if player.is_guess_2 else 0

        A.is_winner_2 = group.Winner_A_2
        B.is_winner_2 = not group.Winner_A_2

        for player in [A, B]:
            player.payoff2 = 200 - player.investment_2 if player.is_winner_2 else 100 - player.investment_2
            player.Totalpayoff2 = player.payoff2 + player.guesspayoff2

class Player(BasePlayer):
    investment = models.FloatField(
        min=0, max=Constants.endowment,
        doc="""Bid in contest"""
    )
    Perceived_investment = models.FloatField(
        min=0, max=Constants.endowment,
        doc="""Perceived bid of other player in contest"""
    )
    payoff1 = models.CurrencyField()
    payoff2 = models.CurrencyField()
    payoff_total = models.CurrencyField()
    guesspayoff1 = models.CurrencyField()
    guesspayoff2 = models.CurrencyField()
    Totalpayoff1 = models.CurrencyField()
    Totalpayoff2 = models.CurrencyField()

    investment_2 = models.FloatField(
        min=0, max=Constants.endowment,
        doc="""Bid in Pd2"""
    )
    Perceived_investment_2 = models.FloatField(
        min=0, max=Constants.endowment,
        doc="""Perceived bid of other player in Pd2"""
    )

    Quiz = models.IntegerField(label="If both you and your matched other participant make equal bids, what is your chance of winning the 100 points?", choices=[[1, '25%'], [2, '50%'], [3, '75%']], widget=widgets.RadioSelectHorizontal)
    Quiz2 = models.IntegerField(
        label="If you bid more than your matched other participant, what is your chance of winning the 100 points?",
        choices=[[1, 'Higher than 50%'], [2, '100%']], widget=widgets.RadioSelectHorizontal)
    q1 = models.StringField()

    is_winner = models.BooleanField()
    is_winner_2 = models.BooleanField()
    is_guess = models.BooleanField()
    is_guess_2 = models.BooleanField()
    timeout1 = models.BooleanField()
    timeout2 = models.BooleanField()

    def set_quiz(player):
        if player.Quiz == 2 and player.Quiz2 == 1:
            player.q1 = "Yes! That's correct."
        else:
            player.q1 = "Oops! That's not right."

    def role(player):
        if player.id_in_group == 1:
            return 'A'
        if player.id_in_group == 2:
            return 'B'

    def other_player(player):
        return player.get_others_in_group()[0]

    def set_payoffs_total(player):
        player.payoff_total = player.Totalpayoff1 + player.Totalpayoff2  # Total payoff for player A
        if player.round_number < 4:
            player.payoff = 0
        else:
            player.payoff = player.payoff_total

class WelcomeVideo(Page):
    timeout_seconds = 180

    def is_displayed(player):
        return player.subsession.round_number == 1

class Welcome(Page):
    timeout_seconds = 180
    def is_displayed(player):
        return player.subsession.round_number == 1

class Welcome2(Page):
    timeout_seconds = 180
    def is_displayed(player):
        return player.subsession.round_number == 1

class PartOne(Page):
    timeout_seconds = 300
    def is_displayed(player):
        return player.subsession.round_number == 1

class Rounds(Page):
    timeout_seconds = 90
    def is_displayed(player):
        return player.subsession.round_number == 1

class Periods(Page):
    timeout_seconds = 90
    def is_displayed(player):
        return player.subsession.round_number == 1

class Types(Page):
    timeout_seconds = 180
    def is_displayed(player):
        return player.subsession.round_number == 1
    def vars_for_template(player):
        return dict(
            other_player_role=player.other_player().role
        )

class TypeWait(Page):
    def is_displayed(player):
        return player.subsession.round_number == 1

class YourType(Page):
    timeout_seconds = 90
    def is_displayed(player):
        return player.subsession.round_number == 1
    def vars_for_template(player):
        return dict(
            other_player_role=player.other_player().role
        )

class BidBag(Page):
    timeout_seconds = 90
    def is_displayed(player):
        return player.subsession.round_number == 1

class Payoff(Page):
    timeout_seconds = 60
    def is_displayed(player):
        return player.subsession.round_number == 1

class Task(Page):
    timeout_seconds = 60
    def is_displayed(player):
        return player.subsession.round_number == 1
    def vars_for_template(player):
        return dict(
            other_player_role=player.other_player().role
        )

class Summary(Page):
    timeout_seconds = 120
    def is_displayed(player):
        return player.subsession.round_number == 1

class Quiz(Page):
    timeout_seconds = 120
    def is_displayed(player):
        return player.subsession.round_number == 1

    form_model = 'player'
    form_fields = ['Quiz', 'Quiz2']

    def before_next_page(player, timeout_happened):
        player.set_quiz()

class Quiz_Result(Page):
    timeout_seconds = 60
    def is_displayed(player):
        return player.subsession.round_number == 1

class Start(Page):
    timeout_seconds = 30
    def is_displayed(player):
        return player.subsession.round_number == 1

class StartWait(WaitPage):
    def is_displayed(player):
        return player.subsession.round_number == 1

class Match(Page):
    timeout_seconds = 15
    def is_displayed(subsession):
        return subsession.round_number > 1

class MatchWait(WaitPage):
    def is_displayed(subsession):
        return subsession.round_number > 1
    def vars_for_template(player):
        return dict(
            player_in_all_rounds_rev=reversed(player.in_previous_rounds())
        )
    template_name = 'Sym/MatchWait.html'

class PRp1(Page):
    timeout_seconds = 240
    form_model = 'player'
    form_fields = ['investment', 'Perceived_investment']

    def vars_for_template(player):
        return dict(
            other_player_role=player.other_player().role
        )
    def before_next_page(player, timeout_happened):
        if timeout_happened:
            player.investment = 25
            player.timeout1 = True

class PRp1Wait(WaitPage):
    def after_all_players_arrive(group):
        group.set_payoffs_1()

class PRp2(Page):
    timeout_seconds = 240
    form_model = 'player'
    form_fields = ['investment_2', 'Perceived_investment_2']
    def vars_for_template(player):
        return dict(
            other_player_role=player.other_player().role
        )
    def before_next_page(player, timeout_happened):
        if timeout_happened:
            player.investment_2 = 25
            player.timeout2 = True

class PRp2Wait(WaitPage):
    def after_all_players_arrive(group):
        group.set_payoffs_2()

class Results(Page):
    timeout_seconds = 60
    def vars_for_template(player):
        return dict(
            other_player_investment=player.other_player().investment,
            other_player_role=player.other_player().role
        )
class Results2(Page):
    timeout_seconds = 60
    def vars_for_template(player):
        return dict(
            other_player_investment_2=player.other_player().investment_2,
            other_player_role=player.other_player().role
        )

    def before_next_page(player, timeout_happened):
        player.set_payoffs_total()

class Final_Results(Page):
    timeout_seconds = 60
    def vars_for_template(player):
        return dict(
            player_in_all_rounds_rev=reversed(player.in_all_rounds())
        )

class Payment(Page):
    timeout_seconds = 60
    def is_displayed(subsession):
        return subsession.round_number == Constants.num_rounds
    def vars_for_template(player):

        return {
            'playerpay': player.in_round(5).payoff,
            'player_in_all_rounds_rev': reversed(player.in_all_rounds())
        }

page_sequence = [WelcomeVideo, PartOne, Types, Quiz, Quiz_Result, Payoff, Start, Match, MatchWait, PRp1,
    PRp1Wait,
    Results, PRp2, PRp2Wait, Results2, Final_Results, Payment]
