
import dash_html_components as html
#import dash_bootstrap_components as dbc
import dash_core_components as dcc
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate

from . import heatmap
from . import pca
from . import distributions
from . import hierachical_clustering
from . import plotting
from . import tools as T


_modules = [
  heatmap,
  distributions,
  pca,
  hierachical_clustering,
  plotting
]

modules = {module._label: module for module in _modules}

groupby_options = [{'label': 'Batch', 'value': 'Batch'},
                   {'label': 'Label', 'value': 'Label'},
                   {'label': 'Type',  'value': 'Type'},
                   {'label': 'Color', 'value': 'Color'}]


_layout = html.Div([
    dcc.Tabs(id='ana-secondary-tab', value=_modules[0]._label, vertical=False, 
        children=[dcc.Tab(value=key, 
                    label=modules[key]._label,
                    ) for key in modules.keys()
        ]
    ),
    
    dcc.Dropdown(id='ana-file-types', options=[], placeholder='Types of files to include', multi=True),
    dcc.Dropdown(id='ana-peak-labels-include', options=[], placeholder='Include peak_labels', multi=True),
    dcc.Dropdown(id='ana-peak-labels-exclude', options=[], placeholder='Exclude peak_labels', multi=True),    
    dcc.Dropdown(id='ana-ms-order', options=[], placeholder='MS-file sorting', multi=True),
    dcc.Dropdown(id='ana-groupby', options=groupby_options, value=None, placeholder='Group by column'),
    html.Div(id='ana-secondary-tab-content')
])


_label = 'Analysis'

_outputs = None

def layout():
    return _layout


def callbacks(app, fsc, cache):

    for module in _modules:
        func = module.callbacks
        if func is not None:
            func(app=app, fsc=fsc, cache=cache)

    @app.callback(
        Output('ana-secondary-tab-content', 'children'),
        Input('ana-secondary-tab', 'value'),
        State('wdir', 'children')
    )
    def render_content(tab, wdir):
        func = modules[tab].layout
        if func is not None:
            return func()
        else:
            raise PreventUpdate


    @app.callback(
        Output('ana-file-types', 'options'),
        Output('ana-file-types', 'value'),
        Input('tab', 'value'),
        State('wdir', 'children')
    )
    def file_types(tab, wdir):
        if tab != _label:
            raise PreventUpdate
        meta = T.get_metadata( wdir )
        if meta is None:
            raise PreventUpdate
        file_types = meta['Type'].drop_duplicates()
        options = [{'value': i, 'label': i} for i in file_types]
        return options, file_types


    @app.callback(
        Output('ana-ms-order', 'options'),
        Output('ana-groupby', 'options'),
        Input('ana-secondary-tab', 'value'),
        State('wdir', 'children')
    )
    def ms_order_options(tab, wdir):
        cols = T.get_metadata(wdir).dropna(how='all', axis=1).columns.to_list()
        if 'index' in cols: cols.remove('index')
        if 'PeakOpt' in cols: cols.remove('PeakOpt')
        options = [{'value':i, 'label': i} for i in cols]
        return options, options


    @app.callback(
        Output('ana-peak-labels-include', 'options'),
        Output('ana-peak-labels-exclude', 'options'),
        Input('tab', 'value'),
        State('wdir', 'children')
    )
    def peak_labels(tab, wdir):
        if tab != _label:
            raise PreventUpdate
        peaklist = T.get_peaklist( wdir ).reset_index()
        options = [{'value': i, 'label': i} for i in peaklist.peak_label]
        return options, options