#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" Dash Server """

import dash_bootstrap_components as dbc
from dash import dcc
from dash import html

from datetime import datetime as dt
from datetime import timedelta

from data_handler import FREQ
from data_handler import DEBUG
from data_handler import STYLES
from data_handler import START_DATE, END_DATE, DELAY
from data_handler import WAS
from data_handler import DISCLAIMER_MODELS


FORECAST_DAYS = [
        (dt.strptime(END_DATE, "%Y%m%d") +
            timedelta(days=idx)).strftime("%a %d").upper()
        for idx in range(3)
    ]

def layout_view():
    """ Return the menu for the various mapview types"""

    return html.Div([
        html.Span(
            dbc.DropdownMenu(
                id='map-view-dropdown',
                label='VIEW',
                children=[
                    dbc.DropdownMenuItem(
                        STYLES[style]['name'],
                        id=dict(
                            tag='view-style',
                            index=style
                            ),
                        active=active
                        )
                    for style, active in zip(list(STYLES.keys()), [True if i == 'carto-positron'
                                                                   else False for i in STYLES])
                    ],
                direction="up",
                in_navbar=True,
                ),
            )
        ],
                           id='map-view-dropdown-div')

def time_series():
    """ Return the timeseries element"""
    return html.Div(
            id='open-timeseries',
            children=[
                dbc.Spinner(
                    id='loading-ts-modal',
                    fullscreen=True,
                    fullscreen_style={'opacity': '0.5', 'zIndex' : '200000'},
                    show_initially=False,
                    # debounce=200,
                    children=[
                        dbc.Modal([],
                                  id='ts-modal',
                                  size='xl',
                                  centered=True,
                                  is_open=False,
                                  ),
                        ],
                    )],
                #style={'display': 'none'},
                )

def layout_layers():
    return html.Div([
        html.Span(
            dbc.DropdownMenu(
                id='map-layers-dropdown',
                label='LAYERS',
                children=[
                    dbc.DropdownMenuItem('AIRPORTS', id='airports')
                    ],
                direction="up",
                ),
            )])

def gen_ts_marks(ts_type, tstep, ts_min):
    """ Generate time slider marks """

    if DEBUG: print("TS MARKS", ts_type, tstep, ts_min)

    if ts_type in ('prob', 'was'):
        return FORECAST_DAYS[tstep-ts_min]

    if DEBUG: print("RET", f'{tstep:d}')
    return f'{tstep:d}'

def gen_time_slider(ts_type='prob', start_date=START_DATE, end_date=END_DATE):
    """ Generate time slider according to the section """

    ts_dict = {
        'model':
        {
            'min': 0,
            'max': 72,
            'step': FREQ,
            'play': True
        },
        'prob':
        {
            'min': 0,
            'max': len(FORECAST_DAYS)-1,
            'step': 1,
            'play': False
        },
        'was':
        {
            'min': 0,
            'max': len(FORECAST_DAYS)-1,
            'step': 1,
            'play': False
        },
    }

    ts_min = ts_dict[ts_type]['min']
    ts_max = ts_dict[ts_type]['max']
    ts_step = ts_dict[ts_type]['step']
    ts_play = ts_dict[ts_type]['play']

    date_picker = html.Span(
        dcc.DatePickerSingle(
            id=f'{ts_type}-date-picker',
            min_date_allowed=dt.strptime(start_date, "%Y%m%d"),
            max_date_allowed=dt.strptime(end_date, "%Y%m%d"),
            initial_visible_month=dt.strptime(end_date, "%Y%m%d"),
            display_format='DD MMM YYYY',
            date=end_date,
            clearable=True,
            placeholder='DD MON YYYY',
            reopen_calendar_on_clear=True,
            ),
        className="timesliderline",
        )

    play_button = html.Span(
        children=[
            html.Button(title='Play',
                        id='btn-play', n_clicks=0,
                        className='fa fa-play text-center'),
            ],
        className="timesliderline anim-buttons",
        )

    marks = {
            tstep: {'label': gen_ts_marks(ts_type, tstep, ts_min)}
        for tstep in range(ts_min, ts_max+ts_step, ts_step)
        }
    if DEBUG: print("FCST MARKS", marks[list(marks.keys())[-1]])
    if ts_type in ('prob', 'was'):
        marks[list(marks.keys())[-1]]['style'] = {}
        marks[list(marks.keys())[-1]]['style']['left'] = ''
        marks[list(marks.keys())[-1]]['style']['right'] = '-40px'

    time_slider = html.Span(
        dcc.Slider(
            id=f'{ts_type}-slider-graph',
            min=ts_min, max=ts_max, step=ts_step, value=ts_min,
            marks=marks            ),
        className="timesliderline",
        )

    if DEBUG: print("TIME SLIDER", time_slider)

    if ts_play:
        return html.Div([
            date_picker,
            play_button,
            time_slider
            ],
            className="timeslider"
        )

    return html.Div([
        date_picker,
        time_slider
        ],
        className="timeslider"
    )

def models_children(start_date=START_DATE, end_date=END_DATE):
    """ Return the html for models maps """
    return [
            html.Div(
                id=dict(
                    tag='tab-name',
                    index='models',
                    )
                ),
            dbc.Alert(
                "To explore the forecast, please select a variable and click on APPLY.",
                id="alert-forecast",
                is_open=True,
                duration=6000,
                fade=True,
                color="primary",
                style={ 'overflow': 'auto', 'marginBottom': 0 }
                ),
            html.Div(
                id='div-collection',
    #            children=[dbc.Spinner(
    #            id='loading-graph-collection',
    #            #debounce=10,
    #            show_initially=False,
                children=[
                    dbc.Container(
                        id='graph-collection',
                        children=[
                        ],
                        fluid=True,
                        ),
                    html.Div(DISCLAIMER_MODELS,
                             className='disclaimer'),
                   ]
    #            )],
            ),
            html.Div(
                [dcc.Store(id="model-clicked-coords"),
                 dcc.Store(id="current-popups-stored")]
            ),
            html.Div(
                dcc.Interval(id='slider-interval',
                    interval=1000,
                    n_intervals=0,
                    disabled=True
            )),
            dbc.NavbarSimple([
                html.Div([
                    gen_time_slider('model', start_date=START_DATE, end_date=end_date),
                    layout_view(),
                    time_series(),
                    # layout_layers(),
                    ],
                         id='layout-dropdown',
                         className="layout-dropdown",
                         ),
                ],
                             className='fixed-bottom navbar-timebar',
                             fluid=True,
                             expand='lg',
                             dark=True,
                             fixed='bottom',)
        ]

def prob_children(start_date=START_DATE, end_date=END_DATE):
    """ Return html for probablility maps"""
    return [
            html.Div(
                id=dict(
                    tag='tab-name',
                    index='prob',
                    )
                ),
            html.Div(
                id='prob-graph',
                className='graph-with-slider'),
            html.Div(DISCLAIMER_MODELS,
                     className='disclaimer'),
            dbc.NavbarSimple([
                html.Div([
                    gen_time_slider('prob', start_date=start_date, end_date=end_date),
                    layout_view(),
                    ],
                         id='layout-dropdown',
                         className="layout-dropdown",
                         ),
                    ],
                    className='fixed-bottom navbar-timebar',
                    fluid=True,
                    expand='lg',
                    dark=True,
                    fixed='bottom',
                )
            ]

def was_children(start_date=START_DATE, end_date=END_DATE):
    """ Return html for WAS maps"""
    return [
            html.Div(
                id=dict(
                    tag='tab-name',
                    index='was',
                    )
                ),
            dbc.Spinner(
                html.Div(
                    children=[
                        html.Div(
                            id="{'index':'None', 'tag': 'empty-map'}")
                        ],
                    id='was-graph',
                    className='graph-with-slider'),
                ),
            html.Div(DISCLAIMER_MODELS,
                     className='disclaimer'),
            dbc.NavbarSimple([
                html.Div([
                    gen_time_slider('was', start_date=start_date, end_date=end_date),
                    layout_view(),
                    ],
                         id='layout-dropdown',
                         className="layout-dropdown",
                         ),
                    ],
                    className='fixed-bottom navbar-timebar',
                    fluid=True,
                    expand='lg',
                    dark=True,
                    fixed='bottom',
                )
            ]

def tab_forecast(window='models', start_date=START_DATE, end_date=END_DATE):
    """ The MAIN function to return all appropriate html for selected tab and sidebar selection """
    windows = {
            'models': models_children(start_date=start_date, end_date=end_date),
            'was': was_children(start_date=start_date, end_date=end_date),
            'prob': prob_children(start_date=start_date, end_date=end_date),
            }

    return dcc.Tab(label='Forecast',
                   id='forecast-tab',
                   value='forecast-tab',
                   className='horizontal-menu',
                   children=windows[window],
                   )


def expand_dropdown(window):
    """ Build a dictionary to return appropriate expanded sidebar dropdown"""

    expand_dropdown = {
            'models': False, 
            'prob': False, 
            'was': False 
            }
    expand_dropdown[window]=True
    return expand_dropdown

def sidebar_forecast(variables, default_var, models, default_model, window='models', country='burkinafaso'):
    """ Build sidebar """
    #get which sidebar dropdown should be expanded for complex url search
    dropdown = expand_dropdown(window)

    return [
    html.Div([
        html.Label("Variable"),
        dcc.Dropdown(
            id='variable-dropdown-forecast',
            options=[{'label': variables[variable]['name_sidebar'],
                      'value': variable} for variable in variables],
            value=default_var,
            clearable=False,
            searchable=False,
            optionHeight=50,
            maxHeight=400
        )],
        className="sidebar-first-item",
    ),
    html.Div([
        dbc.Card([
            dbc.CardHeader(html.H2(
                dbc.Button(children=["Models",
                    html.Span(
                        html.I(className='fa fa-solid fa-angle-up'),
                        id='caret1', className="caret-span")
                    ],
                    color="link", id='group-1-toggle', className='dropdown'),
            )),
            dbc.Collapse(
                id='collapse-1',
                is_open=dropdown['models'],
                children=[
                    dbc.CardBody([
                        dbc.Checklist(
                            id='model-dropdown',
                            options=[{'label': models[model]['name'],
                                      'value': model} for model in models],
                            #value=[default_model,],
                            value=default_model,
                            className="sidebar-dropdown",
                        ),
                        html.Span([
                            html.Button('APPLY', id='models-apply', n_clicks=0),
                        ]),
                        #add hidden country fields and  button for gifs over entered coords
                        html.Span([
                            dcc.Input(id="country-zoom", type="text", style={'display':'none'}),
			    dcc.Input(id="country-lat", type="text", style={'display':'none'}),
                            dcc.Input(id="country-lon", type="text", style={'display':'none'}),
                            html.Button(id="country-focus", n_clicks=0, style={'display':'none'}),
                        ])
                        ],
                    )
                ]
            )],
        ),
        dbc.Card([
            dbc.CardHeader(html.H2(
                dbc.Button(children=["Probability of exceedance",
                    html.Span(
                        html.I(className='fa fa-solid fa-angle-up'),
                        id='caret2', className="caret-span-closed")
                    ],
                    color="link", id='group-2-toggle', className='dropdown'),
            )),
            dbc.Collapse(
                id='collapse-2',
                is_open=dropdown['prob'],
                children=[
                    dbc.CardBody([
                        dcc.RadioItems(
                            id='prob-dropdown',
                            options=[],
                            value=None,
                            className="sidebar-dropdown"
                        ),
                        html.Span([
                            html.Button('APPLY', id='prob-apply', n_clicks=0),
                        ]
                        )]
                    )
                ]
            )],
        ),
        dbc.Card([
            dbc.CardHeader(html.H2(
                dbc.Button(children=["Warning Advisory System",
                                     html.Span(
                                         html.I(className='fa fa-solid fa-angle-up'),
                                         id='caret3', className="caret-span-closed")],
                           color="link", id='group-3-toggle', className='dropdown',
                           disabled=False)
                )),
            dbc.Collapse(
                id='collapse-3',
                is_open=dropdown['was'],
                children=[
                    dbc.CardBody([
                        dcc.RadioItems(
                            id='was-dropdown',
                            options=[{'label': WAS[was]['name'],
                                      'value': was} for was in WAS],
                            value=country,
                            className="sidebar-dropdown"
                            ),
                        html.Div(
                            dcc.Store(id="was-previous"),
                            ),
                        html.Span([
                            html.Button('APPLY', id='was-apply', n_clicks=0),
                            ]
                                  )]
                                 )
                    ]
                )],
                 ),
    ],
    className="accordion"
    ),
    html.Div([
        dbc.Row([
            dbc.Col(
                dbc.Button(
                    "",
                    id="info-button",
                    ),
                width=3,
                ),
            dbc.Col(
                dbc.Button(
                    "DOWNLOAD",
                    id="download-button",
                    ),
                width=9,
                ),
            ],
                no_gutters=True,
                ),
        dbc.Row([
            dbc.Col([
                dbc.Collapse(
                    dbc.Card(dbc.CardBody(
                        [
                            dbc.Button('USER GUIDE',
                                       id='btn-userguide-download',
                                       n_clicks=0,
                                       href="https://dust.aemet.es/products/overview/user-guide/@@download",
                                       className='download-section',
                                       ),
                            html.P("""
                                   Please check out the User Guide for more information."""),
                            ],
                        className="card-text",
                        )),
                    id="info-collapse",
                    is_open=False,
                    ),
                dbc.Collapse(
                    dbc.Card(dbc.CardBody(
                        [
                            html.Label("CURRENT SELECTION"),
                            dbc.Button('PNG FRAME',
                                       id='btn-frame-download',
                                       n_clicks=0,
                                       href="#",
                                       className='download-section',
                                       ),
                            # dbc.Spinner(
                                dcc.Download(
                                    id="frame-download",
                                    base64=True,
                                    ),
                                #  ),
                            dbc.Button('GIF ANIM',
                                       id='btn-anim-download',
                                       n_clicks=0,
                                       href="#",
                                       external_link=True,
                                       target="_blank",
                                       className='download-section',
                                       ),
                            html.Label("NUMERICAL DATA"),
                            dbc.Button('NETCDF',
                                       id='btn-netcdf-download',
                                       n_clicks=0,
                                       href="/products/data-download",
                                       external_link=True,
                                       target="_blank",
                                       className='download-section',
                                       ),
                    ],
                    className="card-text",
                    )),
                id="download-collapse",
                is_open=False,
              )
            ]),
        ],
        className="collapsible-cards",
        ),
    ],
    className="sidebar-bottom",
    )
]
