import PIL 
from PIL import Image ,ImageDraw, ImageFont
import matplotlib.pyplot as plt 
from getData import DataScraper
import pandas as pd 
from settings import USERNAME,PASSWORD,BASE_URL
from datetime import date 
import json
from tqdm import tqdm 
from collections import OrderedDict
import numpy as np 
from datetime import datetime

def get_data(emeis:list[str],scraper:DataScraper) -> list[pd.DataFrame]:
    dataframes = []
    for imei in tqdm(emeis,ascii=True,desc="gather_data"): 
        resp = json.loads(scraper.get_data(imei,history_length=90)["response"].decode("utf-8"))["data"]
        df = pd.DataFrame(resp)
        df['MeasurementTime'] = pd.to_datetime(df['MeasurementTime']) #fix time date
        dataframes.append(df)
            
    return dataframes


def get_data_within_n_days(df:pd.DataFrame,num_days:int,current_date:str) -> pd.DataFrame:
    """
    takes the data from n days back. where 0 means only the current day. 1 means current and yesterday, etc.

    """
    cutoff_date = pd.Timestamp(current_date).tz_localize('UTC') -pd.Timedelta(days=num_days) #'2023-10-01'    

    filtered_df = df[df['MeasurementTime'] >= cutoff_date]

    return filtered_df

def get_data_after_date(df:pd.DataFrame,after_date:datetime=datetime(2024,10,28)) -> pd.DataFrame:

    return df[df['MeasurementTime'] >= pd.Timestamp(str(after_date)).tz_localize('UTC')]


def add_elem(text:str,x:int,y:int,img,font_size:int=28):
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype("arial.ttf", font_size)        
    draw.text((x, y), text, font=font, fill=(int(0.37254901960784315*255),int(0.20784313725490197*255),int(0.09411764705882353*255)))  
    return img 


def fill_column(elements:list[str],column_index:int,img):
    """
    column index starts at 0 for the first column
    """
    delta = 85
    column_shift = [1500,1500+delta*1,1500+delta*2,1500+delta*3,1500+delta*4,1500+delta*5,1500+delta*6]
    dist = 37
    row_shift = [720,760,925,1120,1295,1470,1510,1650,1650+dist,1650+dist*2,1650+dist*3,1650+dist*4,1650+dist*5,1650+dist*6,1650+dist*7,1650+dist*8,1650+dist*9,2135,2315,2315+dist*1,2315+dist*2,2315+dist*3,2560,2750,2750+dist]

    for row_index,elem in enumerate(elements):
        add_elem(elem,column_shift[column_index],row_shift[row_index],img)

    return img

def df_slope(df:pd.DataFrame,y_column_name:str) -> tuple:
    """
    assumes that 'MeasurementTime' carries the DateTime data.
    """
    
    df["x"] = (df["MeasurementTime"]-df["MeasurementTime"].min()).dt.total_seconds()/(60*60*4) #resolution of an hour
    slope, intercept = np.polyfit(df["x"] , df[y_column_name], 1)
    return slope, intercept

"""
Sv4 dynamisch 
Sv5 static
"""

"""
Supposedly this script will only be run on friday.
DO NOT RUN IT ON ANY OTHER DAY THAN THURSDAY!!!
"""
if __name__ == "__main__":
    pd.options.mode.copy_on_write = True
    current_date = date.today()
    week_number = date.isocalendar(current_date)[1]

    scraper = DataScraper(USERNAME,PASSWORD,BASE_URL)
    imeis = OrderedDict([("KW1100-0070","86620705863754"),("KW1100-0071","86620705863410"),("KW1100-0080", "86620705863765"),("KW1100-0069","86620705863772"),("KW1100-0065","86620705864160"),("KW1100-0078","86620705863735"),("KW1100-0061","86620705863782"),("KW1100-0059","86620705863392"),("KW1100-0062","86620705863715"),("KW1100-0075","86620705863575"),("KW1100-0073","86620705864180"),("KW1100-0064","86620705863719"),("KW1100-0063","86620705863729"),("KW1100-0066","86620705863736"),("KW1100-0052","86366306494384"),("KW1100-0054","86366306494401"),("KW1100-0074","86620705864162"),("KW1100-0060","86620705863639"),("KW1100-0055","86620705863526"),("KW1100-0058","86620705864178"),("KW1100-0057","86620705864123") , ("KW1100-0056","86620705864099"),("KW1100-0051","86366306494409"),("KW1100-0079","86620705864105"),("KW1100-0049","86366306491069")])        
    img = Image.open("template.png")
    img = add_elem(str(current_date),400,160,img,font_size=40)
    img = add_elem(str(week_number),400,110,img,font_size=40)


    
    dfs = get_data(list(imeis.values()),scraper) 
    
    dfs = [get_data_after_date(df) for df in dfs] #cull the herd of old data

    seven_day_dfs = [get_data_within_n_days(df,7,current_date) for df in dfs]
    counts_per_day = [df["MeasurementTime"].dt.floor('d').value_counts().sort_index().rename_axis("counts") for df in seven_day_dfs]

    days = {"vr":[],"za":[],"zo":[],"ma":[],"di":[],"wo":[],"do":[]}
    for count in counts_per_day: 
        str_count_list = [str(elem) for elem in list(count)]
        for i,day in enumerate(["do","vr","za","zo","ma","di","wo"]):
            days[day].append(str_count_list[i])
    
    img = fill_column(days["do"],0,img)
    img = fill_column(days["vr"],1,img)
    img = fill_column(days["za"],2,img)
    img = fill_column(days["zo"],3,img)
    img = fill_column(days["ma"],4,img)
    img = fill_column(days["di"],5,img)
    img = fill_column(days["wo"],6,img)
    # plt.imshow(img)
    # plt.show()
    img.save("report.pdf")
    