"""This code defines the layout, functions, and callbacks for the Float
Viewer web page.

AUTHOR        :  Brian Ha (summer intern)
MENTOR        :  Gene Massion
MBARI TEAM    :  Chemical Sensor Group
PROJECT       :  Coastal Profiling Floats (CPF)
DATE CREATED  :  2018-06-29
LAST REVISION :  2018-07-19
"""

# 3rd Party Library Imports
# =============================================================================
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import plotly.colors as colors


# CPF MCS-Specific Imports
# =============================================================================
from gui.app import app
import gui.utils as utils
import gui.css as css


# Constants
# =============================================================================
from cpf_constants import CPF_IDs, JSON_DIRECTORY


# Functions
# =============================================================================
def create_float_dashboard(cpf_id):

    cpf_id = int(cpf_id)
    json_data = utils.get_cpf_json_from_id(cpf_id)

    all_pressure_timestamps, all_pressure_measurements = \
        utils.reconstruct_complete_pressure_history(cpf_id)

    float_dashboard = html.Div([
        html.Div([
            dcc.Graph(
                id='num_satellite_vehicles',
                figure={
                    'data': [
                        go.Bar(
                            x=json_data['Timestamps'],
                            y=json_data['Num_Satellite_Vehicles'],
                            marker={'color': colors.DEFAULT_PLOTLY_COLORS[(cpf_id-1) % 10]},
                        )
                    ],
                    'layout': go.Layout(
                        title='Number of Satellite Vehicles',
                        xaxis={'title': 'Time'},
                        yaxis={'title': ''},
                        hovermode='closest'
                    )
                },
                style=css.plot_style
            ),
        ], style={**css.float_plot_background_style, **{'width': '48.5%',
                                                        'height': '33vh',
                                                        'marginRight': '5px'}}),
        html.Div([
            dcc.Graph(
                id='signal_quality',
                figure={
                    'data': [
                        go.Scatter(
                            x=json_data['Timestamps'],
                            y=json_data['Signal_Quality'],
                            mode='lines+markers',
                            marker={'color': colors.DEFAULT_PLOTLY_COLORS[(cpf_id-1) % 10]},
                        )
                    ],
                    'layout': go.Layout(
                        title='Signal Quality',
                        xaxis={'title': 'Time'},
                        yaxis={'title': ''},
                        hovermode='closest'
                    )
                },
                style=css.plot_style
            ),
        ], style={**css.float_plot_background_style, **{'width': '48.5%',
                                                        'height': '33vh',
                                                        'marginLeft': '5px'}}),
        html.Div([
            dcc.Graph(
                id='Depth',
                figure={
                    'data': [
                        go.Scatter(
                            x=all_pressure_timestamps,
                            y=all_pressure_measurements,
                            mode='lines+markers',
                            marker={'color': colors.DEFAULT_PLOTLY_COLORS[(cpf_id-1) % 10]},
                        )
                    ],
                    'layout': go.Layout(
                        title='Pressure vs. Time',
                        xaxis={'title': 'Time'},
                        yaxis={'title': '[decibar]'},
                        hovermode='closest'
                    )
                },
                style=css.plot_style
            ),
        ], style={**css.float_plot_background_style, **{'width': '99%',
                                                        'height': '33vh'}})
    ], style={'textAlign': 'center'})
    return float_dashboard


# Page Layout
# =============================================================================
layout = html.Div([
    utils.nav_bar,
    html.H1('Float Viewer', style=css.content_heading_style),

    html.Div([
        html.H4('Select a CPF...', style={'color': 'white'}),

        dcc.Dropdown(
            id='cpf_selector',
            options=utils.cpf_dropdown
        )
    ], style={'margin': 'auto', 'width': '90vw'}),

    html.Br(),

    html.Div(id='float_dashboard_display',
             style={'margin': 'auto', 'width': '90vw'}),

], style={**css.content_page_style, **{'minHeight': '900px'}})


# Callbacks
# =============================================================================
@app.callback(Output('float_dashboard_display', 'children'),
              [Input('cpf_selector', 'value')])
def display_float_dashboard(imei_num):

    if imei_num is None:
        return None

    cpf_id = CPF_IDs[imei_num]

    try:
        float_dashboard = create_float_dashboard(cpf_id)
        return float_dashboard

    except FileNotFoundError:
        error_msg_1 = "ERROR: The .json file for CPF-{} was not found. ".format(str(cpf_id).zfill(3))
        error_msg_2 = "Please verify it exists in the {} directory.".format(JSON_DIRECTORY)
        html_error_msg = html.P(error_msg_1 + error_msg_2, style=css.html_p_error_msg_style)
        return html_error_msg
