"""
LICENSE:
Copyright 2016 Hermann Krumrey

This file is part of comunio-manager.

    comunio-manager is a program that allows a user to track his/her comunio.de
    profile

    comunio-manager is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    comunio-manager is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with comunio-manager.  If not, see <http://www.gnu.org/licenses/>.
LICENSE
"""

# imports
import os
import datetime
import matplotlib.dates as dates
import matplotlib.pyplot as pyplot
from comunio.scraper.ComunioSession import ComunioSession
from comunio.database.DatabaseManager import DatabaseManager


class StatisticsCalculator(object):
    """
    Class that calculates various statistics based on the current comunio data and the local database
    """

    def __init__(self, comunio_session: ComunioSession, database_manager: DatabaseManager, xkcd_mode: bool =False)\
            -> None:
        """
        Initializes the statistics calculator with a running comunio session and a database manager
        to interface with the local database

        :param comunio_session:  the comunio session
        :param database_manager: the database manager
        :param xkcd_mode:        if set, the graphs generated by this class will be drawn in an XKCD style
        """
        self.__comunio_session = comunio_session
        self.__database_manager = database_manager
        self.__pyplot_figure = pyplot.figure()

        if xkcd_mode:
            pyplot.xkcd()

    def calculate_total_assets_delta(self) -> int:
        """
        Calculates the difference of the player's current assets compared to the beginning of the season.
        The season is started with 40.000.000€ in cash

        :return: the difference between the values
        """
        assets = self.__database_manager.get_last_cash_amount() + self.__database_manager.get_last_team_value_amount()
        return assets - 40000000

    def generate_time_graph(self, player: str, mode: str) -> str:
        """
        Generates a value/time or a points/time graph for a given player's history as an image file,
        later to be integrated into a GUI.

        :param player: the name of the player for whom the graph will be generated
        :param mode:   the type of value on the y-axis, can be 'points' or 'value'
        :return:       the path to the image in which the graph is stored
        """
        historic_data = self.__database_manager.get_historic_data_for_player(player)

        x_values = []
        y_values = [] if mode == "points" else [self.__database_manager.get_player_buy_value(player)]

        smallest_date = datetime.datetime.utcnow()
        i = len(historic_data) - 1
        while i > -1:
            data_point = historic_data[i]
            data_date = datetime.datetime.strptime(data_point["date"], "%Y-%m-%d")

            x_values.append(data_date.date())
            y_values.append(data_point[mode])

            if mode == "value":
                smallest_date = smallest_date if smallest_date < data_date else data_date

            i -= 1

        if mode == "value":
            x_values = [(smallest_date - datetime.timedelta(days=1)).date()] + x_values

        pyplot.gca().xaxis.set_major_formatter(dates.DateFormatter("%Y-%m-%d"))
        pyplot.gca().xaxis.set_major_locator(dates.DayLocator())
        pyplot.plot(x_values, y_values, "-o")
        pyplot.gcf().autofmt_xdate()

        image_name = (player + "-" + mode).replace(".", "_").replace(" ", "_")
        image_path = os.path.join(os.path.expanduser("~"), ".comunio", "images", image_name)

        if not os.path.isdir(os.path.dirname(image_path)):
            os.makedirs(os.path.dirname(image_path))

        self.__pyplot_figure.savefig(image_path, dpi=self.__pyplot_figure.dpi / 2)
        self.__pyplot_figure.clear()
        return image_path + ".png"
