import sqlite3
import time
import matplotlib.pyplot as plt
import pathlib
from xmlrpc.client import ServerProxy

api = ServerProxy("https://api.molodetz.nl/rpc")

connection = sqlite3.connect('tikker.db')


weekday_sql = (
    "CASE "
    "WHEN strftime('%w', timestamp) = '0' THEN 'Sunday' "
    "WHEN strftime('%w', timestamp) = '1' THEN 'Monday' "
    "WHEN strftime('%w', timestamp) = '2' THEN 'Tuesday' "
    "WHEN strftime('%w', timestamp) = '3' THEN 'Wednesday' "
    "WHEN strftime('%w', timestamp) = '4' THEN 'Thursday' "
    "WHEN strftime('%w', timestamp) = '5' THEN 'Friday' "
    "WHEN strftime('%w', timestamp) = '6' THEN 'Saturday' "
    "END"
)

def query(sql):
    start = time.time()

    cursor = connection.cursor()
    print(sql)
    result = cursor.execute(sql).fetchall()

    cursor.close()
    duration = time.time() - start

    print("Duration: {}\n".format(duration))
    return result

def render_per_hour(week):
    week = f"{week}"

    sql_presses = (
        "SELECT count(0) as total, strftime('%H', timestamp) as hour, "
        "strftime('%U', timestamp) as week "
        "FROM kevent WHERE event = 'PRESSED' AND week = '{week}' "
        "GROUP BY week, hour ORDER BY hour"
    )
    
    #sql_repeated = (
    #    "SELECT count(0) as total, strftime('%H', timestamp) as hour, "
    #    "strftime('%U', timestamp) as week "
    #    "FROM kevent WHERE event = 'REPEATED' AND week = {week} "
    #    "GROUP BY week, hour ORDER BY hour"
    #)

    #sql_released = (
    #    "SELECT count(0) as total, strftime('%H', timestamp) as hour, "
    #    "strftime('%U', timestamp) as week "
    #    "FROM kevent WHERE event = 'RELEASED' AND week = {week} "
    #    "GROUP BY week, hour ORDER BY hour"
    #)
   

    rows_presses = query(sql_presses.format(week=week))
    #rows_repeated = query(sql_repeated.format(week=week))
    #rows_released = query(sql_released.format(week=week))

    totals = [row[0] for row in rows_presses]
    hours = [row[1] for row in rows_presses]

    #totals_repeated = [row[0] for row in rows_repeated]
    #hours_repeated = [row[1] for row in rows_repeated]

    #totals_released = [row[0] for row in rows_released]
    #hours_released = [row[1] for row in rows_released]

    plt.figure(figsize=(8, 6))
    #plt.plot(hours_repeated, totals_repeated, marker='o', label='Repeats per hour', color='green')
    #plt.plot(hours_released, totals_released, marker='o', label='Releases per hour', color='orange')
    plt.plot(hours, totals, marker='o', label=f'Presses per hour week {week}', color='red')

    plt.xlabel('Hour')
    plt.ylabel('Event count')
    plt.title(f'Key presses per hour. Week {week}')
    plt.style.use('dark_background')
    plt.legend()

    plt.savefig(f"graph_week_{week.strip('\'')}_per_hour.png")

def render_per_day():
    sql_pressed_per_day = (
        "SELECT strftime('%Y-%m-%d', timestamp) as month_day,count(0) as total FROM kevent WHERE event = 'PRESSED' GROUP BY month_day ORDER BY month_day"
    )
    plt.figure(figsize=(8,6))

    rows_pressed_per_day = query(sql_pressed_per_day)

    totals = [row[0] for row in rows_pressed_per_day]
    dates = [row[1] for row in rows_pressed_per_day]

    plt.plot(totals, dates, marker='o', label='Presses per day', color='red')

    plt.xlabel('Date')
    plt.ylabel('Event count')
    plt.xticks(rotation=45) 
    plt.style.use('dark_background')
    plt.title('Keyboard events')
    plt.tight_layout() 
    plt.legend()
    plt.savefig(f"graph_per_day.png")

def render_per_week():
    sql_pressed_per_day = (
        f"SELECT strftime('%Y-%U', timestamp) as week,count(0) as total FROM kevent WHERE event = 'PRESSED' GROUP BY week ORDER BY week"
    )
    plt.figure(figsize=(8,6))

    rows_pressed_per_day = query(sql_pressed_per_day)

    totals = [row[0] for row in rows_pressed_per_day]
    dates = [row[1] for row in rows_pressed_per_day]

    plt.plot(totals, dates, marker='o', label='Presses per day', color='red')

    plt.xlabel('Week')
    plt.ylabel('Presses count')
    plt.xticks(rotation=45) 
    plt.title(f'Presses per week')
    plt.tight_layout() 
    plt.style.use('dark_background')
    plt.legend()

    plt.savefig(f"graph_per_week.png")




def render_per_weekday(week):

    sql_presses = (
        f"SELECT count(0) as total, {weekday_sql} as weekday, "
        "strftime('%w', timestamp) as day, strftime('%U', timestamp) as week "
        "FROM kevent WHERE event = 'PRESSED' AND week = '{week}' "
        "GROUP BY week, day ORDER BY day"
    )

    sql_repeated = (
        f"SELECT count(0) as total, {weekday_sql} as weekday, "
        "strftime('%w', timestamp) as day, strftime('%U', timestamp) as week "
        "FROM kevent WHERE event = 'REPEATED' AND week = '{week}' "
        "GROUP BY week, day ORDER BY day"
    )

    sql_released = (
        f"SELECT count(0) as total, {weekday_sql} as weekday, "
        "strftime('%w', timestamp) as day, strftime('%U', timestamp) as week "
        "FROM kevent WHERE event = 'RELEASED' AND week = '{week}' "
        "GROUP BY week, day ORDER BY day"
    )

    rows_presses = query(sql_presses.format(week=week))
    #rows_repeated = query(sql_repeated.format(week=week))
    #rows_released = query(sql_released.format(week=week))

    totals = [row[0] for row in rows_presses]
    days = [row[2] for row in rows_presses]

    #totals_repeated = [row[0] for row in rows_repeated]
    #days_repeated = [row[2] for row in rows_repeated]

    #totals_released = [row[0] for row in rows_released]
    #days_released = [row[2] for row in rows_released]

    plt.figure(figsize=(8, 6))
    #plt.plot(days_repeated, totals_repeated, marker='o', label='Repeats per weekday', color='green')
    #plt.plot(days_released, totals_released, marker='o', label='Releases per weekday', color='orange')
    plt.plot(days, totals, marker='o', label=f'Press count', color='red')

    plt.xlabel('Weekday (0 = Sunday, 6 = Saturday)')
    plt.ylabel('Event count')
    plt.title(f'Presses per weekday. Week {week}')
    plt.style.use('dark_background')
    plt.legend()

    plt.savefig(f"graph_week_{week.strip('\"')}_per_weekday.png")

def get_weeks():
    sql = "SELECT strftime('%U', timestamp) as week FROM kevent GROUP BY week"
    weeks = query(sql)
    return [record[0] for record in weeks]

def get_score_per_week():
    sql = (
        "SELECT strftime('%U', timestamp) as week, event, COUNT(0) as total "
        "FROM kevent GROUP BY event, week"
    )
    return query(sql)

def get_score_per_day():
    
    sql ="SELECT count(0) as total, CASE WHEN strftime('%w', timestamp) = 0 THEN 'Sunday' WHEN strftime('%w', timestamp) = 1 THEN 'Monday' WHEN strftime('%w', timestamp) = 2 THEN 'Tuesday' WHEN strftime('%w', timestamp) = 3 THEN 'Wednesday' WHEN strftime('%w', timestamp) = 4 THEN 'Thursday' WHEN strftime('%w', timestamp) = 5 THEN 'Friday' WHEN strftime('%w', timestamp) = 6 THEN 'Saturday' END as weekday, strftime('%w', timestamp) as day, strftime('%U', timestamp) as week FROM kevent WHERE event = 'REPEATED' GROUP BY week, day ORDER BY day"

    sql = (
        f"SELECT strftime('%U',timestamp) as week, {weekday_sql} as wday, event, COUNT(0) as total "
        f"FROM kevent WHERE event in ('PRESSED') GROUP BY week, event, wday  ORDER BY week, event, wday"
    )
    return query(sql)

def get_totals():
    sql = "SELECT count(0) as total, event from kevent group by event"
    return query(sql)

# Main execution
if __name__ == "__main__":
    time_start = time.time()

    render_per_day()
    render_per_week()
    for week in get_weeks():
        render_per_hour(week)
        render_per_weekday(week)

    print("Score per week:")
    for record in get_score_per_week():
        print(f"{record[0]}  \t{record[1]}  \t{record[2]}")

    print("Score per day:")
    for record in get_score_per_day():
        print(f"{record[0]}  \t{record[1]}  \t{record[2]}")
    
    print("Total events:")
    totals = 0
    for record in get_totals():
        print(f"{record[1]}: {record[0]}")
        totals += record[0]
    print(totals)

    result = {}
    rows = query("SElECT strftime('%Y-%m-%d.%H', timestamp) as date_hour, GROUP_CONCAT(char,'') FROM kevent WHERE event = 'PRESSED' group by date_hour")
    for row in rows:
        result[row[0]] = row[1]
    
    with open("keylog.txt","w") as f:
        for day in result.keys():
            date, hour = day.split(".") 
            label = f"{date} {hour}:00"
            if not pathlib.Path("logs_plain/"+day+".txt").exists():
                with open("logs_plain/"+day+".txt","w") as g:


                    g.write(f"**{label}**: ```{result[day]}```\n\n")
            f.write(f"**{label}**: ```{result[day]}```\n\n")
    
    import json
    for file in pathlib.Path(".").glob("logs_plain/*.txt"):
        print("Working on: {}".format(file))
        dest_file = file.parent.parent.joinpath("logs_summaries").joinpath(file.name)
        print("Dest file: ", dest_file)
        if dest_file.exists():
            continue
        with dest_file.open("w+") as f:
            print("Requesting...")
            param = file.read_text().replace("@","").replace("`","")
            response = api.gpt4o_mini("The following data is key presses made by user. Describe what user could be working on using bulletpoints: "+param)
            print("Done")
            f.write(response)
            print(response)
    for file in pathlib.Path(".").glob("logs_summaries/*.txt"):
        dest_file = file.parent.parent.joinpath("logs_lines").joinpath(file.name)
        if dest_file.exists():
            print("One liner already exists for" + file.name)
            continue
        with dest_file.open("w+") as f:
            source = file.read_text().replace("@","").replace("`","")
            response = api.gpt4o_mini("The following data is a hour of work summarized from the user. Describe what user was doing in a onliner.: "+source)
            f.write(response)
            print("Made one liner for" + file.name)
            
    print("Duration: {}".format(time.time() - time_start))