import dataiku
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
import dash_table
import pandas as pd
import regex as re
from dku_utils.core import get_current_project_and_variables
from dku_utils.folders.pickles.folder_pickles import read_pickle_from_managed_folder

project, variables = get_current_project_and_variables()

# use the style of examples on the Plotly documentation
app.config.external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

# url, root-url and first-loading are used for routing
url_bar_and_content_div = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='root-url', style={'display': 'none'}),
    html.Div(id='first-loading', style={'display': 'none'}),
    html.Div(id='page-content')
])

layout_index = html.Div([
    dcc.Link('Navigate to "page-1"', href='page-1'),
    html.Br(),
    dcc.Link('Navigate to "page-2"', href='page-2'),
])



## add dash table 

category = dataiku.Folder("category")
paths = category.list_paths_in_partition()
all_data = dict()

for path in paths:
    data = read_pickle_from_managed_folder(project, 'category', path)
    all_data[data['file_name']] = data

esg = dataiku.Dataset("keywords",ignore_flow = True)
df_esg = esg.get_dataframe()


company_list = sorted(list(set([all_data[data]['name'] for data in all_data.keys()])))

category_list = sorted(list(set([element for data in all_data.keys() for element in list(all_data[data]['key_word_category_dict'].keys())])))

def make_dictionary(company_list):
    options = []
    for company in company_list:
        options.append({'label': company,'value': company})
    return options   

def find_average(result_dict,key):
    total = 0
    i = 0
    sentiment_list = []
    for item in result_dict[key]:
        sentiment_list.append(item[3])
        total = total + item[2]
        i = i + 1
    return round(total / i,2), max(set(sentiment_list), key=sentiment_list.count)#mode(sentiment_list)
        
layout_page_1 = html.Div([
    html.P('Select a company...'),
    dcc.Dropdown(
        id = 'company',
        options = make_dictionary(company_list)),
    html.P('Select a category...'),
    dcc.Dropdown(
        id = 'category-list',
        options = make_dictionary(category_list),
    multi = True),
    html.Br(),
    html.Button(id='submit-button', n_clicks=0, children='Submit'),
    html.A(html.Button('Clear'), style = {"margin-left": "5px"},href='page-1'),
    html.Br(),
    html.Br(),
    html.Div(id='output-state'),
    html.Br(),
    html.Div(id='drilldown-output'),
    html.Br(),
])

# index layout
app.layout = layout_page_1

# Page 1 callbacks
@app.callback(Output('output-state', 'children'),
              [Input('submit-button', 'n_clicks')],
              [State('company', 'value'),
               State('category-list', 'value')])
def update_output(n_clicks, company, category_list):
    if n_clicks is None:
        raise PreventUpdate
    if n_clicks == 0:
        raise PreventUpdate
    result_df = pd.DataFrame(columns = ['Document Name','Category','Keyword', 'Count', 'Average Sentiment', 'Average Sentiment Score'])
    for category in category_list:
        file_names = [data for data in all_data.keys() if all_data[data]['name'] == company]
        for files in file_names:
            result_dict = all_data[files]['key_word_category_dict'].get(category)
            if result_dict is not None:
                keys = result_dict.keys()
                for key in keys:
                    avg_sentiment, top_sentiment = find_average(result_dict,key)
                    result_df = result_df.append({'Document Name' : files,
                                                      'Category': category, 'Keyword': key, 
                                                      'Count' : len(result_dict[key]), 
                                                      'Average Sentiment' : top_sentiment, 
                                                      'Average Sentiment Score' : avg_sentiment},ignore_index = True)
    return html.Div([dash_table.DataTable(
            id='output-table',
            style_data={
                'whiteSpace': 'normal',
            },
    columns=[{"name": i, "id": i,"type" : "text", "presentation": "markdown"} for i in result_df.columns],
    style_header = {'backgroundColor' : 'rgb(0, 178, 169)', 'font-family': 'sans-serif', 'color': 'white', 'text-align': 'center'},
    data=result_df.to_dict('records'), css=[{
        'selector': '.dash-spreadsheet td div',
        'rule': '''
            line-height: 15px;
            height: auto; width: auto;
            display: block;
            text-align: center;
        '''}]),html.Br(),html.P('Drill down to a sub category'),
    dcc.Dropdown(
        id = 'sub-category-list',
        options = make_dictionary(list(result_df['Keyword'].unique()))
    ,
    multi = True),
    html.Br(),
    html.Button(id='submit-button-drill-down', n_clicks=0, children='Drill down'), html.A(html.Button('Clear'), style = {"margin-left": "5px"},href='page-1')])

@app.callback(Output('drilldown-output', 'children'),
              [Input('submit-button-drill-down', 'n_clicks')],
              [State('company', 'value'),
               State('category-list', 'value'),
              State('sub-category-list','value')])
def drilldown(n_clicks, company, category_list, sub_category_list):
    if n_clicks is None:
        raise PreventUpdate
    if n_clicks == 0:
        raise PreventUpdate
    result_df = pd.DataFrame(columns = ['Category','Keyword', 
                                        'Location', 'Sentiment Score', 'Sentiment', 'Result'])
    for category in category_list:
        file_names = [data for data in all_data.keys() if all_data[data]['name'] == company]
        for files in file_names:
            result_dict = all_data[files]['key_word_category_dict'].get(category)
            if result_dict is not None:
                for sub_category in sub_category_list:
                    if sub_category in result_dict.keys():
                        item_list = result_dict[sub_category]
                        for item in item_list:
                            result_df = result_df.append({'Category': category, 'Keyword': "**" + sub_category + "**", #'Count' : len(result_dict[sub_category]), 
                                                                  ## to be updated with file name from prepare recipe
                                                                 # 'Document' : df['ticker'][df.ticker == ticker].item(), 
                                                                  'Location' : item[0],
                                                                  'Sentiment Score': round(item[2],2), 
                                                                  'Sentiment': item[3], 
                                                                  'Result': re.sub(r"\b%s[a-z]+\b" % sub_category, "**" + sub_category + "**", item[1])}, ignore_index = True)
    return html.Div([dash_table.DataTable(
            id='drilldown-table',
            style_data={
                'whiteSpace': 'normal',
            },
    columns=[{"name": i, "id": i, "type" : "text", "presentation": "markdown"} for i in result_df.columns],
    data=result_df.to_dict('records'), 
                    css=[{
        'selector': '.dash-spreadsheet td div',
        'rule': '''
            line-height: 15px;
            height: auto; width: auto%;
            display: block;
            overflow-y: hidden;
            text-align: center;
        '''
    }],
    style_cell_conditional=[
        {
            'if': {'column_id': 'Document Name'},
              'textOverflow': 'ellipsis',         
        }],
    tooltip_data=[
        {
            column: {'value': str(value), 'type': 'markdown'}
            for column, value in row.items()
        } for row in result_df.to_dict('records')
    ],
    tooltip_duration=None,
    style_header = {'backgroundColor' : 'rgb(0, 178, 169)', 'font-family': 'sans-serif', 'color': 'white', 'text-align': 'center'},
   )])

