# d_and_h.py

# import html_and_py to create HTML
from html_and_py import *
from modules.d_ht_convert_rows import convert_dict_rows_into_table_rows


# ###########################
# # strategy_keys.py
# ###########################
# def attribute_strategy_for_key(key,
#                                key_strategy: dict = None) -> dict:
#     attributes = {}
#
#     if key_strategy is None:
#         # print("default key strategy", len([key]))
#         len([key])  # just to avoid triggering warnings
#     else:
#         ##
#         # Example of strategy
#         ##
#         # if type(key) == float:
#         #     attributes.update({
#         #         'style': 'font-style: italic;'
#         #     })
#         # else:
#         #     print("Not float: %s" % key)
#         pass
#
#     return attributes
# ###########################
# # strategy_keys.py
# ###########################


# ###########################
# # strategy_values.py
# ###########################
# def attribute_strategy_for_value(value,
#                                  value_strategy: dict = None) -> dict:
#     attributes = {}
#
#     if value_strategy is None:
#         # print("default value strategy", len([value]))
#         len([value])  # just to avoid triggering warnings
#     else:
#         ##
#         # Example of strategy
#         ##
#         # if type(value) == float:
#         #     attributes.update({
#         #         'style': 'font-style: italic;'
#         #     })
#         # else:
#         #     print("Not float: %s" % value)
#         pass
#
#     return attributes
# ###########################
# # strategy_value.py
# ###########################


# ##########################
# d_ht_convert_rows.py
# ##########################
# Is it possible to inherit html_and_py from dict_and_html?
# import html_and_py for creating HTML
# import strategies to extend behavior
# from html_and_py import *
# from strategy_keys import attribute_strategy_for_key
# from strategy_values import attribute_strategy_for_value
# ##########################
# d_ht_convert_rows.py
# ##########################

DOCTYPE = init_doctype("html")
TABLE_STYLE = """table,
table * {
  border: solid black 1px;
  border-collapse: collapse;
}"""
HTML_STYLE = create_html({
    'tag': 'style',
    'text': TABLE_STYLE
})


# ###########################
# # d_ht_convert_rows.py
# ###########################
# # Based on previous analysis, this is another independent module that prints
# # a Python dict as <tr> rows of an HTML <table>, eventually with nested
# # <table>'s As it turns out, this is a headless <table>, meaning that there
# # is a wrapper <table> (with <thead> and <tbody>), written before this
# # module. Currently, d_and_h.py calls
# # convert_dict_rows_into_table_rows and saves its output in a <tbody> element.
# # Other projects can benefit from this package by specifying custom
# # strategies of conversion of keys and values. For example, adding id's and
# # href's based on certain rules. It can be added with an "attribute strategy
# # for keys and values", which is an application of the strategy design
# # pattern.  According to this, I could extend the functionality of the code
# # that brings table rows to life, specifically table columns for each row.
# # Attributes will be set according to the output from the "attribute
# # strategy". The context for the strategy are the keys and values of the
# # dictionary being converted into table, so these need to be passed. It can
# # be split into strategy for keys and strategy for values. This way,
# # there are two, smaller contexts. For example, each attribute strategy
# # outputs a dictionary object that describes a set of HTML attributes. In
# # this example, an id and a href attribute could be set based on the context
# # for the key and the value respectively.
# def convert_dict_rows_into_table_rows(source_dictionary: dict,
#                                       attribute_strategies: dict = None
#                                       ) -> [dict]:
#     ##
#     # Walk through the source dictionary collecting keys and values
#     # - For each key, add <tr><td>
#     # - For each value,
#     #    if value is a singleton, <td> is populated with the value
#     #    if value is a nested dict, <td> is populated with a new <table> and a
#     #     sub-processing of its keys and values takes place recursively
#     #
#     # To solve this problem recursively, we need this method to convert each
#     # key-value pair of a source dictionary into just the following HTML:
#     #   <tr> <td> KEY </td>   <td> VALUE </td> </tr>
#     #
#     # For nested tables, spawn a new <table> inside the VALUE <td></td>:
#     #   <tr>
#     #     <td> KEY </td>
#     #     <td>
#     #     <table> VALUE </table>
#     #     </td>
#     #   </tr>
#     ##
#     output_rows = []
#     for dict_key, dict_value in source_dictionary.items():
#         value_children_table = []
#         value_children_text = ''
#         if type(dict_value) == dict:
#             # print("We have a nested dictionary")
#             value_children_table.append(create_html({
#                 'tag': 'table',
#                 'children': convert_dict_rows_into_table_rows(dict_value)
#             }))
#         else:
#             # print("We have a singleton value")
#             value_children_text = dict_value
#
#         # Attribute strategy design pattern
#         key_attributes = attribute_strategy_for_key(
#             dict_key,
#             key_strategy=attribute_strategies
#         )
#         value_attributes = attribute_strategy_for_value(
#             dict_value,
#             value_strategy=attribute_strategies
#         )
#
#         key_column = create_html({
#             'tag': 'td',
#             'attributes': key_attributes,
#             'text': dict_key
#         })
#         value_column = create_html({
#             'tag': 'td',
#             'attributes': value_attributes,
#             'children': value_children_table,
#             'text': value_children_text
#         })
#         current_table_row = create_html({
#             'tag': 'tr',
#             'children': [
#                 key_column,
#                 value_column
#             ]
#         })
#         output_rows.append(current_table_row)
#         # print("Current row:")
#         # print(current_table_row)
#
#     return output_rows
# ###########################
# # d_ht_convert_rows.py
# ###########################


def dict_and_html(source_dictionary: dict,
                  table_root_name: str = 'Dict And Html Table',
                  attribute_strategies: dict = None) -> str:
    """
    It converts the source_dictionary into an HTML table, wrapping it in a
    complete HTML page. If a name is passed to table_root_name, it will be
    printed in the header <thead> of the table. It can be passed a set of
    strategies in attribute_strategies to include additional processing in
    the conversion of the key-value pair from the source_dictionary into a
    row of the HTML table. All that needs to be done to enable this feature
    is to pass an extra argument to dict_and_html to specify the strategies
    to apply. These strategies have not been coded yet.

    :param source_dictionary: Input Python dictionary
    :param table_root_name: Text for the header of the HTML table
    :param attribute_strategies: Python dictionary to select a strategy of
    processing for key-value pairs in the source_dictionary
    :return: An HTML-formatted string representing an HTML page containing the
    table conversion of the source_dictionary
    """
    output = "" + DOCTYPE

    table_children = []
    table_header = create_html({
        'tag': 'thead',
        'children': [
            create_html({
                'tag': 'tr',
                'children': [
                    create_html({
                        'tag': 'th',
                        'text': table_root_name
                    })
                ]
            })
        ]
    })
    table_children.append(table_header)
    table_body = create_html({
        'tag': 'tbody',
        'children': convert_dict_rows_into_table_rows(
            source_dictionary,
            attribute_strategies
        )
    })
    table_children.append(table_body)

    # print(table_header)
    # print(table_body)

    html_page = create_html({
        'tag': 'html',
        'children': [
            create_html({
                'tag': 'head',
                'children': [HTML_STYLE]
            }),  # head
            create_html({
                'tag': 'body',
                'children': [
                    create_html({
                        'tag': 'table',
                        'children': [
                            table_header,
                            table_body
                        ]
                    })  # table
                ]
            })  # body
        ]
    })

    # print("  >>  Printing html_page")
    # print(html_page)
    # print("  >>  Rendering html_page")
    # print(render_html(html_page))

    output += render_html(html_page)
    return output
