from __future__ import print_function
from django.http import HttpResponse
from django.shortcuts import render
import urllib, urllib2, unicodedata, sys, json
from bs4 import BeautifulSoup
import datetime as dt
from django.db.models import Q
from futstats.models import *
from django.core.files import File
from django.template.response import TemplateResponse
from django.core.files.temp import NamedTemporaryFile
from django.conf import settings
from django.core.management import call_command
from django.db import transaction
from django.db.models import Avg
import numpy as np
import matplotlib.pyplot as plt
from sklearn.feature_selection import SelectKBest
from sklearn import svm, grid_search, preprocessing
from sklearn import cross_validation
from sklearn.cross_validation import KFold
from django.db.models import Sum
from sklearn.feature_selection import RFECV
from sklearn.cross_validation import train_test_split
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.svm import SVC
import multiprocessing as mp
import time

def sendMail(date):
    import smtplib
    from email.mime.text import MIMEText
    fromaddr = '61726e61752e666f72617374657240676d61696c2e636f6d'.decode('hex')
    toaddrs = '61726e61752e666f72617374657240676d61696c2e636f6d'.decode('hex')
    content = 'Run finish. '+str(date)
    msg = MIMEText(content)
    msg['From'] = fromaddr
    msg['To'] = toaddrs
    msg['Subject'] = 'Test finished :)'
    username = '61726e61752e666f72617374657240676d61696c2e636f6d'.decode('hex')
    password = '726c666d626b72636b7a7a776575726a'.decode('hex')
    server = smtplib.SMTP('smtp.gmail.com:587')
    server.starttls()
    server.login(username,password)
    server.sendmail(fromaddr, toaddrs, msg.as_string())
    server.quit()    

def posLiga(temporada, jornada, local, visitante, liga):
    l=-1
    v=-1
    orden = Stats.objects.filter(liga=liga, temporada=temporada, jornada=jornada).order_by('-puntos','-goles_favor')
    for index, item in enumerate(orden):
        if item.equipo.nombre==local:
            l=index
        elif item.equipo.nombre==visitante:
            v=index
    return l+1,v+1

def getDataToPredict(m, local , visitante):
    l = []
    s = Stats.objects.filter(liga=m.liga, temporada=m.temporada, jornada=m.jornada-1, equipo=m.local).first()
    s2 = Stats.objects.filter(liga=m.liga, temporada=m.temporada, jornada=m.jornada-1, equipo=m.visitante).first()
    p1, p2 = posLiga(m.temporada, m.jornada-1, m.local, m.visitante, m.liga)
    puntos1, puntos2 = getDifferencePoints(m.liga, m.temporada, m.jornada-1, m.local, m.visitante, 3)
    posLocal = accInTime(m.liga, m.temporada, m.jornada-1, m.local, 3)
    posVisitante = accInTime(m.liga, m.temporada, m.jornada-1, m.visitante, 3)
    if s and s2:
        l.append([p1-p2,puntos1-puntos2, puntos1, puntos2, posLocal-posVisitante,posLocal, posVisitante, s.goles, s.tarjetas_amarillas, s.tarjetas_rojas, s.faltas_recibidas, s.faltas_cometidas, s.balones_perdidos, s.balones_recuperados, s.fuera_juego, s.penalties, s.intervenciones_portero, s.posesion, s.remates, s.puntos, s.goles_favor, s.goles_contra, s2.goles,s2.tarjetas_amarillas, s2.tarjetas_rojas, s2.faltas_recibidas, s2.faltas_cometidas, s2.balones_perdidos, s2.balones_recuperados, s2.fuera_juego, s2.penalties, s2.intervenciones_portero, s2.posesion, s2.remates,s2.puntos,s2.goles_favor,s2.goles_contra, s.goles-s2.goles, s.balones_perdidos-s2.balones_perdidos, s.balones_recuperados-s2.balones_recuperados, s.fuera_juego-s2.fuera_juego, s.posesion-s2.posesion, s.remates-s2.remates,p1,p2, s.faltas_recibidas-s2.faltas_cometidas, s2.faltas_recibidas-s.faltas_cometidas])
    return np.array(l)

def predictMatch2(partido, tp, moral, camp):
    t0 = time.time()
    X, y, scaler = statsRevMix(tp,2, partido.local,partido.local, partido)
    cols = []
    X_new, cols = auto(X, y, 5, cols)
    e = findParameters(X_new, y, 0)
    Xp = getDataToPredict(partido, partido.local, partido.visitante)
    Xps = scaler.transform(Xp) 
    for column in cols:
        Xps = delColumn(Xps,column)
    results = e.predict_proba(Xps)[0]
    prob_per_class_dictionary1 = dict(zip(e.classes_, results))
    if moral < 0:
        prob_per_class_dictionary1['local'] = prob_per_class_dictionary1['local']+abs(moral)
    elif moral > 0:
        prob_per_class_dictionary1['visitante'] = prob_per_class_dictionary1['visitante']+abs(moral)
    if camp < 0:
        prob_per_class_dictionary1['local'] = prob_per_class_dictionary1['local']+abs(camp)
    elif camp > 0:
        prob_per_class_dictionary1['visitante'] = prob_per_class_dictionary1['visitante']+abs(camp)
    r1 = max(prob_per_class_dictionary1, key=prob_per_class_dictionary1.get)
    prob1 = prob_per_class_dictionary1[r1]
    rloc = e.predict(Xps)[0]
    X, y, scaler = statsRevMix(tp,2, partido.visitante, partido.visitante, partido)
    cols = []
    X_new, cols = auto(X, y, 5, cols)
    e = findParameters(X_new, y, 0)
    Xp = getDataToPredict(partido, partido.local, partido.visitante)
    Xps = scaler.transform(Xp)
    for column in cols:
        Xps = delColumn(Xps,column)
    results = e.predict_proba(Xps)[0]
    rvis = e.predict(Xps)[0]
    prob_per_class_dictionary = dict(zip(e.classes_, results))
    if moral < 0:
        prob_per_class_dictionary1['local'] = prob_per_class_dictionary1['local']+abs(moral)
    elif moral > 0:
        prob_per_class_dictionary1['visitante'] = prob_per_class_dictionary1['visitante']+abs(moral)
    if camp < 0:
        prob_per_class_dictionary1['local'] = prob_per_class_dictionary1['local']+abs(camp)
    elif camp > 0:
        prob_per_class_dictionary1['visitante'] = prob_per_class_dictionary1['visitante']+abs(camp)
    r2 = max(prob_per_class_dictionary, key=prob_per_class_dictionary.get)
    prob2 = prob_per_class_dictionary[r2]
    if prob2 > prob1:
        asd = r2
        return asd, prob2*100.0
    else:
        asd = r1
        return asd, prob1*100.0


def predictMatch(request):
    if request.method == 'POST':
        data = request.POST
        visitante = data['visitante']
        local = data['local']
        camp = data['camp']
        moral = data['moral']
        years = request.POST.getlist(u'checkboxes[]')
        moral = (((float(moral) - (-100.0)) * (5.0 - (-5.0))) / (100.0 - (-100-0))) + (-5.0)
        camp = (((float(camp) - (-100.0)) * (5.0 - (-5.0))) / (100.0 - (-100-0))) + (-5.0)
        partido = Partido.objects.filter(local__nombre=local, visitante__nombre=visitante).first()
        response_data = {}
        response_data['local'] =  local
        response_data['visitant'] =  visitante
        try:
            result, prob = predictMatch2(partido, years, moral, camp)
            response_data['result'] = 'ok'
            response_data['prob'] =  prob
            response_data['message'] = result
        except:
            response_data['result'] = 'failed'
            response_data['message'] = "No s'ha pogut fer la prediccio..."
    return HttpResponse(json.dumps(response_data), content_type="application/json")

def predict():
    d = dt.datetime.now()
    jornada = Partido.objects.filter(liga=1, temporada=14, fecha__gt=d).order_by('fecha').first().jornada
    for partido in Partido.objects.filter(liga=1, jornada=jornada,temporada=14):
        if not Pronostico.objects.filter(partido__liga=1, partido=partido):
            t0 = time.time()
            cols = []
            try:
                a = [i for i in range(10, 15)]
                X, y, scaler = statsRevMix(a,2, partido.local,partido.local, partido)#statsRevLocal(10, 2, partido.local, partido)
                X_new, cols = auto(X, y, 5, cols)
            except:
                a = [i for i in range(0, 15)]
                X, y, scaler = statsRevMix(a,2, partido.local,partido.local, partido)#statsRevLocal(10, 2, partido.local, partido)
                X_new, cols = auto(X, y, 5, cols)
            e = findParameters(X_new, y, 0)
            Xp = getDataToPredict(partido, partido.local, partido.visitante)
            Xps = scaler.transform(Xp) 
            for column in cols:
                Xps = delColumn(Xps,column)
            results = e.predict_proba(Xps)[0]
            prob_per_class_dictionary = dict(zip(e.classes_, results))
            r1 = max(prob_per_class_dictionary, key=prob_per_class_dictionary.get)
            prob1 = prob_per_class_dictionary[r1]
            cols = []
            try:
                a = [i for i in range(10, 15)]
                X, y, scaler = statsRevMix(a,2, partido.visitante,partido.visitante, partido)
                X_new, cols = auto(X, y, 5, cols)
            except:
                a = [i for i in range(0, 15)]
                X, y, scaler = statsRevMix(0,2, partido.visitante,partido.visitante, partido)
                X_new, cols = auto(X, y, 5, cols)
            e = findParameters(X_new, y, 0)
            Xp = getDataToPredict(partido, partido.local, partido.visitante)
            Xps = scaler.transform(Xp)
            for column in cols:
                Xps = delColumn(Xps,column)
            results = e.predict_proba(Xps)[0]
            prob_per_class_dictionary = dict(zip(e.classes_, results))
            r2 = max(prob_per_class_dictionary, key=prob_per_class_dictionary.get)
            prob2 = prob_per_class_dictionary[r2]
            p = Pronostico()
            p.partido = partido
            if prob2 > prob1:
                p.ganador = r2
                p.prob = prob2*100.0
            else:
                p.ganador = r1
                p.prob = prob1*100.0
            p.save()

def statsRevMix(temporada, jornada, local, visitante, partido):
    if jornada < 2: jornada=2
    l = []
    t = []
    for m in Partido.objects.exclude(id=partido.id).filter(liga=1, temporada__in=temporada, jornada__gte=jornada, visitante__nombre=visitante.nombre, jugado=True):
        s = Stats.objects.filter(liga=m.liga, temporada=m.temporada, jornada=m.jornada-1, equipo=m.local).first()
        s2 = Stats.objects.filter(liga=m.liga, temporada=m.temporada, jornada=m.jornada-1, equipo=m.visitante).first()
        p1, p2 = posLiga(m.temporada, m.jornada-1, m.local, m.visitante, m.liga)
        puntos1, puntos2 = getDifferencePoints(m.liga, m.temporada, m.jornada-1, m.local, m.visitante, 3)
        posLocal = accInTime(m.liga, m.temporada, m.jornada-1, m.local, 3)
        posVisitante = accInTime(m.liga, m.temporada, m.jornada-1, m.visitante, 3)
        if s and s2:
            l.append([p1-p2,puntos1-puntos2, puntos1, puntos2, posLocal-posVisitante,posLocal, posVisitante, s.goles, s.tarjetas_amarillas, s.tarjetas_rojas, s.faltas_recibidas, s.faltas_cometidas, s.balones_perdidos, s.balones_recuperados, s.fuera_juego, s.penalties, s.intervenciones_portero, s.posesion, s.remates, s.puntos, s.goles_favor, s.goles_contra, s2.goles,s2.tarjetas_amarillas, s2.tarjetas_rojas, s2.faltas_recibidas, s2.faltas_cometidas, s2.balones_perdidos, s2.balones_recuperados, s2.fuera_juego, s2.penalties, s2.intervenciones_portero, s2.posesion, s2.remates,s2.puntos,s2.goles_favor,s2.goles_contra, s.goles-s2.goles, s.balones_perdidos-s2.balones_perdidos, s.balones_recuperados-s2.balones_recuperados, s.fuera_juego-s2.fuera_juego, s.posesion-s2.posesion, s.remates-s2.remates,p1,p2, s.faltas_recibidas-s2.faltas_cometidas, s2.faltas_recibidas-s.faltas_cometidas])
            if m.ganador == '1': t.append('local')
            elif m.ganador == '2': t.append('visitante')
            else: t.append('empate')  
    for m in Partido.objects.exclude(id=partido.id).filter(liga=1, temporada__in=temporada, jornada__gte=jornada, local__nombre=local.nombre, jugado=True):
        s = Stats.objects.filter(liga=m.liga, temporada=m.temporada, jornada=m.jornada-1, equipo=m.local).first()
        s2 = Stats.objects.filter(liga=m.liga, temporada=m.temporada, jornada=m.jornada-1, equipo=m.visitante).first()
        p1, p2 = posLiga(m.temporada, m.jornada-1, m.local, m.visitante, m.liga)
        puntos1, puntos2 = getDifferencePoints(m.liga, m.temporada, m.jornada-1, m.local, m.visitante, 3)
        posLocal = accInTime(m.liga, m.temporada, m.jornada-1, m.local, 3)
        posVisitante = accInTime(m.liga, m.temporada, m.jornada-1, m.visitante, 3)
        if s and s2:
            l.append([p1-p2,puntos1-puntos2, puntos1, puntos2, posLocal-posVisitante,posLocal, posVisitante, s.goles, s.tarjetas_amarillas, s.tarjetas_rojas, s.faltas_recibidas, s.faltas_cometidas, s.balones_perdidos, s.balones_recuperados, s.fuera_juego, s.penalties, s.intervenciones_portero, s.posesion, s.remates, s.puntos, s.goles_favor, s.goles_contra, s2.goles,s2.tarjetas_amarillas, s2.tarjetas_rojas, s2.faltas_recibidas, s2.faltas_cometidas, s2.balones_perdidos, s2.balones_recuperados, s2.fuera_juego, s2.penalties, s2.intervenciones_portero, s2.posesion, s2.remates,s2.puntos,s2.goles_favor,s2.goles_contra, s.goles-s2.goles, s.balones_perdidos-s2.balones_perdidos, s.balones_recuperados-s2.balones_recuperados, s.fuera_juego-s2.fuera_juego, s.posesion-s2.posesion, s.remates-s2.remates,p1,p2, s.faltas_recibidas-s2.faltas_cometidas, s2.faltas_recibidas-s.faltas_cometidas])
            if m.ganador == '1': t.append('local')
            elif m.ganador == '2': t.append('visitante')
            else: t.append('empate')
    X = np.array(l)
    scaler = preprocessing.MinMaxScaler(feature_range=(-1, 1)).fit(X)
    return scaler.transform(X), np.array(t), scaler

def statsRevVisitante(temporada, jornada, visitante, partido):
    if jornada < 2: jornada=2
    l = []
    t = []
    for m in Partido.objects.exclude(id=partido.id).filter(liga=1, temporada__gte=temporada, jornada__gte=jornada, visitante__nombre=visitante.nombre, jugado=True):
        s = Stats.objects.filter(liga=m.liga, temporada=m.temporada, jornada=m.jornada-1, equipo=m.local).first()
        s2 = Stats.objects.filter(liga=m.liga, temporada=m.temporada, jornada=m.jornada-1, equipo=m.visitante).first()
        p1, p2 = posLiga(m.temporada, m.jornada-1, m.local, m.visitante, m.liga)
        puntos1, puntos2 = getDifferencePoints(m.liga, m.temporada, m.jornada-1, m.local, m.visitante, 3)
        posLocal = accInTime(m.liga, m.temporada, m.jornada-1, m.local, 3)
        posVisitante = accInTime(m.liga, m.temporada, m.jornada-1, m.visitante, 3)
        if s and s2:
            l.append([p1-p2,puntos1-puntos2, puntos1, puntos2, posLocal-posVisitante,posLocal, posVisitante, s.goles, s.tarjetas_amarillas, s.tarjetas_rojas, s.faltas_recibidas, s.faltas_cometidas, s.balones_perdidos, s.balones_recuperados, s.fuera_juego, s.penalties, s.intervenciones_portero, s.posesion, s.remates, s.puntos, s.goles_favor, s.goles_contra, s2.goles,s2.tarjetas_amarillas, s2.tarjetas_rojas, s2.faltas_recibidas, s2.faltas_cometidas, s2.balones_perdidos, s2.balones_recuperados, s2.fuera_juego, s2.penalties, s2.intervenciones_portero, s2.posesion, s2.remates,s2.puntos,s2.goles_favor,s2.goles_contra, s.goles-s2.goles, s.balones_perdidos-s2.balones_perdidos, s.balones_recuperados-s2.balones_recuperados, s.fuera_juego-s2.fuera_juego, s.posesion-s2.posesion, s.remates-s2.remates,p1,p2, s.faltas_recibidas-s2.faltas_cometidas, s2.faltas_recibidas-s.faltas_cometidas])
            if m.ganador == '1': t.append('local')
            elif m.ganador == '2': t.append('visitante')
            else: t.append('empate')
    X = np.array(l)
    scaler = preprocessing.MinMaxScaler(feature_range=(-1, 1)).fit(X)
    return scaler.transform(X), np.array(t), scaler

def accInTime(liga, temporada, jornada, team, lapse):
    stats_local = Partido.objects.filter(Q(local=team) | Q(visitante=team),liga=liga, temporada=temporada, jornada__range=(jornada-lapse+1,jornada)).order_by('jornada')
    total = 0
    for s in stats_local:
        if s.local == team:
            total += s.posesion_local
        else:
            total += s.posesion_visitante
    if len(stats_local) == 0: return 0
    return round(float(total)/len(stats_local),1)

def getDifferencePoints(liga, temporada, jornada, local, visitante, lapse):
    stats = Stats.objects.filter(liga=liga, temporada=temporada, jornada__range=(jornada-lapse+1,jornada), equipo=local)
    puntos_local=stats.first().puntos-stats.last().puntos
    stats = Stats.objects.filter(liga=liga, temporada=temporada, jornada__range=(jornada-lapse+1,jornada), equipo=visitante)
    puntos_visitante=stats.first().puntos-stats.last().puntos
    return puntos_local, puntos_visitante

def statsRevLocal(temporada, jornada, local, partido):
    if jornada < 2: jornada=2
    l = []
    t = []
    for m in Partido.objects.exclude(id=partido.id).filter(liga=1, temporada__gte=temporada, jornada__gte=jornada, local__nombre=local.nombre, jugado=True):
        s = Stats.objects.filter(liga=m.liga, temporada=m.temporada, jornada=m.jornada-1, equipo=m.local).first()
        s2 = Stats.objects.filter(liga=m.liga, temporada=m.temporada, jornada=m.jornada-1, equipo=m.visitante).first()
        p1, p2 = posLiga(m.temporada, m.jornada-1, m.local, m.visitante, m.liga)
        puntos1, puntos2 = getDifferencePoints(m.liga, m.temporada, m.jornada-1, m.local, m.visitante, 3)
        posLocal = accInTime(m.liga, m.temporada, m.jornada-1, m.local, 3)
        posVisitante = accInTime(m.liga, m.temporada, m.jornada-1, m.visitante, 3)
        if s and s2:
            l.append([p1-p2,puntos1-puntos2, puntos1, puntos2, posLocal-posVisitante,posLocal, posVisitante, s.goles, s.tarjetas_amarillas, s.tarjetas_rojas, s.faltas_recibidas, s.faltas_cometidas, s.balones_perdidos, s.balones_recuperados, s.fuera_juego, s.penalties, s.intervenciones_portero, s.posesion, s.remates, s.puntos, s.goles_favor, s.goles_contra, s2.goles,s2.tarjetas_amarillas, s2.tarjetas_rojas, s2.faltas_recibidas, s2.faltas_cometidas, s2.balones_perdidos, s2.balones_recuperados, s2.fuera_juego, s2.penalties, s2.intervenciones_portero, s2.posesion, s2.remates,s2.puntos,s2.goles_favor,s2.goles_contra, s.goles-s2.goles, s.balones_perdidos-s2.balones_perdidos, s.balones_recuperados-s2.balones_recuperados, s.fuera_juego-s2.fuera_juego, s.posesion-s2.posesion, s.remates-s2.remates,p1,p2, s.faltas_recibidas-s2.faltas_cometidas, s2.faltas_recibidas-s.faltas_cometidas])
            if m.ganador == '1': t.append('local')
            elif m.ganador == '2': t.append('visitante')
            else: t.append('empate')
    X = np.array(l)
    scaler = preprocessing.MinMaxScaler(feature_range=(-1, 1)).fit(X)
    return scaler.transform(X), np.array(t), scaler

def findParameters(X, y, test):
    # Set the parameters by cross-validation
    tuned_parameters = [{'kernel': ['rbf'], 'gamma': [1e-2,1e-3, 1e-4], 'C': [1, 10, 100, 1000]}, {'kernel': ['linear'], 'C': [0.1,1, 10, 100, 1000]}]
    score = 'accuracy'
    X_train, X_test, y_train, y_test = cross_validation.train_test_split(X,y, test_size=test, random_state=0)
    clf = grid_search.GridSearchCV(SVC(C=1,probability=True,class_weight='auto'), tuned_parameters, cv=5, scoring=score)
    clf.fit(X_train, y_train)
    return clf.best_estimator_

def delColumn(arr,col):
    return np.delete(arr,(col), axis=1)

def featureSel(X,y):
    param_grid = [{'C':0.1},{'C': 1},{'C':10}]
    estimator = SVC(kernel='linear',class_weight='auto')
    selector = RFECV(estimator, step=1, cv=3)
    clf = GridSearchCV(selector, {'estimator_params': param_grid}, cv=4)
    clf.fit(X, y)
    return clf.best_estimator_.ranking_, clf.best_estimator_.estimator_, clf.best_estimator_.grid_scores_

def auto(X, y, num, columns):
    a,b,c = featureSel(X, y)
    if max(a) <= num:
        return X, columns
    else:
        l = a.tolist()
        col = l.index(max(a))
        columns.append(col)
        X_new = delColumn(X,col)
        return auto(X_new, y, num, columns)

def balance(X,y):
    import random
    l = y.tolist()
    f = X.tolist()
    m = min(l.count('empate'),l.count('local'),l.count('visitante'))
    while l.count('empate')> m:
        pos = random.randint(0,len(l)-1) 
        if l[pos] == 'empate':
            l.pop(pos)
            f.pop(pos)
    while l.count('local')> m:
        pos = random.randint(0,len(l)-1)
        if l[pos] == 'local':
            l.pop(pos)
            f.pop(pos)
    while l.count('visitante')> m:
        pos = random.randint(0,len(l)-1)
        if l[pos] == 'visitante':
            l.pop(pos)
            f.pop(pos)
    return np.array(f), np.array(l)

def accAverage(liga, equipo,temporada, jornada,opcio):
    num = 0 
    l = Partido.objects.filter(liga=liga, local=equipo, temporada=temporada, jornada__lt=jornada+1).aggregate(Avg(opcio+'_local'))[opcio+'_local__avg']
    if l == None:
        l = 0.0
        num = 1
    v=Partido.objects.filter(liga=liga, visitante=equipo, temporada=temporada, jornada__lt=jornada+1).aggregate(Avg(opcio+'_visitante'))[opcio+'_visitante__avg']
    if v == None:
        v = 0.0    
        num = 1
    if num == 1:
        return round(float(l+v),1)
    return round(float(l+v)/2.0,1)

def accSum(liga, equipo, temporada, jornada, opcio):
    l = Partido.objects.filter(liga=liga, local=equipo, temporada=temporada,jornada__lt=jornada+1).aggregate(Sum(opcio+'_local'))[opcio+'_local__sum']
    if l == None:
        l = 0
    v=Partido.objects.filter(liga=liga, visitante=equipo, temporada=temporada,jornada__lt=jornada+1).aggregate(Sum(opcio+'_visitante'))[opcio+'_visitante__sum']
    if v == None:
        v = 0
    return l+v

def accSumInverse(liga, equipo, temporada, jornada, opcio):
    l = Partido.objects.filter(liga=liga, local=equipo, temporada=temporada,jornada__lt=jornada+1).aggregate(Sum(opcio+'_visitante'))[opcio+'_visitante__sum']
    if l == None:
        l = 0
    v=Partido.objects.filter(liga=liga, visitante=equipo, temporada=temporada,jornada__lt=jornada+1).aggregate(Sum(opcio+'_local'))[opcio+'_local__sum']
    if v == None:
        v = 0
    return l+v

def accPoints(liga, equipo, temporada, jornada):
    ganados = Partido.objects.filter(liga=liga, local=equipo, temporada=temporada,jornada__lt=jornada+1, ganador=1).count()
    ganados += Partido.objects.filter(liga=liga, visitante=equipo, temporada=temporada,jornada__lt=jornada+1, ganador=2).count()
    perdidos = Partido.objects.filter(liga=liga, local=equipo, temporada=temporada,jornada__lt=jornada+1, ganador=2).count()
    perdidos += Partido.objects.filter(liga=liga, visitante=equipo, temporada=temporada,jornada__lt=jornada+1, ganador=1).count()
    empatados = Partido.objects.filter(liga=liga, local=equipo, temporada=temporada,jornada__lt=jornada+1, ganador='X').count()
    empatados += Partido.objects.filter(liga=liga, visitante=equipo, temporada=temporada,jornada__lt=jornada+1, ganador='X').count()
    return (ganados*3+empatados), ganados, perdidos, empatados

def createStats(temporada, jornada, equipo, partido, liga):
    s = Stats.objects.filter(liga=liga, temporada=temporada, jornada=jornada, equipo=equipo)
    if not s:
        s = Stats()
        s.temporada = temporada
        s.jornada = jornada
        s.liga = liga
    else: s = s.first()
    s.equipo = equipo
    s.goles_favor = accSum(liga, equipo, temporada, jornada, 'goles')  
    s.goles_contra = accSumInverse(liga, equipo, temporada, jornada, 'goles')
    s.puntos, s.ganados, s.perdidos, s.empatados = accPoints(liga, equipo, temporada, jornada) 
    s.goles = accAverage(liga, equipo,temporada, jornada, 'goles')
    s.tarjetas_amarillas = accAverage(liga, equipo,temporada, jornada, 'tarjetas_amarillas')
    s.tarjetas_rojas = accAverage(liga, equipo,temporada, jornada, 'tarjetas_rojas') 
    s.faltas_recibidas = accAverage(liga, equipo,temporada, jornada, 'faltas_recibidas')
    s.faltas_cometidas = accAverage(liga, equipo,temporada, jornada, 'faltas_cometidas')
    s.balones_perdidos = accAverage(liga, equipo,temporada, jornada, 'balones_perdidos')
    s.balones_recuperados = accAverage(liga, equipo,temporada, jornada, 'balones_recuperados')
    s.fuera_juego = accAverage(liga, equipo,temporada, jornada, 'fuera_juego')
    s.penalties = accAverage(liga, equipo,temporada, jornada, 'penalties')
    s.intervenciones_portero = accAverage(liga, equipo,temporada, jornada, 'intervenciones_portero')
    s.posesion = accAverage(liga, equipo,temporada, jornada, 'posesion')
    s.remates = accAverage(liga, equipo,temporada, jornada, 'remates')
    s.save()
    
def buildStats(t, liga):
    Stats.objects.filter(liga=liga, temporada=t).delete()
    lon = Partido.objects.filter(liga=liga).order_by("jornada").last().jornada+1
    for i in range(1,lon):
        for m in Partido.objects.filter(liga=liga, temporada=t,jornada=i):
            createStats(t, i, m.local, m, liga)
            createStats(t, i, m.visitante, m, liga)

def get_media(team, option):
    l=Partido.objects.filter(local=team,jugado=True).aggregate(Avg(option+'_local')).values()[0]
    v=Partido.objects.filter(visitante=team,jugado=True).aggregate(Avg(option+'_visitante')).values()[0]
    return round(l,2),round(v,2)

def team(request, num):
    d = {}
    t = Equipo.objects.get(id=num)
    g_local,g_visitante=get_media(t, 'goles')
    d['g_local'] = g_local
    d['g_visitante'] = g_visitante
    p_local,p_visitante=get_media(t, 'posesion')
    d['p_local'] = p_local
    d['p_visitante'] = p_visitante
    pen_local,pen_visitante=get_media(t, 'penalties')
    d['pen_local'] = pen_local
    d['pen_visitante'] = pen_visitante
    rem_local,rem_visitante=get_media(t, 'remates')
    d['rem_local'] = rem_local
    d['rem_visitante'] = rem_visitante
    ta_local,ta_visitante=get_media(t, 'tarjetas_amarillas')
    d['ta_local'] = ta_local
    d['ta_visitante'] = ta_visitante
    tr_local,tr_visitante=get_media(t, 'tarjetas_rojas')
    d['tr_local'] = tr_local
    d['tr_visitante'] = tr_visitante
    fc_local,fc_visitante=get_media(t, 'faltas_cometidas')
    d['fc_local'] = fc_local
    d['fc_visitante'] = fc_visitante
    fr_local,fr_visitante=get_media(t, 'faltas_recibidas')
    d['fr_local'] = fr_local
    d['fr_visitante'] = fr_visitante
    
    m = Partido.objects.filter(Q(local=t) | Q(visitante=t),jugado=True).order_by('-fecha')[:5]
    partidos = [[e.local.nombre,e.visitante.nombre,e.goles_local,e.goles_visitante] for e in Partido.objects.filter(Q(local=t) | Q(visitante=t),jugado=True, temporada=14).order_by('-fecha')[:5]]
    context = {'team':[t.id,t.nombre,t.escudo],'partidos':partidos}
    return TemplateResponse(request, 'futstats/team.html',dict(context, **d))

def index(request):
    d = dt.datetime.now()-dt.timedelta(days=1)
    jornada = Partido.objects.filter(liga=1, temporada=14, fecha__gt=d).order_by('fecha').first().jornada 
    l = [[p.partido.local.id,p.partido.local.escudo.url,str(p.partido.local.nombre),p.partido.visitante.id,p.partido.visitante.escudo.url, str(p.partido.visitante.nombre), str(p.ganador)]for p in Pronostico.objects.filter(partido__liga=1, partido__jornada=jornada,partido__temporada=14)]
    context = {'equipos':l,'jornada':jornada}
    return TemplateResponse(request, 'futstats/index.html', context)

def checkWrongBad(temporada, jornada):
    bien = 0
    mal = 0
    fecha = 0.0
    if temporada==0:
        for p in Pronostico.objects.filter(partido__jugado=True):
            if p.partido.ganador == '1' and p.ganador == 'local':
                bien += 1
            elif p.partido.ganador == '2' and p.ganador == 'visitante':
                bien += 1
            elif p.partido.ganador == 'X' and p.ganador == 'empate':
                bien += 1
            else:
                mal += 1
        return bien, mal
    for p in Pronostico.objects.filter(partido__temporada=temporada, partido__jornada=jornada, partido__jugado=True):
        fecha = time.mktime(p.partido.fecha.timetuple()) * 1000
        if p.partido.ganador == '1' and p.ganador == 'local':
            bien += 1
        elif p.partido.ganador == '2' and p.ganador == 'visitante':
            bien += 1
        elif p.partido.ganador == 'X' and p.ganador == 'empate':
            bien += 1
        else:
            mal += 1
    if bien+mal == 0: return 0,0,0,0
    return fecha, bien, mal, round((float(bien)/(bien+mal))*100.0, 2)

def accAvg(data, jornada):
    r = []
    e = 1
    while e <= len(data):
        r.append([jornada,round(sum(data[:e])/len(data[:e]), 2)])
        e += 1
        jornada += 1
    return r
        
def pronosticosData(temporada):
    l = []
    avg = []
    ini = Pronostico.objects.filter(partido__jugado=True).order_by('partido__jornada').first().partido.jornada
    fin = Pronostico.objects.filter(partido__jugado=True).order_by('partido__jornada').last().partido.jornada+1
    for j in xrange(ini,fin):
        f,b,m,p = checkWrongBad(temporada, j)
        l.append([j, p])
        avg.append(p)
    return l, accAvg(avg, 10)

def dataClasses():
    local = Pronostico.objects.filter(partido__ganador=1, ganador='local').count()
    local_total = Pronostico.objects.filter(ganador='local').count()
    visitante = Pronostico.objects.filter(partido__ganador=2, ganador='visitante').count()
    visitante_total = Pronostico.objects.filter(ganador='visitante').count()
    empate = Pronostico.objects.filter(partido__ganador='X', ganador='empate').count()
    empate_total = Pronostico.objects.filter(ganador='empate').count()
    return [[0,local],[1,visitante],[2,empate]], [[0,local_total],[1,visitante_total],[2,empate_total]],[[0,'local'],[1,'visitante'],[2,'empate']]
    
def panel(request):
    d = dt.datetime.now()
    jornada = Partido.objects.filter(temporada=14, fecha__gt=d).order_by('fecha').first().jornada
    data, avg = pronosticosData(14)
    hit, total,labels = dataClasses()
    teams = [str(e) for e in Partido.objects.filter(liga=1, temporada=14).values_list('local__nombre',flat=True).distinct().order_by('local__nombre')]
    context = {'data':data, 'avg':avg, 'hit':hit, 'total':total, 'labels':labels, 'teams':teams}
    return TemplateResponse(request, 'futstats/panel.html', context)

def chunks(l, n):
    """ Yield successive n-sized chunks from l.
    """
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

def get_data(request):
    call_command('download_match')    
    return TemplateResponse(request, 'futstats/index.html',{'result': 'OK'})

def team_shield(soup, className):
    return soup.find('div', {'class' : className}).find('img', {'class' : 's-inb-sm'}).get('data-src')
 
def team_name(soup, className):
    if soup.find('div', {'class' : className}).find('a', {'class' : 'drt-team-name'}):
        return unicodedata.normalize('NFKD',soup.find('div', {'class' : className}).find('a', {'class' : 'drt-team-name'}).text).encode('ascii','ignore').rstrip().lstrip()    
    else:
        return unicodedata.normalize('NFKD',soup.find('div', {'class' : className}).find('p', {'class' : 'drt-team-name'}).text).encode('ascii','ignore').rstrip().lstrip()    

def process(soup, temporada, liga):
    local = team_name(soup,'drt-team s-left')
    if Equipo.objects.get(nombre=local).escudo.name == '':
        escudo_equipo_local = team_shield(soup,'drt-team s-left')
        saveShield(local, escudo_equipo_local)
    visitante = team_name(soup,'drt-team s-right cf')
    if Equipo.objects.get(nombre=visitante).escudo.name == '':
        escudo_equipo_visitante = team_shield(soup,'drt-team s-right cf')
        saveShield(visitante, escudo_equipo_visitante)
    if not played(temporada, local, visitante, liga):
        extractData(local, visitante, soup,temporada, liga)

def played(temporada, nombre_equipo_local, nombre_equipo_visitante, liga):
    try:
        Partido.objects.get(liga=liga, temporada=temporada, local__nombre=nombre_equipo_local,visitante__nombre=nombre_equipo_visitante, jugado=True)
        return True
    except:
        return False

def extractData(nombre_equipo_local, nombre_equipo_visitante, soup, temporada, liga):
    try:
        match = Partido.objects.get(liga=liga, temporada=temporada,local__nombre=nombre_equipo_local,visitante__nombre=nombre_equipo_visitante)
        match.goles_local = soup.findAll('li', {'class' : 's-pr s-tcenter'})[0].find('p').text
        match.goles_visitante = soup.findAll('li', {'class' : 's-pr s-tcenter'})[1].find('p').text
        
        stats =  soup.find('div', {'id' : 'bq_estadisticas'})
        if stats:    
            local = stats.findAll('p', {'class' : 'eq-loc'})
            visitante = stats.findAll('p', {'class' : 'eq-vis'})
            match.tarjetas_amarillas_local = local[0].text
            match.tarjetas_amarillas_visitante = visitante[0].text
            match.tarjetas_rojas_local = local[1].text
            match.tarjetas_rojas_visitante = visitante[1].text
            match.faltas_recibidas_local = local[2].text
            match.faltas_recibidas_visitante = visitante[2].text
            match.faltas_cometidas_local = local[3].text
            match.faltas_cometidas_visitante = visitante[3].text
            match.balones_perdidos_local = local[4].text
            match.balones_perdidos_visitante = visitante[4].text
            match.balones_recuperados_local = local[5].text
            match.balones_recuperados_visitante = visitante[5].text
            match.fuera_juego_local = local[6].text
            match.fuera_juego_visitante = visitante[6].text
            match.penalties_local = local[7].text
            match.penalties_visitante = visitante[7].text
            match.intervenciones_portero_local = paradas_local = stats.find('div', {'class': 's-pa sts-stop'}).find('div', {'class' : 's-left'}).find('span').text
            match.intervenciones_portero_visitante = paradas_visitante = stats.find('div', {'class': 's-pa sts-stop'}).find('div', {'class' : 's-right'}).find('span').text
            match.posesion_local = stats.find('p', {'class' : 'pos-loc'}).text.replace("%","")
            if match.posesion_local == u'':
                match.posesion_local = 50
            match.posesion_visitante = stats.find('p', {'class' : 'pos-vis'}).text.replace("%","")
            if match.posesion_visitante == u'':
                match.posesion_visitante = 50
            match.remates_local = accShoots(stats,'local')
            match.remates_visitante = accShoots(stats,'away')
            match.jugado = True
        match.ganador = matchWinner(soup.findAll('li', {'class' : 's-pr s-tcenter'})[0].find('p').text, soup.findAll('li', {'class' : 's-pr s-tcenter'})[1].find('p').text)
        match.save()
    except Exception as inst:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        log(nombre_equipo_local, nombre_equipo_visitante, inst, exc_type, fname, exc_tb.tb_lineno)

def accShoots(stats, option):
    total = 0
    if option == 'local':
        total += int(stats.find('div', {'class': 's-pa sts-post'}).find('div', {'class' : 's-left'}).find('span').text)
        total += int(stats.find('div', {'class': 's-pa sts-inside sts-highlight'}).find('div', {'class' : 's-left'}).find('span').text)
        total += int(stats.find('div', {'class': 's-pa sts-out sts-secondary'}).find('div', {'class' : 's-left'}).find('span').text)
        total += int(stats.find('div', {'class': 's-pa sts-other sts-secondary'}).find('div', {'class' : 's-left'}).find('span').text)
    else:
        total += int(stats.find('div', {'class': 's-pa sts-post'}).find('div', {'class' : 's-right'}).find('span').text)
        total += int(stats.find('div', {'class': 's-pa sts-inside sts-highlight'}).find('div', {'class' : 's-right'}).find('span').text)
        total += int(stats.find('div', {'class': 's-pa sts-out sts-secondary'}).find('div', {'class' : 's-right'}).find('span').text)
        total += int(stats.find('div', {'class': 's-pa sts-other sts-secondary'}).find('div', {'class' : 's-right'}).find('span').text)    
    return total

def matchWinner(goles_local, goles_visitante):
    if goles_local == goles_visitante:
        signo = 'X'
    elif goles_local < goles_visitante:
        signo = '2'
    else:
        signo = '1'
    return signo

def saveMatch(jornada, local, visitante, data, temporada, liga):
    try:
        if not Partido.objects.filter(liga=liga, temporada=temporada, local__nombre=local, visitante__nombre=visitante):
            match = Partido()
            match.liga = liga
            match.temporada = temporada
            match.fecha = data
            match.jornada = jornada 
            match.local = Equipo.objects.get(nombre=local)
            match.visitante = Equipo.objects.get(nombre=visitante)
            match.save()
    except Exception as inst:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        log(local, visitante, inst, exc_type, fname, exc_tb.tb_lineno)
        
def saveShield(equipo, escudo):
    try:
        team = Equipo.objects.get(nombre=equipo)
        img_temp = NamedTemporaryFile()
        img_temp.write(urllib2.urlopen(escudo).read())
        img_temp.flush()
        s = equipo+".jpg"
        team.escudo.save(s, File(img_temp),save=True)
    except Equipo.DoesNotExist:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        log(local, visitante, inst, exc_type, fname, exc_tb.tb_lineno)
  
def createTeam(equipo):
    try:
        team = Equipo.objects.get(nombre=equipo)
    except Equipo.DoesNotExist:
        team = Equipo()
        team.nombre = equipo
        team.save()

def log(local, visitante, inst, a, b, c):
     with open(settings.BASE_DIR+'/futstats/log', 'a') as f:
         f.write(str(dt.datetime.now())+" - "+str(local)+" : "+str(visitante)+" Error:"+str(inst)+" | "+str(a)+":"+str(b)+":"+str(c)+"\n")

#Function which apply matches to teams
@transaction.atomic
def OLD_accData(temporada):
    for e in Equipo.objects.all():
        cleanTeam(e)
        #search for his partidos
        partidos = Partido.objects.filter(temporada=temporada, local=e, jugado=True)
        accStats(e, partidos, 'local')
        partidos = Partido.objects.filter(temporada=temporada, visitante=e, jugado=True)
        accStats(e, partidos, 'visitante')

def cleanTeam(equipo):
    equipo.goles = 0
    equipo.goles_recibidos = 0
    equipo.puntos = 0
    equipo.tarjetas_amarillas = 0
    equipo.tarjetas_rojas = 0
    equipo.faltas_recibidas = 0
    equipo.faltas_cometidas = 0
    equipo.balones_perdidos = 0
    equipo.balones_recuperados = 0
    equipo.fuera_juego = 0
    equipo.penalties = 0
    equipo.intervenciones_portero = 0
    equipo.disparos = 0
    equipo.save()

