from datetime import datetime as dt

import pandas_datareader as pdr
from dash.dependencies import Input
from dash.dependencies import Output
import dash
import pandas as pd
import plotly.graph_objs as go


df = pd.read_csv(
    'https://gist.githubusercontent.com/chriddyp/'
    'cb5392c35661370d95f300086accea51/raw/'
    '8e0768211f6b747c0db42a9ce9a0937dafcbd8b2/'
    'indicators.csv')




def register_callbacks(app):
    @app.callback(
        dash.dependencies.Output('crossfilter-indicator-scatter', 'figure'),
        [dash.dependencies.Input('crossfilter-xaxis-column', 'value'),
         dash.dependencies.Input('crossfilter-yaxis-column', 'value'),
         dash.dependencies.Input('crossfilter-xaxis-type', 'value'),
         dash.dependencies.Input('crossfilter-yaxis-type', 'value'),
         dash.dependencies.Input('crossfilter-year--slider', 'value')])
    def update_graph(xaxis_column_name, yaxis_column_name,
                     xaxis_type, yaxis_type,
                     year_value):
        dff = df[df['Year'] == year_value]

        return {
            'data': [go.Scatter(
                x=dff[dff['Indicator Name'] == xaxis_column_name]['Value'],
                y=dff[dff['Indicator Name'] == yaxis_column_name]['Value'],
                text=dff[dff['Indicator Name'] == yaxis_column_name]['Country Name'],
                customdata=dff[dff['Indicator Name'] == yaxis_column_name]['Country Name'],
                mode='markers',
                marker={
                    'size': 15,
                    'opacity': 0.5,
                    'line': {'width': 0.5, 'color': 'white'}
                }
            )],
            'layout': go.Layout(
                xaxis={
                    'title': xaxis_column_name,
                    'type': 'linear' if xaxis_type == 'Linear' else 'log'
                },
                yaxis={
                    'title': yaxis_column_name,
                    'type': 'linear' if yaxis_type == 'Linear' else 'log'
                },
                margin={'l': 40, 'b': 30, 't': 10, 'r': 0},
                height=450,
                hovermode='closest'
            )
        }

    def create_time_series(dff, axis_type, title):
        return {
            'data': [go.Scatter(
                x=dff['Year'],
                y=dff['Value'],
                mode='lines+markers'
            )],
            'layout': {
                'height': 225,
                'margin': {'l': 20, 'b': 30, 'r': 10, 't': 10},
                'annotations': [{
                    'x': 0, 'y': 0.85, 'xanchor': 'left', 'yanchor': 'bottom',
                    'xref': 'paper', 'yref': 'paper', 'showarrow': False,
                    'align': 'left', 'bgcolor': 'rgba(255, 255, 255, 0.5)',
                    'text': title
                }],
                'yaxis': {'type': 'linear' if axis_type == 'Linear' else 'log'},
                'xaxis': {'showgrid': False}
            }
        }

    @app.callback(
        dash.dependencies.Output('x-time-series', 'figure'),
        [dash.dependencies.Input('crossfilter-indicator-scatter', 'hoverData'),
         dash.dependencies.Input('crossfilter-xaxis-column', 'value'),
         dash.dependencies.Input('crossfilter-xaxis-type', 'value')])
    def update_y_timeseries(hoverData, xaxis_column_name, axis_type):
        country_name = hoverData['points'][0]['customdata']
        dff = df[df['Country Name'] == country_name]
        dff = dff[dff['Indicator Name'] == xaxis_column_name]
        title = '<b>{}</b><br>{}'.format(country_name, xaxis_column_name)
        return create_time_series(dff, axis_type, title)

    @app.callback(
        dash.dependencies.Output('y-time-series', 'figure'),
        [dash.dependencies.Input('crossfilter-indicator-scatter', 'hoverData'),
         dash.dependencies.Input('crossfilter-yaxis-column', 'value'),
         dash.dependencies.Input('crossfilter-yaxis-type', 'value')])
    def update_x_timeseries(hoverData, yaxis_column_name, axis_type):
        dff = df[df['Country Name'] == hoverData['points'][0]['customdata']]
        dff = dff[dff['Indicator Name'] == yaxis_column_name]
        return create_time_series(dff, axis_type, yaxis_column_name)