# Setup, just putting together what we will need to do the analysis
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.spines import Spine
from matplotlib.projections.polar import PolarAxes
from matplotlib.projections import register_projection

%matplotlib inline
pokemon_data = pd.read_csv('../datasets/pokemon-stats.csv')
damage_mul = pd.read_csv('./damage_multipliers.csv')
status = ['HP','Attack','Defense','Sp. Atk','Sp. Def','Speed']
pokemon_data.head()

damage_mul.head()

# Setup your team! Choose 6 pokemon in the list below
team = ["Milotic", "Aggron", "Vigoroth", "Raichu", "Breloom", "Alakazam"]

# Let's gather only your team's data
team_data = pokemon_data.query("Name in @team")
team_data

# First, let's see your types matchups
# Primary types
team_types = team_data["Type1"].unique().tolist()
# Secundary types may be NaN, let's deal with it
team_types.extend(team_data["Type2"].dropna().unique().tolist())
all_types = damage_mul["Attacking"].unique()
attack_matchups = {}
defense_matchups = {}

for p in team:
    t1 = pokemon_data[pokemon_data["Name"] == p]["Type1"].item()
    t2 = False
    if pokemon_data[pokemon_data["Name"] == p]["Type2"].any():
        t2 = pokemon_data[pokemon_data["Name"] == p]["Type2"].item()
    for t in all_types:
        att_mul =damage_mul[damage_mul["Attacking"] == t1][t].item()
        def_mul = damage_mul[damage_mul["Attacking"] == t][t1].item()
        if t2:
            # In case you have a dual type poke, we get the max multiplier for the attack
            # and the product for the defense
            att_mul = max(att_mul,damage_mul[damage_mul["Attacking"] == t2][t].item())
            def_mul *=damage_mul[damage_mul["Attacking"] == t][t2].item()
        attack_matchups[t] = attack_matchups.get(t, 0) + att_mul
        defense_matchups[t] = defense_matchups.get(t,0) + def_mul
        
attack_matchups = pd.DataFrame(attack_matchups, index=['Score']).T.sort_values('Score', ascending=False).T
defense_matchups = pd.DataFrame(defense_matchups, index=['Score']).T.sort_values('Score', ascending=False).T
status_data = pd.melt(team_data, id_vars=['#','Name','Type1', 'Type2','Legendary','Generation', 'Total'], var_name="Stat")

"""
Explanation: Pokemon Team Composition Analysis
This notebook aims to provide a complete analysis for team composition, choose your 6 pokemons below and run it trough so you can get an overview of your team
End of explanation
"""


plt.figure(figsize=(10,3))
plt.subplot(121)
plt.suptitle("Types Matchups")
plt.title("Attack Matchups")
plt.xlabel("Defending Type")
plt.ylabel("Score")
plt.xticks(range(18), attack_matchups.columns,rotation=65)

att_color = lambda x:(1,0.3,0.3) if x <= 5 else (0.2,0.3,1) if x <= 7 else (0.3, 0.8, 0.1)
def_color = lambda x:(1,0.3,0.3) if x > 8 else (0.2,0.3,1) if x >= 6 else (0.3, 0.8, 0.1)

for x, v in zip(range(18), attack_matchups.values[0]):
    plt.bar(x,v, color=att_color(v))
plt.subplot(122)
plt.title("Defense Matchups")
plt.xlabel("Attacking Type")
plt.xticks(range(18), defense_matchups.columns[::-1],rotation=65)
for x, v in zip(range(18), defense_matchups.values[0][::-1]):
    plt.bar(x,24-v, color=def_color(v))
    
plt.show()

"""
Explanation: Types Matchups
The graphs below show your team's score in both attack and defense matchup, this is calculated as the sum of multipliers of your team against each type for both attack and defense, then the defense score is calculated as 24 (the max possible score for a given type) minus the sum
End of explanation
"""


plt.figure(figsize=(10,5))
plt.title("Status values for your team")
sns.swarmplot(x="Stat", y="value", data=status_data, hue="Name")
plt.ylabel("Value")
plt.xlabel("Status")
colors = ['r','g','b','y','c','k']
for stat,c in zip(status,colors):
    plt.hlines(team_data[stat].mean(),-1,6, linestyles='dotted', color=c, label="%s Avg"%stat)
plt.legend(loc=(1.05,0.05))
plt.show()
print(pokemon_data[status].mean())
print(team_data[status].mean())

fig = plt.figure( figsize=(4,4))
ax = plt.subplot(111)
sns.heatmap(team_data[status], cmap='gist_heat_r')
plt.yticks(range(6), team_data["Name"][::-1], rotation=0)
plt.xticks(rotation=90)
plt.show()

"""
Explanation: Status Analysis
Here you can see an analysis for your team's stats, in the graph below you see how each of your team's pokemons compares to the average status
End of explanation
"""


# Let's get you 3 worst attack and defense matchups
att_w = attack_matchups.columns[-3:].tolist()
def_w = defense_matchups.columns[-3:].tolist()
archenemy = pokemon_data.query("Type1 in @att_w or Type2 in @att_w")
archenemy.query("Type1 in @def_w or Type2 in @def_w")

"""
Explanation: Archenemies
Below you can find an analysis that seeks to point out which pokemons you should be aware of when battling, this analysis takes into account the type matchups of your team
End of explanation
"""


