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, default_var=DEFAULT_VAR, default_model=[DEFAULT_MODEL], obs_option='rgb', eval_option='nrt', for_option='models'):
    """ Function rendering requested tab """
    tabs = {
        'forecast-tab' : sidebar_forecast(VARS, default_var, MODELS, default_model, window=for_option),
        'evaluation-tab' : sidebar_evaluation(eval_option),
        'observations-tab' :  sidebar_observations(obs_option),
        '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.Br(),
                        html.Br(),
                        dcc.Link("Evaluation", id='evaluation_link', href='/dashboard/?tab=evaluation', className='error_links', refresh=True),
                        html.Br(),
                        html.Br(),
                        dcc.Link("Observations", id='observations_link', href='/dashboard/?tab=observations', className='error_links', refresh=True)
                        ],
                    )
                ]
            )
            ]
    return page

@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(tab=route_selections['tab'][0],
                    default_var=route_selections['var'][0],
                    default_model=route_selections['model'],
                    obs_option=route_selections['obs_option'][0],
                    eval_option=route_selections['eval_option'][0],
                    for_option=route_selections['for_option'][0]
                    ), 
                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 
