PROJECT_PATH = '/home/md/Work/ligalytics/leagues_stable/'
import os, sys
sys.path.insert(0, PROJECT_PATH)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "leagues.settings")

from leagues import settings
settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3'

import django
django.setup()

from scheduler.models import *
from common.functions import distanceInKmByGPS
import pandas as pd
import numpy as np
from django.db.models import Count, F, Value


thisScenario = Scenario.objects.get(id = 2)
thisSeason = thisScenario.season
thisLeague = thisSeason.league


mathModelName=thisLeague.name
if thisSeason.optimizationParameters!="":
    mathModelName=thisSeason.optimizationParameters



otherScenGames=[]
if thisSeason.improvementObjective!="--":
    for otherScenario in Scenario.objects.filter(season=thisSeason):
        impObjWeight = 5
        if thisSeason.improvementObjective=="stick to old solutions":
            impObjWeight = -5
        if otherScenario.solutionlist() != [['']]:
            for g in otherScenario.solutionlist():                
                otherScenGames.append((int(g[1]),int(g[2]),int(g[3]), impObjWeight ))

getGlobalCountry={ gc['uefa']: gc['id']  for gc in GlobalCountry.objects.values() }

teamObjects = Team.objects.filter(season=thisSeason,active=True).order_by('position').values()
teams=[]
realteams=[]
faketeams=[]
importantteams=[]
shortteams=[]
t_pos={}
t_pot={}
t_color={}
t_country={}
t_globalCountry={}
t_stadium = {}
t_shortname = {}
t_usePhases = {}
t_lon = {}
t_lat = {}
t_attractivity ={}
getTeamById={}
getTeamIdByName={}
getTeamIdByShortName={}
getTeamByName={}
getStadiumById={}
teamByShort={}
top4 = []
for t in teamObjects:
    # print (t['name'],  t['id'])
    teams.append(t['id'])
    shortteams.append(t['shortname'])
    teamByShort[t['shortname']]= t['name']
    getTeamIdByShortName[t['shortname']]=t['id']
    if t['name']!='-':
        realteams.append(t['id'])
    else:
        faketeams.append(t['id'])
    if t['very_important']:
        importantteams.append(t['id'])
    t_country[t['id']]= t['country']
    t_globalCountry[t['id']]= t['globalCountry_id']
    if not t_globalCountry[t['id']] and t_country[t['id']] in getGlobalCountry.keys()  :
        t_globalCountry[t['id']] = getGlobalCountry[t_country[t['id']]]
    t_pos[t['name']]= t['position']
    t_color[t['name']]="lightyellow"
    t_pot[t['id']]= t['pot']
    t_stadium[t['id']]=t['stadium']
    t_attractivity[t['id']]=t['attractivity']
    t_lon[t['id']]=t['longitude']
    t_lat[t['id']]=t['latitude']
    t_shortname[t['id']]=t['shortname']
    t_usePhases[t['id']]= thisScenario.usePhases
    getTeamById[t['id']]=t['name']
    getStadiumById[t['id']]=t['stadium']
    getTeamIdByName[t['name']]=t['id']
    getTeamByName[t['name']]=t
    if t['attractivity'] >= thisSeason.topTeamMinCoefficient :
        top4.append(t['id'])

inactive_teams=[]
for t in  Team.objects.filter(season=thisSeason,active=False).order_by('position').values():
    inactive_teams.append(t['id'])
    t_attractivity[t['id']]=t['attractivity']
    t_lon[t['id']]=t['longitude']
    t_lat[t['id']]=t['latitude']
    t_country[t['id']]= t['country']
    getTeamById[t['id']]=t['name']


lowerBoundFound = False
distance ={}
attractivity ={}
distanceById={}
distanceInDaysById={}
stadium_names = set([t['stadium'] for t in teamObjects if t['stadium']!=''])
stadium_id={}
stadium_name={}
sid=0
for stadium in stadium_names :
    stadium_name[sid]=stadium
    stadium_id[stadium]=sid
    sid+=1
stadiums = list(stadium_name.keys())
teamsOfStadium ={ st:[] for st in stadiums }

travelDict= thisSeason.travelDict()
for t1 in teamObjects:
    if t1['stadium']!='':
        teamsOfStadium[stadium_id[t1['stadium']]].append(t1['id'])
    for t2 in teamObjects:
        # distance[t1['name'],t2['name']] = distanceInKm(t1,t2)
        # print (t1['name'],t2['name'],distance[t1['name'],t2['name']] ," -> ", travelDict[t1['id']][t2['id']]['distance'] )
        distance[t1['name'],t2['name']] = travelDict[t1['id']][t2['id']]['distance'] 
        distanceById[t1['id'],t2['id']] = distance[t1['name'],t2['name']]
        distanceInDaysById[t1['id'],t2['id']] = int(distance[t1['name'],t2['name']]/350 +0.99)
        attractivity[t1['id'],t2['id']] = int(100*t1['attractivity']*t2['attractivity'])


dayObjects = Day.objects.filter(season=thisSeason).values()
days = [ d['id'] for d in dayObjects if d['round']>0 ]

higherSeasons = thisSeason.higherSeasons()
higherGames = thisSeason.higherGames()

this_season_team_names = list(getTeamByName.keys())

higherTeamObjects = Team.objects.filter(season__in=higherSeasons,active=True).values()
higherDayObjects = Day.objects.filter(season__in=higherSeasons,maxGames__gte=1).values()
higherTeams = [ t['id'] for t in higherTeamObjects] 
higherTeamsOf={ t: [] for t in teams}
for t in higherTeamObjects:
    getTeamById[t['id']]=t['name']
    t_country[t['id']]=t['country']
    if t['name'] in this_season_team_names:
        higherTeamsOf[getTeamIdByName[t['name']]].append(t['id'])

print ("Teams : " , teams)
print ("VIP Teams : " , importantteams)
print ("TOP Teams : " , top4)

allConferences = Conference.objects.filter(scenario=s2)
sharedStadiums = False
for ff in  thisSeason.federationmember.all():
    sharedStadiums= ff.federation.sharedStadiums

# print ("\nGroups : ")
t_conference = {t : 0 for t in teams }
conf_teams={}
for c in Conference.objects.filter(scenario=s2,regional=False).order_by('name'):
    # print ("A" , c)
    cteams = c.teams.filter(active=True)
    conf_teams[c.name]=[]
    for t in cteams:
        conf_teams[c.name].append(t.id)
        # print ("group for ", t)
        # if t_conference[t.id]!=0:
            # print (getTeamById[t.id] , " in several groups")
        if t_conference[t.id]==0 or len(cteams)< len(t_conference[t.id].teams.filter(active=True)):
            t_conference[t.id]=c
            # print  (" is " , c )
# for t in set([t for t in teams if t_conference[t]==0 ]):
    # print (" no group " ,  getTeamById[ t])
# return ''

prioVal ={'A': 25 , 'B': 5 , 'C': 1, 'Hard' : 1000}

sw_prio = {}
sw_float1 = {}
sw_float2 = {}
sw_int1 = {}
sw_int2 = {}
sw_text = {}
for sw in SpecialWish.objects.filter(scenario=s2):
    sw_prio[sw.name]=prioVal[sw.prio] if sw.active else 0
    sw_float1[sw.name]=sw.float1
    sw_float2[sw.name]=sw.float2
    sw_int1[sw.name]=sw.int1
    sw_int2[sw.name]=sw.int2
    sw_text[sw.name]=sw.text
special_wishes=list(sw_prio.keys())
special_wishes_active = [ sw for sw in special_wishes if sw_prio[sw]>0 ]

print (special_wishes_active)

noBreakLimitTeams = []
if "allowManyBreaksInRow" in special_wishes_active :
    noBreakLimitTeams = sw_text["allowManyBreaksInRow"].split(",")
    print (noBreakLimitTeams)
    noBreakLimitTeams = [t for t in teams if getTeamById[t] in noBreakLimitTeams]
    print (noBreakLimitTeams)                

pairings_tmp = Pairing.objects.filter(scenario=s2, active=True).values()
pairings_tmp2 = Pairing.objects.filter(scenario__is_published=True, team1__id__in=teams, team2__id__in=higherTeams, active=True).values()
pairings_tmp3 = Pairing.objects.filter(scenario__is_published=True, team2__id__in=teams, team1__id__in=higherTeams, active=True).values()
pairings = []
for p in  [ p for p in pairings_tmp if p['team1_id'] in teams and p['team2_id'] in teams+higherTeams ] + [ p for p in pairings_tmp2 ] + [ p for p in pairings_tmp3]:
    if p not in pairings:
        pairings.append(p) 
breaks = Break.objects.filter(season=thisSeason).values()
blockings_tmp = Blocking.objects.filter(scenario=s2,active=True).values()
blockings = [ bl for bl in blockings_tmp if  bl['team_id'] in teams ]

# times = ['Early', 'Late']
timeObjects = TimeSlot.objects.filter(season=thisSeason).values()
times = [ str(t['id']) for t in timeObjects]
getTimeById = {str(t['id']):t['name'] for t in timeObjects}
getIdByTime = {t['name']:str(t['id']) for t in timeObjects}

blocked_arena = {(t,d, tm) : False for t in teams for d in days for tm in ["----"] + times  }
hidden_arena = {(t,d, tm) : False for t in teams for d in days for tm in ["----"] + times  }
nBlockingHome=0
nBlockingAway=0

for bl in blockings:
    if bl['type'] in ["Hide"]:
        hidden_arena[(bl['team_id'],bl['day_id'], bl['time'] )]=True

    if bl['type'] in ["Home","Hide"]:
        nBlockingHome+=1
        blocked_arena[(bl['team_id'],bl['day_id'], bl['time'] )]=True
    else:
        nBlockingAway+=1

nTeams=len(teams)
nPhases =thisSeason.numPhases
groupView = thisSeason.groupBased

gameCntr={(t1,t2) : 0 for t1 in teams for t2 in teams}
undirectedGameCntr={(t1,t2) : 0 for t1 in teams for t2 in teams}

if thisSeason.useFeatureOpponentMatrix:
    gameRequirements = GameRequirement.objects.filter(season=thisSeason, team1__active=True, team2__active=True) 
    # print (len(gameRequirements))
    for gm in gameRequirements:
        if thisSeason.undirectedGames:
            undirectedGameCntr[(gm.team1.id,gm.team2.id)]+=gm.number
            undirectedGameCntr[(gm.team2.id,gm.team1.id)]+=gm.number
            # print ( "found undirected  game " , (gm.team1.id,gm.team2.id) , gm.number )
        else:
            gameCntr[(gm.team1.id,gm.team2.id)]+=gm.number
            # print ( "found directed  game " , (gm.team1.id,gm.team2.id) , gm.number )
else:
    for t1 in teams:
        for t2 in teams:
            if t1!=t2:
                gameCntr[(t1,t2)]+=nPhases/2

    for c in Conference.objects.filter(scenario=s2):
        cteams = c.teams.filter(active=True)
        for t1 in cteams:
            for t2 in cteams:
                if t1!=t2:
                    gameCntr[(t1.id,t2.id)]+=c.deltaGames/2

    for (t1,t2) in gameCntr.keys():
        if gameCntr[(t1,t2)]%1!=0 :
            undirectedGameCntr[(t1,t2)]=1
        gameCntr[(t1,t2)] = int(gameCntr[(t1,t2)])

games = [ gm for gm in gameCntr.keys() if gameCntr[gm]+undirectedGameCntr[gm]>0]

objectiveFunctionWeights = ObjectiveFunctionWeight.objects.filter(scenario=s2).values()

gew={}
gew['Trips'] = 5
gew['Derbies'] = 5
gew['Pairings'] = 5
for ow in objectiveFunctionWeights:
    gew[ow['name']]= ow['use'] * ow['prio']

objectivePrio = 'Breaks'
if  gew['Trips']>gew['Breaks'] :
    objectivePrio = 'Trips'

print("objectivePrio:", objectivePrio)

specialGameControl= mathModelName in ["Florida State League"]

if len(games)==0:
    games = [ (t1,t2) for t1 in teams for t2 in teams if t1!=t2 ]
    specialGameControl=True
    
realgames= [(t1,t2) for (t1,t2) in games if getTeamById[t1]!="-" and getTeamById[t2]!="-"]

# nur wenn die solutionlist alle spiele enthält, wird dieser modus aktiviert
evalRun = ( runMode == "Improve" and localsearch_time==0 
            and len(thisScenario.solutionlist())==sum([gameCntr[gm]+0.5*undirectedGameCntr[gm] for gm in realgames]) )

opponents = { t: set([]) for t in realteams}

for (t1,t2) in games:
    if t1 in realteams and t2 in realteams:
        opponents[t1].add(t2)
        opponents[t2].add(t1)