"""
This module contains classes help full to generate html page programmatically.

@author: VieVie31
"""
from typing import List

__all__ = ["make_html_index", "make_html_function_doc"]

class Tag:
    def __init__(self, *children, **attributes):
        self.children = children
        self.attributes = attributes

    @property
    def innerHTML(self):
        s = ""
        for c in self.children:
            s += str(s)

    def __str__(self):
        tag_name = self.__class__.__name__.lower()
        attributes = ' '.join([
            f"{a}='{self.attributes[a]}'"
            if isinstance(self.attributes[a], str) else
            f"{a}='{' '.join(map(str, self.attributes[a]))}'" 
            for a in self.attributes
        ])
        return f"<{tag_name} {attributes}>{''.join(map(str, self.children))}</{tag_name}>"

class ATag:
    def __init__(self, **attributes):
        self.attributes = attributes
    
    def __str__(self):
        tag_name = self.__class__.__name__.lower()
        attributes = ' '.join([
            f"{a}='{self.attributes[a]}'"
            if isinstance(self.attributes[a], str) else
            f"{a}='{' '.join(map(str, self.attributes[a]))}'" 
            for a in self.attributes
        ])
        return f"<{tag_name} {attributes}/>"

class FlattenStrTags:
    def __init__(self, *tags_objects):
        self.children = tags_objects
    
    def __str__(self):
        return ''.join(map(str, self.children))


class Html(Tag):
    pass

class Head(Tag):
    pass

class Title(Tag):
    pass

class Style(Tag):
    pass

class Body(Tag):
    pass

class Footer(Tag):
    pass

class H1(Tag):
    pass

class H2(Tag):
    pass

class H3(Tag):
    pass

class H4(Tag):
    pass

class H5(Tag):
    pass

class H6(Tag):
    pass

class P(Tag):
    pass

class Span(Tag):
    pass

class Div(Tag):
    pass

class Code(Tag):
    pass

class I(Tag):
    pass

class Tt(Tag):
    pass

class Script(Tag):
    pass

class A(Tag):
    pass

class Li(Tag):
    pass

class Ul(Tag):
    pass

class Details(Tag):
    pass

class Summary(Tag):
    pass

class Br(ATag):
    pass

class Img(ATag):
    pass

class Hr(ATag):
    pass


def make_html_index(modules) -> str:
    """
    Generate an HTML index page referencing all functions
    grouped by module in the API.

    :param modules: 
        defaultdict where keys are modules names
        and values list of function names
    """
    generated_index = str(Html(
        Head(Title("Index - List of all API's functions")),
        Body(
            H1("Index of functions available in the API"),
            Hr(),
            *[
                FlattenStrTags(
                    H2(m),
                    Ul(*[
                        Li(A(f, href=f"/help{f}"))
                        for f in modules[m]
                    ]),
                    Hr()
                )
                for m in modules
            ],
            Footer(
                'Generated by ★', A('bonAPIty', href='https://github.com/VieVie31/bonapity'), '★'
            )
        )
    ))
    return generated_index

def make_html_function_doc(fname, signature, docstring, python_code, js_code) -> str:
    """
    Generate the html documentation page for a given function
    """
    return str(Html(
        Head(Title(f"Documentation for : {fname}")),
        Body(
            H1(f"Documentation for : {fname}"),
            Div(H2("Signature"), I(Tt(signature))),
            Hr(),
            Div(
                H2("Description : "),
                Code(docstring, style='display:block;white-space:pre-wrap'),
                Hr()
            ),
            Div(
                H2("Generated Code"),
                "We help you by providing templates/wrappers to write the client using your API.",
                Details(
                    Summary("Python"),
                    I(Code(python_code, style='display:block;white-space:pre-wrap')),
                    "By using this decorator, all your arguments are becoming keywords arguments."
                ),
                Details(
                    Summary("Javascript"),
                    I(Code(js_code, style='display:block;white-space:pre-wrap'))
                ),
            ),
            Div(
                Hr(),
                Footer(
                    'Generated by ★', A('bonAPIty', href='https://github.com/VieVie31/bonapity'), '★'
                ),
                style="position:absolute;bottom:5;right:5;"
            )
        )
    ))
