import csv
from collections import defaultdict
import json
import urllib
from datetime import datetime
# from difflib import SequenceMatcher
import codecs
import os
SCRIPT_DIR = os.path.dirname(__file__)


def update_2016_fpl_data():
    """downloads and updates FPL data for 2016-2017 season using fpl api
    """
    master_url = 'https://fantasy.premierleague.com/drf/bootstrap-static'
    response = urllib.urlopen(master_url)
    master_data = json.loads(response.read())
    print "master data loaded"
    i = 0
    for player in master_data['elements']:
        player_id = player['id']
        print 'pulling data for player %s' % (i)
        player_url = 'https://fantasy.premierleague.com/drf/element-summary/%s' % (player_id)
        response = urllib.urlopen(player_url)
        player_data = json.loads(response.read())
        master_data['elements'][i]['player_data'] = player_data
        i += 1

    data_json = json.dumps(master_data)
    with open('fpl_2016_data.json', 'w') as f:
        f.write(data_json)


def create_table_dataset():
    """creates a file containing json of form -
    {
        "Liverpool",
        {
            "2013": [
                {
                    "week": 1,
                    "total_points": 0,
                    "total_goals_scored": 0,
                    "total_goals_conceded": 0,
                    "total_clean_sheets": 0,
                    "at_home": True,
                },
                ...
            ]
            ...
        },
        ...
    },
    """
    with open('england_2013-2015_fixtures.csv', 'r') as read_file:
        # create list of fixtures per team
        fixtures_dict = defaultdict(list)
        next(read_file)
        for line in read_file:
            entries = [entry.strip().strip('"') for entry in line.split(',')]
            date = datetime.strptime(entries[0], '%Y-%m-%d')
            season = int(entries[1])
            home_team = entries[2]
            away_team = entries[3]
            home_goals = int(entries[4])
            away_goals = int(entries[5])
            if home_goals > away_goals:
                points_tuple = (3, 0)
            elif home_goals == away_goals:
                points_tuple = (1, 1)
            else:
                points_tuple = (0, 3)
            home_entry = {
                'date': date,
                'season': season,
                'opponent': away_team,
                'is_home': True,
                'goals_scored': home_goals,
                'goals_conceded': away_goals,
                'points_taken': points_tuple[0]
            }
            away_entry = {
                'date': date,
                'season': season,
                'opponent': home_team,
                'is_home': False,
                'goals_scored': away_goals,
                'goals_conceded': home_goals,
                'points_taken': points_tuple[1]
            }
            fixtures_dict[home_team].append(home_entry)
            fixtures_dict[away_team].append(away_entry)

    # print fixtures_dict['Liverpool']
    teams_dataset_dict = {}
    for team, fixtures in fixtures_dict.iteritems():
        seasons_dict = defaultdict(list)
        sorted_fixtures = sorted(fixtures, key=lambda k: k['date'])
        i = 0
        total_points = 0
        total_clean_sheets = 0
        total_goals_scored = 0
        total_goals_conceded = 0
        previous_season = 2012
        for result in sorted_fixtures:
            season = result['season']
            if previous_season != season:
                i = 0
                total_points = 0
                total_goals_scored = 0
                total_goals_conceded = 0
                total_clean_sheets = 0
                previous_season = season
            total_points += result['points_taken']
            total_goals_scored += result['goals_scored']
            total_goals_conceded += result['goals_conceded']
            if result['goals_conceded'] == 0:
                total_clean_sheets += 1
            i += 1
            week = i
            entry = {
                "week": week,
                "total_points": total_points,
                "total_goals_scored": total_goals_scored,
                "total_goals_conceded": total_goals_conceded,
                "total_clean_sheets": total_clean_sheets,
                "at_home": result['is_home']
            }
            seasons_dict[season].append(entry)
        teams_dataset_dict[team] = seasons_dict
    teams_dataset_json = json.dumps(teams_dataset_dict)
    with open('table_data.json', 'w') as f:
        f.write(teams_dataset_json)

    # print teams_dataset_dict['Liverpool'][2014][37]


def create_players_static_dataset_2014():
    """creates a json list of dicts with following values per player for each player in fpl 2016 db
        1:{
            'name': name,
            'position': position,
            'team_name': team_name,
            'points_last_season': points_last_season (None if not in last season roster),
            'minutes_last_season': minutes_last_season (None if not in 2013 roster),
        }
    """
    # load 2014 fpl player data
    fpl14_player_list = []
    with codecs.open('FPL2014/Player_Details.csv', 'r', encoding='utf-8', errors='replace') as f:
        next(f)
        for line in f:
            entries = [entry.strip().strip('"') for entry in line.split(',')]
            fpl14_player_list.append(entries)

    # load 2013 fpl player data
    fpl13_player_list = []
    with codecs.open('FPL2013/FPL2013_player_data.csv', 'r', encoding='utf-8', errors='replace') as f:
        next(f)
        for line in f:
            entries = [entry.strip().strip('"') for entry in line.split(',')]
            fpl13_player_list.append(entries)

    player_dict = defaultdict(dict)
    print len(fpl14_player_list)
    for player_entry in fpl14_player_list:
        # print player_entry
        id = int(player_entry[0])
        name = player_entry[1]
        print name
        # name = name.decode('string_escape')
        # name = name.encode('utf8')
        # print name
        team_name = player_entry[2]
        position = player_entry[3]
        i = 0
        index = -1
        for player_13 in fpl13_player_list:
            if name.lower().strip() == player_13[0].lower().strip():
                index = i
            i += 1
        if index == -1:
            points_last_season = None
            minutes_last_season = None
        else:
            matched_player = fpl13_player_list.pop(index)
            points_last_season = matched_player[6]
            minutes_last_season = matched_player[2]
        player_dict[id] = {
            'name': name,
            'team_name': team_name,
            'position': position,
            'points_last_season': points_last_season,
            'minutes_last_season': minutes_last_season,
        }
    player_dict_json = json.dumps(player_dict)
    with open('2014_static_player_dataset.json', 'w') as f:
        f.write(player_dict_json)


def get_average_points_per_minute_dict(players_static_data):
    """returns dict with average points per last season per position
    """
    total_pls_goalkeeper = 0.0
    total_minls_goalkeeper = 0.0
    # num_of_goalkeepers = 0
    total_pls_defender = 0.0
    total_minls_defender = 0.0
    # num_of_defenders = 0
    total_pls_midfielder = 0.0
    total_minls_midfielder = 0.0
    # num_of_midfielders = 0
    total_pls_forward = 0.0
    total_minls_forward = 0.0
    # num_of_forwards = 0

    for p_id, stats in players_static_data.iteritems():
        if stats['points_last_season']:
            if stats['position'] == 'Goalkeeper':
                # num_of_goalkeepers += 1
                total_pls_goalkeeper += float(stats['points_last_season'])
                total_minls_goalkeeper += float(stats['minutes_last_season'])
            elif stats['position'] == 'Defender':
                # num_of_defenders += 1
                total_pls_defender += float(stats['points_last_season'])
                total_minls_defender += float(stats['minutes_last_season'])
            elif stats['position'] == 'Midfielder':
                # num_of_midfielders += 1
                total_pls_midfielder += float(stats['points_last_season'])
                total_minls_midfielder += float(stats['minutes_last_season'])
            elif stats['position'] == 'Forward':
                # num_of_forwards += 1
                total_pls_forward += float(stats['points_last_season'])
                total_minls_forward += float(stats['minutes_last_season'])
            else:
                print "Something is wrong. Check player static data positions."

    average_ppmls_goalkeeper = total_pls_goalkeeper / total_minls_goalkeeper
    average_ppmls_defender = total_pls_defender / total_minls_defender
    average_ppmls_midfielder = total_pls_midfielder / total_minls_midfielder
    average_ppmls_forward = total_pls_forward / total_minls_forward

    average_ppmls_dict = {
        'Goalkeeper': average_ppmls_goalkeeper,
        'Defender': average_ppmls_defender,
        'Midfielder': average_ppmls_midfielder,
        'Forward': average_ppmls_forward,
    }
    return average_ppmls_dict


def create_data_points_2014():
    """creates data points of the form
        player_id,
        last_season_points_per_minutes,
        opponent_points_per_game_last_season,
        minutes_per_matches_played,
        points_per_matches_played,
        goals_per_matches_played,
        assists_per_matches_played,
        yellow_cards_per_matches_played,
        red_cards_per_matches_played,
        bps_per_matches_played,
        price,
        avg_points,
        avg_minutes,
        avg_goals,
        avg_assists,
        avg_bps,
        avg_net_transfers,
        avg_price_drop,
        team_points_per_match,
        team_goals_scored_per_match,
        team_goals_conceded_per_match,
        opponent_points_per_match,
        opponent_goals_scored_per_match,
        opponent_goals_conceded_per_match,
        is_at_home,

    """
    teams_points_per_match_2013 = {
        'Arsenal': float(79) / 38,
        'Aston Villa': float(38) / 38,
        'Burnley': float(33) / 38,
        'Chelsea': float(82) / 38,
        'Everton': float(72) / 38,
        'Crystal Palace': float(45) / 38,
        'Hull': float(37) / 38,
        'Leicester': float(33) / 38,
        'Liverpool': float(84) / 38,
        'Man City': float(86) / 38,
        'Man Utd': float(64) / 38,
        'Newcastle': float(49) / 38,
        'QPR': float(33) / 38,
        'Southampton': float(56) / 38,
        'Spurs': float(69) / 38,
        'Stoke': float(50) / 38,
        'Sunderland': float(38) / 38,
        'Swansea': float(42) / 38,
        'West Brom': float(36) / 38,
        'West Ham': float(40) / 38,
    }

    f_path = os.path.join(SCRIPT_DIR, '2014_static_player_dataset.json')
    with open(f_path, 'r') as f:
        players_static_data = json.load(f)

    average_ppmls_dict = get_average_points_per_minute_dict(players_static_data)

    f_path = os.path.join(SCRIPT_DIR, 'table_data.json')
    with open(f_path, 'r') as f:
        table_data = json.load(f)

    match_data_dict = defaultdict(dict)
    f_path = os.path.join(SCRIPT_DIR, 'FPL2014/Player_Data.csv')
    with open(f_path, 'r') as f:
        next(f)
        for line in f:
            entries = [entry.strip().strip('"') for entry in line.split(',')]
            # week
            week = int(entries[1])
            # player id
            player_id = entries[0]
            # points per minutes last season
            minutes_last_season = players_static_data[player_id]['minutes_last_season']
            points_last_season = players_static_data[player_id]['points_last_season']
            if points_last_season:
                minutes_last_season = int(minutes_last_season)
                points_last_season = int(points_last_season)
                if minutes_last_season != 0:
                    last_season_points_per_minutes = float(points_last_season) / minutes_last_season
                else:
                    # player present but did not play last season
                    last_season_points_per_minutes = 0
            else:
                # new player this season, assign average values for last season
                position = players_static_data[player_id]['position']
                last_season_points_per_minutes = average_ppmls_dict[position]
            # team_points_per_match_last_season
            team = players_static_data[player_id]['team_name']
            team_points_per_match_last_season = teams_points_per_match_2013[team]
            # opponent_points_per_game_last_season
            opponent_name = entries[2]
            opponent_points_per_match_last_season = teams_points_per_match_2013[opponent_name]
            # price
            price = entries[-2]
            # team_points_per_match
            # team_goals_scored_per_match,
            # team_goals_conceded_per_match,
            # is_at_home,
            # print players_static_data[player_id]
            team_table_data = table_data[team]["2014"]
            aggregate_data = team_table_data[week - 1]
            team_points_per_match = float(aggregate_data['total_points']) / (week)
            team_goals_scored_per_match = float(aggregate_data['total_goals_scored']) / (week)
            team_goals_conceded_per_match = float(aggregate_data['total_goals_conceded']) / (week)
            # if player_id == '344':
            #     print aggregate_data['total_points']
            #     print team_points_per_match
            # print team
            # print week
            # print team_table_data[week]
            is_at_home = team_table_data[week - 1]['at_home']
            # opponent_points_per_match,
            # opponent_goals_scored_per_match,
            # opponent_goals_conceded_per_match,
            oppn_table_data = table_data[opponent_name]["2014"]
            aggregate_data = oppn_table_data[week - 1]
            opponent_points_per_match = float(aggregate_data['total_points']) / (week)
            opponent_goals_scored_per_match = float(aggregate_data['total_goals_scored']) / (week)
            opponent_goals_conceded_per_match = float(aggregate_data['total_goals_conceded']) / (week)

            player_dict = {
                'last_season_points_per_minutes': last_season_points_per_minutes,
                'team_points_per_match_last_season': team_points_per_match_last_season,
                'opponent_points_per_match_last_season': opponent_points_per_match_last_season,
                'price': price,
                'team_points_per_match': team_points_per_match,
                'team_goals_scored_per_match': team_goals_scored_per_match,