from urllib.parse import urlparse, parse_qs
import dash
import dash_bootstrap_components as dbc
from dash import dcc
from dash import html
from dash.dependencies import Output
from dash.dependencies import Input
from dash.dependencies import State
from dash.dependencies import ALL
from data_handler import DEFAULT_VAR
from data_handler import DEFAULT_MODEL
from data_handler import VARS 
from data_handler import MODELS
from data_handler import DEBUG
from data_handler import DATES
from data_handler import cache, cache_timeout 
from data_handler import ALIASES
from data_handler import ROUTE_DEFAULTS

from tabs.forecast import tab_forecast
from tabs.forecast import sidebar_forecast
from tabs.evaluation import tab_evaluation
from tabs.evaluation import sidebar_evaluation
from tabs.observations import tab_observations
from tabs.observations import sidebar_observations
from tabs.fullscreen import go_fullscreen 

#-------------------- ADD ROUTING FUNCTIONS ----------------------
def get_input_aliases(route_selections):
    """ Change user inputs into internal variables"""
    for key, value in route_selections.items():
        #preserve the list of models by only changing the individual model name
        if key == 'model':
            route_selections[key] = ['median' if x=='multi-model' else x for x in route_selections[key]]
        elif value[0] in ALIASES:
            route_selections[key] = [ALIASES[value[0]]]
    return route_selections

def eval_section_query(queries):
    """pull SECTION var from url query and assign value to appropriate option"""
    if 'section' in queries:
        if queries['tab']==['forecast-tab']:
            queries['for_option'] = queries['section']
        elif queries['tab']==['evaluation-tab']:
            queries['eval_option'] = queries['section']
        elif queries['tab']==['observations-tab']:
            queries['obs_option'] = queries['section']
    return queries   

def get_url_queries(url, ROUTE_DEFAULTS=ROUTE_DEFAULTS):
    """ pull all of the keyword arguments from url and update ROUTE_DEFAULTS dict as necessary""" 
    parsed_url = urlparse(url, scheme='http', allow_fragments=False)
    queries = parse_qs(parsed_url[4])
    route_selections = ROUTE_DEFAULTS.copy()
    route_selections.update(queries)
    route_selections = get_input_aliases(route_selections)
    route_selections = eval_section_query(route_selections)
    return route_selections

@dash.callback(
    Output('app-sidebar', 'children'),
    [Input('app-tabs', 'value')],
    prevent_initial_call=True
)
def render_sidebar(tab='forecast-tab', route_selections=ROUTE_DEFAULTS):
    """ Function rendering requested tab """
    tabs = {
        'forecast-tab' : sidebar_forecast(VARS, route_selections['var'][0], MODELS, route_selections['model'], window=route_selections['for_option'][0], country=route_selections['country'][0]),
        'evaluation-tab' : sidebar_evaluation(route_selections['eval_option'][0]),
        'observations-tab' :  sidebar_observations(route_selections['obs_option'][0]),
        'fullscreen-tab' : 'Full'
    }
    if tabs[tab][0] is 'Full':
        return 
    return tabs[tab]

def render404():
    """Create a 404 page"""
    page = [html.Div(
            className='background',
            children=[
                html.Div(
                    id='error_div',
                    children=[html.H2('404 Error', id='error_title'),
                        html.P("Sorry we can't find the page you were looking for."),
                        html.P("Here are some helpful links that might help:"),
                        dcc.Link("Forecast", id='forecast_link', href='/dashboard/?tab=forecast', className='error_links', refresh=True),
                        #html.A("Forecast", id='forecast_link', className='error_links', n_clicks=0),
                        html.Br(),
                        html.Br(),
                        dcc.Link("Evaluation", id='evaluation_link', href='/dashboard/?tab=evaluation', className='error_links', refresh=True),
                        #html.A("Evaluation", id='evaluation_link', className='error_links', n_clicks=0),
                        html.Br(),
                        html.Br(),
                        dcc.Link("Observations", id='observations_link', href='/dashboard/?tab=observations', className='error_links', refresh=True)
#                        html.A("Observations", id='observations_link', className='error_links', n_clicks=0),
                        ],
                    )
                ]
            )
            ]
    return page

# @dash.callback(
#     Output("url", "href"),
#     Input("forecast_link", "n_clicks"),
#     Input("evaluation_link", "n_clicks"),
#     Input("observations_link", "n_clicks"),
#     prevent_initial_call=True
# )
# def something(click, eval, obs):
#     #router('/dashboard/?tab=forecast')
#     return '/dashboard/?tab=forecast'
#
@dash.callback(
    Output("content", "children"),
    Input("url", "href"),
)
def router(url):
    """ Get url search queries and build layout for app"""
    route_selections = get_url_queries(url)
    print('===== route_selections', route_selections)
    try:
        children = [
            html.Div(
                id='app-sidebar',
                children=render_sidebar(route_selections['tab'][0],
                    route_selections), 
                className='sidebar'
            ),
            dcc.Tabs(id='app-tabs', value=route_selections['tab'][0] , children=[
                tab_forecast(window=route_selections['for_option'][0], end_date=route_selections['date'][0]),#'models', 'prob', 'was'
                tab_evaluation(route_selections['eval_option'][0]), #nrt or scores
                tab_observations(route_selections['obs_option'][0]),#rgb or visibility
                # go_fullscreen(pathname),
            ]),
        ]
    except: #This handles when user inputs incorrect URL params
        children = render404()
    return children

