""" Dash Server """

#import gevent.monkey
#gevent.monkey.patch_all()

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 dash.dependencies import MATCH
from dash.dependencies import ClientsideFunction
from dash.exceptions import PreventUpdate
import flask
from flask import g, make_response, request
from flask_caching import Cache
#from pyinstrument import Profiler
from pathlib import Path

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 tabs.forecast import tab_forecast
from tabs.forecast import sidebar_forecast
#from tabs.forecast_callbacks import register_callbacks as fcst_callbacks
from tabs.evaluation import tab_evaluation
from tabs.evaluation import sidebar_evaluation
#from tabs.evaluation_callbacks import register_callbacks as eval_callbacks
from tabs.observations import tab_observations
from tabs.observations import sidebar_observations
#from tabs.observations_callbacks import register_callbacks as obs_callbacks
from tabs.fullscreen import go_fullscreen 

import uuid
import socket

HOSTNAME = socket.gethostbyname_ex(socket.gethostname())[0]

if HOSTNAME in ('bscesdust03.bsc.es', 'dust.hqads.aemet.es'):
    pathname = '/daily_dashboard/'
else:
    pathname = '/dashboard/'

TIMEOUT = 10

fontawesome = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css'
leaflet = "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.2.0/leaflet.css"
# fontawesome = 'https://use.fontawesome.com/releases/v5.15.4/css/all.css'

srv = flask.Flask(__name__)
app = dash.Dash(__name__,
                external_scripts=['https://code.jquery.com/jquery-3.6.0.slim.min.js'],
                external_stylesheets=[dbc.themes.BOOTSTRAP,
                                      dbc.themes.GRID,
                                      fontawesome,
                                      leaflet
                                     ],
                url_base_pathname=pathname,
                server=srv,
                prevent_initial_callbacks=True
                )
app.css.config.serve_locally = True
app.scripts.config.serve_locally = True
app.config.suppress_callback_exceptions = True
server = app.server

from data_handler import cache, cache_timeout 
cache.init_app(server)

try:
    cache.clear()
except Exception as e:
    print('CACHE CLEAR ERROR:', str(e))
    pass

app.index_string = """
<!DOCTYPE html>
<html>
    <head>
        <script>
            L_PREFER_CANVAS=true;
            L_DISABLE_3D=true;
            L_SCROLL_WHEEL_ZOOM=false;

            HTMLCanvasElement.prototype.getContext = function(origFn) {
            return function(type, attribs) {
            attribs = attribs || {};
            attribs.preserveDrawingBuffer = true;
            return origFn.call(this, type, attribs);
             };
            }(HTMLCanvasElement.prototype.getContext);
        </script>
        <!-- Global site tag (gtag.js) - Google Analytics -->
        <!--
        <script async src="https://www.googletagmanager.com/gtag/js?id=G-5V3R8V4021"></script>
        <script>
          window.dataLayer = window.dataLayer || [];
          function gtag(){dataLayer.push(arguments);}
          gtag('js', new Date());

          gtag('config', 'G-5V3R8V4021');
        </script>
        -->
        {%metas%}
        <title>{%title%}</title>
        {%favicon%}
        {%css%}
    </head>
    <body>
        {%app_entry%}
        <footer>
            {%config%}
            {%scripts%}
            {%renderer%}
        </footer>
    </body>
</html>
"""

def get_args(url):
    """ pull all of the keyword arguments from url and update get_var dict as necessary""" 
    from data_handler import DATES
    from datetime import datetime as dt
    from datetime import timedelta
    get_var = {
            'tab':['forecast-tab'],
            'var': ['OD550_DUST'],
            'model': ['median'],
            'for_option': ['models'],
            'eval_option': ['nrt'],
            'obs_option': ['rgb'],
            'date': [DATES['end_date'] or (dt.now() - timedelta(days=1)).strftime("%Y%m%d")]
            }

    from urllib.parse import urlparse, parse_qs
    parsed_url = urlparse(url, scheme='http', allow_fragments=False)
    args = parse_qs(parsed_url[4])
    print('-------URL ARGS----', args)

    get_var.update(args)
    return get_var

#SET APP LAYOUT TO BE POPULATED
app.layout = html.Div([
    dcc.Location(id="url", refresh=False)
], id="content")

@app.callback(
    Output('app-sidebar', 'children'),
    [Input('app-tabs', 'value')],
)
def render_sidebar(tab, default_var=DEFAULT_VAR, default_model=[DEFAULT_MODEL], obs_option='rgb', 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(),
        'observations-tab' :  sidebar_observations(obs_option),
        'fullscreen-tab' : 'Full'
    }
    if tabs[tab][0] is 'Full':
        return 
    return tabs[tab]

@app.callback(
    Output("content", "children"),
    Input("url", "href")
)
def router(url):
    """ Get url search queries and build layout for app"""

    get_var = get_args(url)

    children = [
        html.Div(
            id='app-sidebar',
            children=render_sidebar(tab=get_var['tab'][0],
                default_var=get_var['var'][0],
                default_model=get_var['model'],
                obs_option=get_var['obs_option'][0],
                for_option=get_var['for_option'][0]
                ), 
            className='sidebar'
        ),
        dcc.Tabs(id='app-tabs', value=get_var['tab'][0] , children=[
            tab_forecast(window=get_var['for_option'][0], end_date=get_var['date'][0]),#'models', 'prob', 'was'
            tab_evaluation(get_var['eval_option'][0]), #nrt or scores
            tab_observations(get_var['obs_option'][0]),#rgb or visibility
            # go_fullscreen(pathname),
        ]),
    ]
    return children 

#@app.callback(
#    [Output('obs-network-dropdown', 'placeholder'),
#    Output('obs-models-dropdown', 'placeholder'),
#    Output('obs-statistics-dropdown', 'placeholder'),
#    Output('obs-timescale-dropdown', 'placeholder'),
#    Output('scores-map-apply', 'n_clicks')],
#    Input("url", "href")
#)
#def eval_scores_selector(url):
#    return 'MODIS', ['station','median'], ['bias'], 'monthly',  1
#
if DEBUG: print('SERVER: stop creating app layout')

from tabs.forecast_callbacks import *
from tabs.evaluation_callbacks import *
from tabs.observations_callbacks import *
#fcst_callbacks(app, cache=cache, cache_timeout=cache_timeout)
#eval_callbacks(app, cache=cache, cache_timeout=cache_timeout)
#obs_callbacks(app, cache=cache, cache_timeout=cache_timeout)

if __name__ == '__main__':
    app.run_server(debug=True, # use_reloader=False,  # processes=4, threaded=False,
                   host='0.0.0.0', port=7778)
