from drstats.db import get_db, Db, get_users
import asyncio
from drstats.duration import Duration


def new_plot():
    import matplotlib.pyplot as plt

    plt.clf()
    plt.cla()
    plt.close(0)
    plt.figure(figsize=(8, 8))
    return plt


def get_date_range():
    with Db() as db:
        record = list(
            db.query(
                "SELECT min(date(created)) as start_date, max(date(created)) as end_date FROM rants"
            )
        )[0]
        return record["start_date"], record["end_date"]


def get_date_range_str():
    start_date, end_date = get_date_range()
    return f"from {start_date} to {end_date}"


async def rant_stats_per_day():
    with Duration("Rant stats per day"):
        plt = new_plot()
        async with Db() as db:
            x = []
            y = []

            for record in db.query("SELECT * FROM rant_stats_per_day"):
                y.append(record["count"])
                x.append(
                    record["created_date"].replace("2014-", "")
                    + " "
                    + str(record["weekday"])
                )

            plt.plot(x, y, label=get_date_range_str(), color="blue")
            plt.xticks(rotation=20)
            plt.xlabel("Date")
            plt.ylabel("Rant count")
            plt.title("Rants per day")
            plt.legend()
            plt.savefig(f"export/rants_per_day_{get_date_range_str()}.png")


async def comment_stats_per_day():
    with Duration("Comment stats per day"):

        plt = new_plot()
        async with Db() as db:
            x = []
            y = []

            for record in db.query("SELECT * FROM comment_stats_per_day"):
                y.append(record["count"])
                x.append(
                    record["created_date"].replace("2014-", "")
                    + " "
                    + str(record["weekday"])
                )

            plt.plot(x, y, label=get_date_range_str(), color="blue")
            plt.xticks(rotation=20)
            plt.xlabel("Date")
            plt.ylabel("Comment count")
            plt.title("Comments per day")
            plt.legend()
            plt.savefig(f"export/comments_per_day_{get_date_range_str()}.png")


async def rant_stats_per_weekday():
    with Duration("Rant stats per weekday"):
        plt = new_plot()
        async with Db() as db:
            x = []
            y = []

            for record in db.query("SELECT * FROM rant_stats_per_weekday"):
                y.append(record["count"])
                x.append(str(record["weekday"]))

        plt.plot(x, y, label=get_date_range_str(), color="green")
        plt.xticks(rotation=20)
        plt.xlabel("Weekday")
        plt.ylabel("Rant count")
        plt.title("Rants per weekday")
        plt.legend()
        plt.savefig(f"export/rants_per_weekday_{get_date_range_str()}.png")


async def comment_stats_per_weekday():
    with Duration("Comment stats per weekday"):
        plt = new_plot()
        async with Db() as db:
            x = []
            y = []

            for record in db.query("SELECT * FROM comment_stats_per_weekday"):
                y.append(record["count"])
                x.append(str(record["weekday"]))

            plt.plot(x, y, label=get_date_range_str(), color="green")
            plt.xticks(rotation=20)
            plt.xlabel("Weekday")
            plt.ylabel("Comment count")
            plt.title("Comments per weekday")
            plt.legend()
            plt.savefig(f"export/comments_per_weekday_{get_date_range_str()}.png")


async def rant_stats_per_hour():
    with Duration("Rant stats per hour"):
        plt = new_plot()
        async with Db() as db:
            x = []
            y = []

            for record in db.query("SELECT * FROM rant_stats_per_hour"):
                y.append(record["count"])
                x.append(record["hour"])

            plt.plot(x, y, label=get_date_range_str(), color="pink")
            plt.xticks(rotation=45)
            plt.xlabel("Hour")
            plt.ylabel("Rant count")
            plt.title("Rants per hour")
            plt.legend()
            plt.savefig(f"export/rants_per_hour_{get_date_range_str()}.png")


async def comment_stats_per_hour():
    with Duration("Comment stats per hour"):
        plt = new_plot()
        async with Db() as db:
            x = []
            y = []

            for record in db.query("SELECT * FROM comment_stats_per_hour"):
                y.append(record["count"])
                x.append(record["hour"])

            plt.plot(x, y, label=get_date_range_str(), color="pink")
            plt.xticks(rotation=45)
            plt.xlabel("Hour")
            plt.ylabel("Comment count")
            plt.title("Comments per hour")
            plt.legend()
            plt.savefig(f"export/comments_per_hour_{get_date_range_str()}.png")


async def score_most_ignored_last_7_days():
    with Duration("Score most ignored last 7 days"):
        plt = new_plot()
        async with Db() as db:
            x = []
            y = []

            for record in db.query(
                "SELECT * FROM score_ignored_most_last_7_days LIMIT 15"
            ):
                x.append(record["username"])
                y.append(record["userscore"])

            plt.bar(x, y, label="Upvotes")
            plt.xticks(rotation=45)
            plt.xlabel("Ranter")
            plt.ylabel("Times ignored")
            plt.title("Most ignored based on score regarding last 7 days")
            plt.legend()
            plt.savefig(
                f"export/score_ignored_most_last_7_days_{get_date_range_str()}.png"
            )


async def score_last_7_days():
    with Duration("Upvotes (score) last 7 days"):
        plt = new_plot()
        async with Db() as db:
            x = []
            y = []

            for record in db.query("SELECT * FROM score_last_7_days LIMIT 15"):
                x.append(record["username"])
                y.append(record["userscore"])

            plt.bar(x, y, label="Upvotes")
            plt.xticks(rotation=45)
            plt.xlabel("Ranter")
            plt.ylabel("Upvote count")
            plt.title("Most popular based on score regarding last 7 days")
            plt.legend()
            plt.savefig(f"export/score_last_7_days_{get_date_range_str()}.png")


async def user_score_per_day(username):
    with Duration("User {} score per day".format(username)):
        plt = new_plot()
        async with Db() as db:

            plt.xticks(rotation=45)
            plt.title(f"{username}'s score per day")
            plt.xlabel("Date")
            plt.ylabel("Score")

            x = []
            y = []

            for record in db.query(
                "SELECT * FROM user_stats WHERE username = '{}'".format(username)
            ):
                x.append(record["date"])
                y.append(record["post_count"])
            plt.plot(x, y, label="Posts")

            x = []
            y = []
            for record in db.query(
                "SELECT * FROM user_stats WHERE username = '{}'".format(username)
            ):
                x.append(record["date"])
                y.append(record["ignore_count"])
            plt.plot(x, y, label="Times ignored")

            x = []
            y = []
            for record in db.query(
                "SELECT * FROM user_stats WHERE username = '{}'".format(username)
            ):
                x.append(record["date"])
                y.append(record["upvote_times"])
            plt.plot(x, y, label="Times upvoted")

            x = []
            y = []
            for record in db.query(
                "SELECT * FROM user_stats WHERE username = '{}'".format(username)
            ):
                x.append(record["date"])
                y.append(record["upvote_total"])
            plt.plot(x, y, label="Sum upvotes")

            plt.legend()
            plt.savefig(f"export/score_user_{username}_{get_date_range_str()}.png")


def stats():
    with Duration("Complete process"):
        asyncio.run(rant_stats_per_day())
        asyncio.run(rant_stats_per_weekday())
        asyncio.run(rant_stats_per_hour())
        asyncio.run(comment_stats_per_day())
        asyncio.run(comment_stats_per_weekday())
        asyncio.run(comment_stats_per_hour())
        asyncio.run(score_most_ignored_last_7_days())
        asyncio.run(score_last_7_days())
        for user in get_users():
            asyncio.run(user_score_per_day(user))
