"""This code defines the functions, layout, and callbacks for the Fleet
Overview 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-08-02
"""

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


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


# Constants
# =============================================================================
from cpf_constants import CPF_IDs


# Functions
# =============================================================================
def get_scatter_plot_data_for_all_floats(json_key):

    data_traces = []

    for cpf_id in list(CPF_IDs.values()):

        if json_key == 'Pressure_[decibar]':

            try:
                all_pressure_timestamps, all_pressure_measurements = \
                    utils.reconstruct_complete_pressure_history(cpf_id)
                trace = go.Scatter(
                    x=all_pressure_timestamps,
                    y=all_pressure_measurements,
                    mode='lines+markers',
                    name='CPF-' + str(cpf_id).zfill(3)
                )
                data_traces.append(trace)
            except FileNotFoundError:
                continue
        else:
            try:
                json_data = utils.get_cpf_json_from_id(cpf_id)
            except FileNotFoundError:
                continue

            try:
                trace = go.Scatter(
                    x=json_data['Timestamps'],
                    y=json_data[json_key],
                    mode='lines+markers',
                    name='CPF-' + str(cpf_id).zfill(3)
                )
                data_traces.append(trace)
            except KeyError:
                continue

    return data_traces


# Page Layout
# =============================================================================
layout = html.Div([
    utils.nav_bar,

    html.H1('Fleet Overview', style=css.content_heading_style),

    html.Br(),

    html.Div(id='fleet_overview_dashboard_div', key=1),

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


# Callbacks
# =============================================================================
@app.callback(
    Output('fleet_overview_dashboard_div', 'children'),
    [Input('fleet_overview_dashboard_div', 'key')])
def update_fleet_overview_dashboard(purposefully_unused_arg):
    """This function draws the fleet overview dashboard. It is within a
    callback so that the dashboard is updated upon page refresh."""

    fleet_overview_dashboard = [
        html.Div([
            html.Div([
                dcc.Graph(
                    id='battery_voltage',
                    figure={
                        'data': get_scatter_plot_data_for_all_floats(
                            'Battery_Bus_Voltage_[volts]'),

                        'layout': go.Layout(
                            title='Battery Bus Voltage',
                            xaxis={'title': 'Time'},
                            yaxis={'title': '[Volts]'},
                            hovermode='closest',
                            showlegend=True,
                        )
                    },
                    style=css.plot_style
                ),
            ], style={**css.fleet_plot_background_style, **{'marginRight': '10px'}}),
            html.Div([
                dcc.Graph(
                    id='Depth',
                    figure={
                        'data': get_scatter_plot_data_for_all_floats(
                            'Pressure_[decibar]'),
                        'layout': go.Layout(
                            title='Pressure vs. Time',
                            xaxis={'title': 'Time'},
                            yaxis={'title': '[decibar]'},
                            hovermode='closest',
                            showlegend=True,
                        )
                    },
                    style=css.plot_style
                ),
            ], style=css.fleet_plot_background_style)
        ], id='Upper_Dashboard_Grid', style={'margin': 'auto', 'width': '90vw'}),

        html.Div([
            html.Div([
                dcc.Graph(
                    id='Can_Pressure',
                    figure={
                        'data': get_scatter_plot_data_for_all_floats(
                            'Can_Pressure_[millibar]'),
                        'layout': go.Layout(
                            title='Can Pressure',
                            xaxis={'title': 'Time'},
                            yaxis={'title': '[millibar]'},
                            hovermode='closest',
                            showlegend=True,
                        )
                    },
                    style=css.plot_style
                ),
            ], style={**css.fleet_plot_background_style, **{'marginRight': '10px'}}),

            html.Div([
                dcc.Graph(
                    id='Can_Humidity',
                    figure={
                        'data': get_scatter_plot_data_for_all_floats(
                            'Can_Humidity_[rel_%]'),
                        'layout': go.Layout(
                            title='Can Humidity',
                            xaxis={'title': 'Time'},
                            yaxis={'title': '[Relative %]'},
                            hovermode='closest',
                            showlegend=True,
                        )
                    },
                    style=css.plot_style
                ),
            ], style=css.fleet_plot_background_style)
        ], id='Lower_Dashboard_Grid', style={'margin': 'auto', 'width': '90vw'})]

    return fleet_overview_dashboard
