from otree.api import (
    models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer,
    Currency as c, currency_range
)
import random
from otreeutils.surveys import (
generate_likert_field, generate_likert_table, create_player_model_for_survey
)
from collections import Counter

author = 'Nathaniel Burke'

doc = """
Your app description
"""

class Constants(BaseConstants):
	name_in_url = 'group_identity_switch'
	players_per_group = 2
	num_rounds = 20
	max_players_in_team = 6
	total_players = 8
	switching_rounds = [3,6,9,12,15,18]
	multiplier = [1, 1.25, 1.5, 1.75, 2, 2.25] # access multiplier like multiplier[group.team_size-1]
	team_ranges = [[100,300],[260,460]] # 100-300 is WCOB, 260-460 is COE


class Player(BasePlayer):
	college = models.IntegerField(
		choices=[
			[1, 'Walton College of Business'],
			[2, 'College of Engineering'],
		],
		widget=widgets.RadioSelect,
		label="Which college are you enrolled in?"
	)
	team = models.IntegerField() #team 1 is WCOB, team 2 is COE
	desired_team = models.IntegerField( #1 is stay, 2 is switch
		choices=[
			[1, 'I want to stay with my team'],
			[2, 'I want to switch teams'],
		],
		widget=widgets.RadioSelect,
		label="Would you like to switch teams?"
	)

	votes_for_switch = models.IntegerField(initial=0)
	votes_against_switch = models.IntegerField(initial=0)
	switch_honored = models.BooleanField()

	voted_for_players = models.StringField()

	endowment = models.CurrencyField()
	payout = models.CurrencyField()

	contribution = models.CurrencyField(
		min=0,
		label="How much will you contribute?"
	)
	def get_average_contribution(self):
		contributionSum = 0
		rounds = self.in_rounds(1, self.round_number)
		for round in rounds:
			contributionSum += round.contribution
		return (c(contributionSum) / len(rounds))

	def contribution_max(self):
		return self.endowment

	def get_team_contribution(self):
		return self.group.total_contribution - self.contribution

	def get_team_size(self):
		return len(self.group.get_players())

def make_field(fChoices, fLabel):
	return models.IntegerField(
		choices=fChoices,
		widget=widgets.RadioSelect,
		label=fLabel,
		)

class Subsession(BaseSubsession):
	def creating_session(self):
		print('in creating_session', self.round_number)

	def set_player_endowment(self):
		for p in self.get_players():
			if p.college == 1:
				p.endowment = c(random.randint(Constants.team_ranges[0][0], Constants.team_ranges[0][1]))
			elif p.college == 2:
				p.endowment = c(random.randint(Constants.team_ranges[1][0], Constants.team_ranges[1][1]))

	def group_players(self):
		players = self.get_players()
		firstT = [p for p in players if p.college == 1]
		secondT = [p for p in players if p.college == 2]
		group_matrix = []
		group_matrix.append(firstT)
		group_matrix.append(secondT)
		self.set_group_matrix(group_matrix)

	def group_players_new(self):
		players = self.get_players()
		firstT = [p for p in players if p.team == 1]
		secondT = [p for p in players if p.team == 2]
		group_matrix = []
		group_matrix.append(firstT)
		group_matrix.append(secondT)
		self.set_group_matrix(group_matrix)

	def sync_team_by_college(self):
		players = self.get_players()
		for p in players:
			p.team = p.college

	def sync_team_by_previous(self):
		players = self.get_players()
		for p in players:
			if (p.in_round(self.round_number - 1).desired_team == 2 and p.in_round(self.round_number - 1).switch_honored == True):
				if (p.in_round(self.round_number - 1).team == 2):
					p.team = 1
				else:
					p.team = 2
			else:
				p.team = p.in_round(self.round_number - 1).team

	def carry_over_data(self):
		for p in self.get_players():
			p.endowment = c(p.in_round(self.round_number - 1).payout)
			p.college = p.in_round(self.round_number - 1).college

	def switch_teams(self):
		groups = self.get_groups()
		total_players = 0
		for group in groups:
			total_players += len(group.get_players())

		for group in groups:
			group_size = len(group.get_players())
			opposite_group_size = total_players - group_size
			available_spots = Constants.max_players_in_team - opposite_group_size
			ordered = group.get_sorted_switch_players()
			#majority ordered
			maj_ordered = []
			for player in ordered:
				if (player.votes_for_switch > opposite_group_size/2):
					maj_ordered.append(player)

			while (available_spots > 0 and len(maj_ordered) > 0):
				maj_ordered[len(maj_ordered)-1].switch_honored = True
				maj_ordered.pop()

	def count_votes(self):
		#get all the players
		players = self.get_players()
		#use delimiter (,) to put votes in a list
		votes = []
		for player in players:
			if (player.voted_for_players != "-1"):
				votes += player.voted_for_players.split(",")
		#count votes in the list and store in a dictionary
		dictionary = Counter(votes)
		print(dictionary)
		#Find users based on keys and assign their votes for with dictionary value
		for key, value in dictionary.items():
			#Find user based on key
			for targetplayer in players:
				if (str(key).strip() == str(targetplayer.participant_id).strip()):
					targetplayer.votes_for_switch = value
					print("test")
					print(value)
					break

class Group(BaseGroup):
	total_contribution = models.CurrencyField()
	individual_share = models.CurrencyField()
	team_size = models.IntegerField()

	def attempted(self):
		players = self.get_players()
		attempted = []
		for player in players:
			if player.desired_team == 2:
				attempted.append(player)
		return attempted

	def get_joined_team(self):
		players = self.subsession.get_players()
		joined = []
		for player in players:
			if player.switch_honored == True and player.team != self.id_in_subsession:
				joined.append(player)
		return joined

	def get_left_team(self):
		players = self.subsession.get_players()
		left = []
		for player in players:
			if player.switch_honored == True and player.team == self.id_in_subsession:
				left.append(player)
		return left

	def get_other_sdp(self):
		players = self.subsession.get_players()
		otherPlayers = []
		for player in players:
			if self.id_in_subsession != player.team and player.desired_team == 2:
				otherPlayers.append(player)
		return otherPlayers

	def get_other_sdp_size(self):
		other = self.get_other_sdp()
		return len(other)

	def get_switch_desired_players(self):
		players = self.get_players()
		switchers = []
		for p in players:
			if (p.desired_team == 2):
				switchers.append(p)
		return switchers

	def get_sorted_switch_players(self): #call this after voting
		players = self.get_switch_desired_players()
		players_ordered = [] #lowest votes: idx = 0, highest votes: idx = len(players_ordered)-1
		for p in players:
			idx = 0
			inserted = False
			while (idx < len(players_ordered)):
				if (p.votes_for_switch >= players_ordered[idx].votes_for_switch):
					idx += 1
				else:
					players_ordered.insert(idx, p)
					inserted = True
					break
			if not inserted:
				players_ordered.append(p)
		return players_ordered

	def get_multiplier_value(self):
		return Constants.multiplier[self.team_size-1]

	def get_total_contribution_with_multiplier(self):
		return self.total_contribution * self.get_multiplier_value()

	pass
