from dash import dcc

import json

from dash.dependencies import Input, Output, State
from dash import html

from .option_comps import option_comps

import sd_material_ui as smui

from app import app

from datastore import datastore

ds = datastore()


x_axis_options = []
y_axis_options = []

for index, row in ds.get_valid_axes().iterrows():
    x_axis_options.append(
        {
            'label': row['pretty_name'],
            'value': index,
            'primaryText': row['pretty_name'],
        }
    )
    y_axis_options.append(
        {
            'label': row['pretty_name'],
            'value': index,
            'primaryText': row['pretty_name']
        }
    )


layout = [
    html.Div(
        [

            html.Div(
                option_comps,
                className='flex-box',style={'margin-bottom':'0.5%'}
            ),
            html.Div(
                [
                    html.Div(
                        [
                            dcc.Graph(
                                id='main-plot',
                                config={
                                    'scrollZoom': True,
                                    'modeBarButtonsToRemove': [
                                        'select2d',
                                        'lasso2d',
                                        'autoScale2d',
                                        'toggleSpikelines',
                                        'hoverCompareCartesian'
                                    ],
                                    'responsive':True
                                }
                            )
                        ],
                        className=''
                    ),
                    html.Div(
                        id='radio-over-xray',
                        className='',
                    )
                ],
                className='flex-box-main-plot'
            ),
            smui.Dialog(id='click-info-dialog',
                        children=[
                            html.Div(id='main-info-content',
                                     className='max-width scroll max-height-500'),
                            smui.FlatButton(
                                id='close-diag', label='Close', backgroundColor='orange')
                        ],
                        modal=True, open=False, className='dialog-max-width'

                        )

        ]
    )
]

# This callback takes care of axis selection, filtering, scaling the points and assigining color codes


@app.callback(
    Output('main-plot', 'figure'),
    [
        Input('x-axis-dropdown', 'value'),
        Input('y-axis-dropdown', 'value'),
        #Input('filters-checklist', 'values'),
        Input('scaling-dropdown', 'value'),
        Input('category-color-dropdown', 'value'),
    ] +
    [
        Input(i['label'], 'checked') for i in ds.get_filters()
    ]
)
def update_axes(xaxis, yaxis, scale, cat_color, *checked_filters):

    ds.reset_filters()
    filters = ds.get_filters()
    # filter the data
    # print(checked_filters)
    # if checked_filters is not None:
    for i, is_filter_checked in enumerate(checked_filters, start=0):
        if is_filter_checked:
            attr = filters[i]['value']
            if hasattr(ds, attr):
                getattr(ds, attr)()
            else:
                print('Data store has no attribute {0}'.format(attr))

    df = ds.get_filtered_data()
    attr = ds.get_col_attributes()
    xtitle = attr[attr.index == xaxis]['pretty_name'].values[0]
    ytitle = attr[attr.index == yaxis]['pretty_name'].values[0]
    marker_options = {} if scale is None else ds.get_marker_scaling_options(
        scale)
    color_options = {} if cat_color is None else ds.get_cat_color(cat_color)
    marker_options = {**marker_options, **color_options}

    return {
        'data': [
            {
                'x': df[xaxis],
                'y':df[yaxis],
                'type':'scatter',
                'mode':'markers',
                'marker':marker_options,
                'text':df['Name']
            }
        ],
        'layout': {
            'title': {'text': xtitle+' vs. '+ytitle},
            'xaxis': {
                'title': {'text': xtitle},
                'showline': True,
                'linewidth': 4,
                'linecolor': '#636363',
                'zeroline': True
            },
            'yaxis': {
                'title': {'text': ytitle},
                'showline': True,
                'linewidth': 4,
                'linecolor': '#636363',
                'zeroline': True
            },
            'margin': {
                'l': 55,
                'b': 55,
                'r': 55,
                't':55
            },
            'clickmode': 'event',
            'hovermode': 'closest'
        }


    }

# Callback to take care of displaying the data


@app.callback(
    Output('radio-over-xray', 'children'),
    [Input('main-plot', 'hoverData'), Input('main-plot', 'relayoutData')]
)
def display_image_on_hover(hoverData, relayout):
    # return json.dumps(hoverData)
    if hoverData is not None and len(hoverData['points']) > 0:
        source = hoverData['points'][0]['text']
        df = ds.get_filtered_data()
        child = html.H3('No information is available for {0}'.format(source))
        if (df[df['Name'] == source].iloc[0])['radio_over_xray']:
            child = html.Div(
                [
                    html.Div(
                        [
                            html.H4(source)
                        ],
                        style={'text-align':'center'}
                    ),
                    html.Div(
                        [
                            html.Img(
                                src=app.get_asset_url(
                                    'data_downloads/{0}/radio_over_xray.png'.format(source)),
                                className='img-hover'

                            )
                        ],
                        style={'margin':'auto'}
                    )
                ],
                className='flex-box',
                style={'flex-direction': 'column'}
            )
        return child
    else:
        return 'Hover over any data point to display the image'


@app.callback(
    [
        Output('click-info-dialog', 'open'),
        Output('main-info-content', 'children')
    ],
    [
        Input('main-plot', 'clickData'),
        Input('close-diag', 'n_clicks'),
    ],
    [
        State('click-info-dialog', 'open')
    ]
)
def display_info_dialog(clickData, closeClick, diagOpen):

    selectedRows = []
    if closeClick and diagOpen:

        return False, ''

    #print('CLICK DATA',clickData)
    if (len(clickData['points']) > 0 or len(selectedRows) > 0) and not diagOpen:
        df = ds.get_filtered_data()
        source = ''
        radio_over_xray = False
        if (len(selectedRows) > 0):
            radio_over_xray = df.iloc[selectedRows[0]]['radio_over_xray']
        if (len(clickData['points']) > 0):
            source = clickData['points'][0]['text']
            radio_over_xray = (df[df['Name'] == source].iloc[0])[
                'radio_over_xray']
        child = html.H3('No information is available for {0}'.format(source))
        if radio_over_xray:
            child = html.Div(
                [
                    html.Div(
                        [
                            html.Img(
                                src=app.get_asset_url(
                                    'data_downloads/{0}/radio_over_xray.png'.format(source)),
                                    style={'max-height':'500px','max-width':'100%'}
                            )
                        ],
                        style={'margin': '0 auto'}
                    ),
                    html.Div(
                        [
                            html.Div(
                                [
                                    ds.get_source_table(source)
                                ]
                            )
                        ],
                        style={'margin': '0 auto'}
                    )

                ],className='flex-box',style={'flex-direction':'column'}
            )
        return True, child
