from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from datetime import datetime, timedelta
from time import gmtime, strftime
import time
from itertools import groupby
from hasApi import get_calendar_events, get_todo_items
import dateutil.parser
from dotenv import load_dotenv

black = "#000000"
white = "#ffffff"


fontSymbols = ImageFont.truetype("SymbolsNerdFont-Regular.ttf", 18)
fontTitle = ImageFont.truetype("Nunito-Bold.ttf", 24)
fontLarge = ImageFont.truetype("Nunito-ExtraLight.ttf", 18)
fontLargeBold = ImageFont.truetype("Nunito-SemiBold.ttf", 18)
fontSmall = ImageFont.truetype("Nunito-ExtraLight.ttf", 16)
fontVerySmall = ImageFont.truetype("Nunito-ExtraLight.ttf", 10)


class Space(Exception):
    pass


def getsize(font, text):
    _, _, right, bottom = font.getbbox(text)
    return (right, bottom)


def reflow_quote(quote, width, font):
    words = quote.split(" ")
    reflowed = ""
    line_length = 0

    for i in range(len(words)):
        word = words[i] + " "
        word_length = getsize(font, word)[0]
        line_length += word_length

        if line_length < width:
            reflowed += word
        else:
            line_length = word_length
            reflowed = reflowed[:-1] + "\n  " + word

    reflowed = reflowed.rstrip()

    return reflowed


def draw_image():
    image = Image.new("P", (400, 300))
    draw = ImageDraw.Draw(image)

    # Draw the top bar
    topbar = 26
    draw.rectangle((0, 0, 400, 300), fill=white)
    draw.rectangle((0, 0, 400, topbar), fill=black)

    # Add the clock
    timeStr = strftime("%H:%M", time.localtime())
    draw.text((10, 3), timeStr, white, fontSmall)

    # Add indoor temperature
    draw.text((350, 3), "19c", white, fontSmall)

    # Add sections
    ep = 3
    margin = 5
    draw.rounded_rectangle(
        (margin, topbar + margin, (400 / 2) - margin, 300 - margin),
        10,
        outline=black,
        width=2,
    )
    draw.rounded_rectangle(
        ((400 / 2) + margin, topbar + margin, 400 - margin, 300 - margin),
        10,
        outline=black,
        width=2,
    )

    # Add tasks
    draw.text((20, topbar + 7), "Tasks", black, fontTitle)
    draw.line((margin, 62, 200 - margin, 62), fill=black, width=1)

    tasks = get_todo_items()

    taskStart = 70
    for task in tasks:
        if task["status"] == "completed":
            continue
            draw.text((15, taskStart - 2), "󰄵", black, fontSymbols)
        else:
            draw.text((15, taskStart), "󰄱", black, fontSymbols)

        reflowedTitle = reflow_quote(task["summary"], 160, fontLarge)
        titleSizeW, titleSizeH = getsize(fontLarge, reflowedTitle)
        titleSizeH *= reflowedTitle.count("\n") + 1

        draw.text((35, taskStart - 3), reflowedTitle, black, fontLarge)
        taskStart += titleSizeH + (2 * ep)

    # Add cal
    draw.text((220, topbar + 7), "Calendar", black, fontTitle)
    draw.line(((400 / 2) + margin, 62, 400 - margin, 62), fill=black, width=1)
    events = get_calendar_events()

    def get_start_date(x):
        start = x["start"]
        if "date" in start:
            startDate = datetime.strptime(start["date"], "%Y-%m-%d").date()
        elif "dateTime" in start:
            startDate = datetime.strptime(start["dateTime"][:10], "%Y-%m-%d").date()
        else:
            print("Error")
            print(start)
            return None
        if startDate < datetime.today().date():
            return datetime.today().date()
        else:
            return startDate

    itemStart = 70
    for key, group in groupby(events, get_start_date):
        dayStart = itemStart
        # Calculate
        if key == datetime.today().date():
            dateStr = "Today"
        elif key == (datetime.today() + timedelta(days=1)).date():
            dateStr = "Tomorrow"
        else:
            dateStr = key.strftime("%d %b")

        w, h = getsize(fontLarge, "Today")
        dayStart += h + (ep)

        dayTasks = list(group)

        for thing in dayTasks:
            reflowedItem = reflow_quote(thing["summary"], 170, fontSmall)
            w, h = getsize(fontLarge, "Today")
            h *= reflowedItem.count("\n") + 1
            dayStart += h + (ep)

        dayStart + ep

        if dayStart > 280:
            print()
            break

        # Commit if possible
        draw.text((215, itemStart), dateStr, black, fontLargeBold)
        w, h = getsize(fontLargeBold, dateStr)
        itemStart += h + ep
        for thing in dayTasks:
            reflowedItem = reflow_quote(thing["summary"], 170, fontSmall)
            w, h = getsize(fontSmall, thing["summary"])
            h *= reflowedItem.count("\n") + 1
            draw.text((230, itemStart), reflowedItem, black, fontSmall)
            itemStart += h + ep

        itemStart += ep

    return image


if __name__ == "__main__":
    load_dotenv()
    img = draw_image()
    img.save("built.bmp")
