from .constants import IDEAL_LIFT_OR_CONFIDENCE_THRESHOLD
from ...association_rules import get_confidence_interpretation, get_lift_interpretation, get_conviction_interpretation


def open_html_tag(str_tag_type, str_html_enrichments):
    return "<{} {}>".format(str_tag_type, str_html_enrichments)


def close_html_tag(str_tag_type):
    return "</{}>".format(str_tag_type)


def generate_table_header_html(table_column_labels, columns_html_enrichments):
    """
    Generates the header of an html table, based on a list of columns.
    'table_columns' : list of strings (ie column names)
    'columns_html_enrichments' : list of strings describing html enrichments to add to columns (ex : class, id, style).
    """
    html = ""
    html += open_html_tag("thead", "")
    html += open_html_tag("tr", "")
    
    if len(columns_html_enrichments) == 0:
        columns_html_enrichments = ["" for __ in range(len(table_column_labels))]
    
    for column_label, html_enrichments in zip(table_column_labels, columns_html_enrichments):
        print(f"column_label : {column_label}")
        html += open_html_tag("th", html_enrichments)
        html += column_label
        html += close_html_tag("th")
        
    html += close_html_tag("tr")
    html += close_html_tag("thead")
    return html


def enrich_cell_data(column_name, cell_data):
    interpretation_context = "webapp"
    if column_name == "Confidence":
        cell_tooltip = get_confidence_interpretation(cell_data, interpretation_context)
        cell_tooltip += " This confidence is " 
        if cell_data < 0.3:
            cell_enrichments = 'class="bad_metric"'
            cell_tooltip += "bad."
        elif cell_data < 0.6:
            cell_enrichments = 'class="medium_metric"'
            cell_tooltip += "medium."
        elif cell_data < 0.8:
            cell_enrichments = 'class="good_metric"'
            cell_tooltip += "good."
        elif cell_data < 0.9:
            cell_enrichments = 'class="really_good_metric"'
            cell_tooltip += "really good."
        else:
            cell_enrichments = 'class="excellent_metric"'
            cell_tooltip += "excellent."
        cell_enrichments += ' style="font-weight: bolder;"'
    
    elif column_name == "Lift":
        if isinstance(cell_data, str):
            cell_enrichments = 'class="excellent_metric"'
            cell_tooltip = "With a lift > 1, using the rule seems to INCREASE the likelihood to purchase the outcome itemset. This lift is excellent."
        else:    
            cell_tooltip = get_lift_interpretation(cell_data, interpretation_context)
            cell_tooltip += " This lift is "

            if cell_data < 1:
                cell_enrichments = 'class="bad_metric"'
                cell_tooltip += "bad."
            if cell_data == 1:
                cell_enrichments = 'class="medium_metric"'
                cell_tooltip += "neutral."
            elif cell_data < 2:
                cell_enrichments = 'class="good_metric"'
                cell_tooltip += "good."
            else:
                cell_enrichments = 'class="really_good_metric"'
                cell_tooltip += "really good."
        cell_enrichments += ' style="font-weight: bolder;"'
        
    elif column_name == "Conviction":
        if isinstance(cell_data, str):
            cell_enrichments = 'class="excellent_metric"'
            cell_tooltip = "With a conviction > 1, the outcome itemset seems to be DEPENDANT on the trigger itemset. This conviction is excellent."
            
        else:    
            cell_tooltip = get_conviction_interpretation(cell_data, interpretation_context)
            cell_tooltip += " This conviction is "

            if cell_data < 1:
                cell_enrichments = 'class="bad_metric"'
                cell_tooltip += "bad."
            if cell_data == 1:
                cell_enrichments = 'class="medium_metric"'
                cell_tooltip += "neutral."
            elif cell_data < 2:
                cell_enrichments = 'class="good_metric"'
                cell_tooltip += "good."
            else:
                cell_enrichments = 'class="really_good_metric"'
                cell_tooltip += "really good."
        cell_enrichments += ' style="font-weight: bolder;"'

    else:
        cell_enrichments = ""
        cell_tooltip = ""
    return cell_enrichments, cell_tooltip


def from_dataframe_values_to_html_table(dataframe):
    """
    'dataframe' : a pandas dataframe
    """
    html = ""
    html += open_html_tag("tbody", "")
    
    dataframe_values = dataframe.values
    dataframe_columns = list(dataframe.columns)
    n_dataframe_rows = dataframe_values.shape[0]
    
    for row_values in dataframe_values:
        html += open_html_tag("tr", 'style="background-color:#FFFFFF;"')
        for column_name, cell_data in zip(dataframe_columns, row_values):
            try:
                cell_enrichments, cell_tooltip = enrich_cell_data(column_name, cell_data)
            except NameError:
                cell_enrichments = ""
                cell_tooltip = ""
                
            cell_has_tooltip = (len(cell_tooltip) > 0)
            html += open_html_tag("td", cell_enrichments)
            if cell_has_tooltip:
                html += open_html_tag("div", 'class="tooltip"')
                html += open_html_tag("span", 'class="tooltiptext"')
                html += cell_tooltip
                html += close_html_tag("span")
                
            html += str(cell_data)
            
            if cell_has_tooltip:
                html += close_html_tag("div")
                
            html += close_html_tag("td")
        html += close_html_tag("tr")
    
    html += close_html_tag("tbody")
    return html


def filter_association_rules_dataframe(dataframe, confidence_threshold, lift_threshold, conviction_threshold, support_threshold):
    dataframe = dataframe[(dataframe["rule_confidence"] >= confidence_threshold)\
                          &(dataframe["rule_lift"] >= lift_threshold)\
                          &(dataframe["rule_conviction"] >= conviction_threshold)\
                          &(dataframe["rule_support"] >= support_threshold)]
    return dataframe


def simplify_itemsets(list_of_itemset):
    return [itemset[0] if (len(itemset) == 1) else itemset for itemset in list_of_itemset]


def format_metrics(dataframe):
    for metric in ["rule_support", "rule_confidence", "rule_lift", "rule_conviction"]:
        formated_metric_values = []
        metric_values = list(dataframe[metric])
        
        for value in metric_values:
            if metric == "rule_support":
                value = round(100*value, 2)
                
            elif metric in ["rule_confidence", "rule_lift", "rule_conviction"]:
                value = round(value, 1)
                
            if metric in ["rule_lift", "rule_conviction"]:
                if value > IDEAL_LIFT_OR_CONFIDENCE_THRESHOLD:
                    value = "> {}".format(IDEAL_LIFT_OR_CONFIDENCE_THRESHOLD)
                    
            formated_metric_values.append(value)
            
        dataframe[metric] = formated_metric_values
    return dataframe