from datetime import timedelta
from datetime import datetime
from typing import TypedDict, List, Union
from os import path
from pathlib import Path
from shutil import copy
import xml.etree.ElementTree as ET
import datetime as dt
import json

TOM = datetime.today() + timedelta(days=1) # tomorrow by default
STARTTIME = TOM.replace(hour=5, minute=0, second=0, microsecond=0)
FIFTEENMINUTES = 60 * 15
THREEMINUTES = 60 * 3

SHOWTEMPLATE = """
<html>
    <head>
        <title>{title}</title>
    </head>
    <body>
        <h1>{title}</h1>
        <hr />
        <p>{description}</p>
        {img}
    </body>
</html>
"""

IMGTEMPLATE = """<img alt="Poster for {title}" src="{poster}" />"""

INDEX = """
<html>
    <head>
        <title>New Ellijay TV: Electronic Program Guide</title>
    </head>
    <body>
        <ul>
        {list}
        </ul>
    </body>
</html>
"""

LINEENTRY = """<li>
    <a href='./index/{pth}.html'>{title}</a> - {starttime} ({duration}m)
</li>"""


# Type annotations for a good DX
Entry = TypedDict(
    "Entry",
    {
        "in": int,
        "out": int,
        "duration": int,
        "source": str,
        # METADATA ADDONS:
        "start_time": datetime,
        "description": str,
        "poster": str,
        "title": str
    },
)

class Program(TypedDict):
    channel: str
    date: str
    program: List[Entry]


Directory = []


program: Union[Program, None] = None # Union because I want it to exist without loading the file

with open("playlist.json", "r") as f:
    program = json.load(f)

Path("out/index/images").mkdir(exist_ok=True, parents=True)

if program: # Narrow the type
    runningTime = 0
    for element in program["program"]:

        if element["duration"] < THREEMINUTES: # Skip short programs
            continue

        element["start_time"] = STARTTIME + dt.timedelta(seconds=runningTime) # Set the starttime to the duration of the current programs + the starttime

        if element["duration"] > FIFTEENMINUTES:
            # round start_time down to nearest 15 minutes
            element["start_time"] = element["start_time"] - dt.timedelta(
                minutes=element["start_time"].minute % 15
            )
            element["start_time"] = element["start_time"]
        

        # replace file extension with .nfo on element["source"] and put it in a new variable
        info = path.splitext(element["source"])[0] + ".nfo"
        # info = "example.nfo"

        # parse info file as xml

        if not path.exists(info):
            element["description"] = ""
            element["poster"] = ""
            element["title"] = path.splitext(path.basename(element['source']))[0]
            continue

        with open(info, "r") as f:
            xmlTree = ET.parse(f)
            root = xmlTree.getroot()

            
            description = root.findall("./plot")[0]
            element["description"] = description.text # type: ignore

            try:
                poster = root.findall("./art/poster")[0]
                loc: str = poster.text # type: ignore
                
                image_file_name = path.splitext(path.basename(element['source']))[0] + path.splitext(loc)[1]
                copy(loc, f"out/index/images/{image_file_name}") # add poster and file extension of original poster
                element["poster"] = f"./images/{image_file_name}"

            except IndexError:
                element["poster"] = ""
            
            

            
            title = root.findall("./title")[0]
            element["title"] = title.text # type: ignore


        # print(element)


        runningTime += element["duration"] # Add new duration to runningTime
        Directory.append(element)
else:
    print("No program found")
    exit()

for element in Directory:
    # create path from element["source"]
    pth = path.basename(element["source"])

    with open(f"out/index/{pth}.html", "w") as f:
        f.write(SHOWTEMPLATE.format(
            title=element["title"],
            description=element["description"],
            poster=element["poster"],
            img=IMGTEMPLATE.format(
                poster=element["poster"],
                title=element["title"]
            ) if element["poster"] != "" else "", # only add a poster if one exists
        ))
    print(f"{element['title']} click-through page created")


# generate main index:

itemlist = ""

for element in Directory:
    pth = path.basename(element["source"])
    itemlist += LINEENTRY.format(
        pth=pth,
        title=element["title"],
        starttime=element["start_time"].strftime('%Y-%m-%d %H:%M'),
        duration=element["duration"] // 60,
    )


with open("out/index.html", "w") as f:
    f.write(INDEX.format(list=itemlist))
