import os
from pathlib import Path
import shutil
import re
from datetime import datetime

from jinja2 import Environment, PackageLoader, select_autoescape
import frontmatter
from slugify import slugify
import pypandoc

# TODO make newsletter URL's absolute to klank.school

env = Environment(
    loader=PackageLoader("src"),
    autoescape=select_autoescape()
)

CONTENT_D = os.path.abspath("src/content")
OUTPUT_D = "dist"
documents = {}

def listDocuments(params):
    param = params.split(" ")

    template = env.select_template([f"snippets/list-documents.jinja"])
    html = template.render(documents=documents, layout=param[0], type=param[1])

    return html


def getParam(params, index):
    if len(params) > index:
        return params[index]
    else:
        return False


def listEvents(params):
    param = params.split(" ")
    tag = getParam(param, 1)

    if "events" not in documents:
        return ""

    events = []
    if tag:
        for event in documents["events"]:
            if tag in event["tags"]:
                events.append(event)
    else:
        events = documents["events"]


    print(events)
    template = env.select_template([f"snippets/list-events.jinja"])
    html = template.render(events=events, filter=param[0], tag=getParam(param, 1))

    return html


def slugify_filter(value):
    return slugify(value)


def prettydate(value, format='%d/%m/%Y'):
    return datetime.fromtimestamp(int(value)).strftime(format)


def shortcode_filter(value):

    shortcode_callbacks = {
        "show": listDocuments,
        "events": listEvents
    }

    def shortcode_replacer(match):

        shortcode_name = match.group(1).strip()
        param = match.group(2).strip()

        if shortcode_name in shortcode_callbacks:
            return shortcode_callbacks[shortcode_name](param)

        return match.group(0)

    pattern = re.compile(r"{{\s*(\w+)\s+([^{}]+?)\s*}}")
    return pattern.sub(shortcode_replacer, value)


env.filters["shortcode"] = shortcode_filter
env.filters["slugify"] = slugify_filter
env.filters["prettydate"] = prettydate


def render_single_file(template, page, path, dist, name = False):
    modifier = False

    print(f"rendering: {path}")

    html = template.render(documents=documents, page=page, name=name)
    name = Path(path).stem

    if not os.path.exists(dist):
        os.makedirs(dist)

    with open(f"{dist}/{name}.html", "w", encoding="utf-8") as output_file:
        output_file.write(html)


def get_page_data(path, isPreload=False):
    filename = Path(path).stem

    page = frontmatter.load(path)
    page['slug'] = slugify(filename)
    page.filename = filename
    page.folder = os.path.basename(os.path.dirname(path))

    if "start_datetime" in page:
        now = datetime.now()
        page["has_passed"] = datetime.fromtimestamp(page["start_datetime"]) < now




    page.body = pypandoc.convert_text(
        page.content,
        to='html',
        format='md',
        extra_args=[
            "-N",
            "--section-divs",
            "--lua-filter=include-files.lua"
        ])


    return page


def render_posts(path):
    name = Path(path).stem
    template = env.select_template([f"{name}.jinja", "post.jinja"])

    for filename in os.listdir(path):
        if filename.endswith(".md"):
            post_path = os.path.join(path, filename)
            page = get_page_data(post_path)
            render_single_file(template, page, post_path, f"{OUTPUT_D}/{name}", name)


def preload_documents():
    print("preload any needed data")
    now = datetime.now()
    documents["meta"] = {}
    documents["meta"]["now"] = now.strftime("%d %B %Y")

    for subdir in os.listdir(CONTENT_D):
        path = os.path.join(CONTENT_D, subdir)

        if os.path.isdir(path):
            name = Path(path).stem
            if name not in documents:
                documents[name] = []

            files = os.listdir(path)
            files.sort()
            for filename in files:
                if filename.endswith(".md"):
                    post_path = os.path.join(path, filename)

                    documents[name].append(get_page_data(post_path, isPreload=True))

        elif Path(path).suffix == '.md':
            documents[Path(path).stem] = get_page_data(path, isPreload=True)


def copy_assets():
    if os.path.exists("dist/assets"):
        shutil.rmtree("dist/assets")

    shutil.copytree("src/assets", "dist/assets")

def main():
    preload_documents()



    print("render the content")
    for subdir in os.listdir(CONTENT_D):
        path = os.path.join(CONTENT_D, subdir)

        if os.path.isdir(path):
            render_posts(path)
        elif Path(path).suffix == '.md':
            template = env.select_template(
                [f"{Path(path).stem}.jinja", "post.jinja"])
            page = get_page_data(path)
            render_single_file(template, page, path, OUTPUT_D)
        elif Path(path).suffix in [".csv"]:
            print("not compiling this file!")

    copy_assets()

main()
