from otree.api import *
import random
import json
from datetime import datetime
import time

doc = """
Your app description
"""

class C(BaseConstants):
    NAME_IN_URL = 'count_number'
    PLAYERS_PER_GROUP = None
    NUM_ROUNDS = 6
    POINTS_PER_CORRECT_ANSWER = cu(1)
# One round means the page sequence will be done once. Otherwise when the results page is over.


class Subsession(BaseSubsession):
    pass

def creating_session(subsession: Subsession):
    import itertools  #For a equal sized treatmentgroups we loop through the given list of treatments. Assign evenly in a repeating sequence
    if subsession.round_number == 1: # maintain consistent treatment assignments across the apps
        treatments = itertools.cycle(['control', 'treatment1', 'treatment2'])
        for player in subsession.get_players():
            treatment_group = next(treatments)
            player.participant.vars['treatment'] = treatment_group
            player.treatment_group = treatment_group



class Group(BaseGroup):
    pass


class Player(BasePlayer):
    number_entered = models.IntegerField(label='Please enter the number:') #Store the entered number
    sum_of_numbers = models.IntegerField() #Store the correct number
    matrix = models.StringField(initial ="")  #This ensures that the matrix field starts as an empty string
    result = models.StringField()
    treatment_group = models.StringField()
    start_time = models.FloatField(blank=True)  # Timestamp when the page is loaded
    end_time = models.FloatField(blank=True)  # Timestamp when the page is submitted

    skipped_task = models.BooleanField(initial=False)

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


class Start(Page):
    form_model = "player"
    form_fields = ["number_entered"]
    timeout_seconds = 30  #Für Control- und Treatmentgruppe 1 nicht anzeigen


    @staticmethod
    def vars_for_template(player: Player):
        # Initialize matrix_to_display outside the if block
        player.start_time = time.time()
        matrix_to_display = json.loads(player.matrix) if player.matrix else None

        if not player.matrix:
            matrix_size = 6
            random_matrix = [[random.randint(0, 1) for _ in range(matrix_size)] for _ in range(matrix_size)]
            correct_sum = sum(sum(row) for row in random_matrix)
            player.matrix = json.dumps(random_matrix)
            player.sum_of_numbers = correct_sum
            # Now assign the newly created matrix to matrix_to_display
            matrix_to_display = random_matrix

        progress_percent = ((player.round_number - 1) / C.NUM_ROUNDS) * 100
        treatment = player.participant.vars.get('treatment', None)


        return {
            'matrix': matrix_to_display,
            'progress_percent': progress_percent,
            'treatment': treatment,
        }

    @staticmethod
    def before_next_page(player: Player, timeout_happened):
        # Check if the skip button was pressed
        if player.skipped_task:
            # Logic for skipping to the next page
            player.is_skipped = True
            # Optionally set payoff and result if you need to record these for skipped tasks
            player.payoff = cu(0)
            player.result = "Skipped"
        else:
            # Existing logic for when the task is not skipped
            if player.sum_of_numbers == player.field_maybe_none("number_entered"):
                player.payoff = C.POINTS_PER_CORRECT_ANSWER
                player.result = "Correct"
            else:
                player.payoff = cu(0)
                player.result = "Wrong"
        player.end_time = time.time()

 #   @staticmethod
  #  def error_message(player: Player, values):      #make sure they have to repeat if wrong
 #       if values["number_entered"] != player.sum_of_numbers:  # Return an error message if the entered number is not equal to the sum of numbers
 #        return 'The answer is incorrect. Please try again.'








#generate the random numbers somewhere else!
#and then access them here
#we do not want them to refresh page and get new ones
#round_number is also set by python already

class Results(Page):
    pass

class DelayPage(Page):
    timeout_seconds = 35

    @staticmethod
    def is_displayed(player:Player):
        return player.round_number == C.NUM_ROUNDS
    @staticmethod
    def vars_for_template(player: Player):
        return {
            'delay_time_seconds': 35
        }

class CombinedResults(Page):
    @staticmethod
    def is_displayed(player: Player):
        return player.round_number == C.NUM_ROUNDS
    @staticmethod
    def vars_for_template(player: Player):
        all_players = player.in_all_rounds() #list contains all diff. players
        combined_payoff = 0  #in each round we access them
        for temp_player in all_players:
            combined_payoff += temp_player.payoff
        return {
            "combined_payoff": combined_payoff
        }




page_sequence = [Instructions,Start]
#DelayPage nicht vergessen DelayPage nach CombinedResults