import pytest
from datetime import datetime
from datetime import timedelta
import importlib
map_handler = importlib.import_module('map_handler')
timeseries_handler = importlib.import_module('timeseries_handler')
from map_handler import END_DATE
from map_handler import FREQ

FMT_ISO = "%Y%m%d"
FMT_DASH = "%Y-%m-%d"
FMT_MON = "%d %b %Y"
EDATE_OBJ = datetime.strptime(END_DATE, FMT_ISO)
EDATE_PREV = (datetime.strptime(END_DATE, FMT_ISO) - timedelta(days=7)).strftime(FMT_ISO)

# =================== AERONET OBSERVATIONS HANDLER ============================
@pytest.fixture
def EvaluationGroundFigureHandler():
    return map_handler.EvaluationGroundFigureHandler(sdate=EDATE_PREV, edate=END_DATE , obs='aeronet', 
                                                      var='OD550_DUST') 

def test_aeronet_get_figure_layers(EvaluationGroundFigureHandler):

    EvaluationGroundFigureHandler.get_figure_layers()
    assert str(type(EvaluationGroundFigureHandler.geojson)) == "<class 'dash_leaflet.GeoJSON.GeoJSON'>"

# =================== TIME SERIES HANDLER ============================
@pytest.fixture
def TSHandler():
    return timeseries_handler.ForecastModelsTimeSeriesHandler('median', END_DATE, 'OD550_DUST')

def test_TimeSeriesHandler_retrieve_single_point(TSHandler):
    run = TSHandler.retrieve_single_point(1, 45, 45, model='median')
    assert float(run) == 0.13055419921875

def test_TimeSeriesHandler_retrieve_single_point_1(TSHandler):
    run = TSHandler.retrieve_single_point(3, 5, 5, model=None)
    assert float(run) == 0.32350343465805054

def test_retrieve_timeseries(TSHandler):
    run = TSHandler.retrieve_timeseries(5, 5, model=None, method='netcdf', forecast=False)
    assert run.layout.title.text =='Dust Optical Depth @ lat = 5 and lon = 5'

def test_retrieve_timeseries_1(TSHandler):
    run = TSHandler.retrieve_timeseries(35, 15, model='monarch', method='netcdf', forecast=True)
    assert run.layout.title.text =='Dust Optical Depth @ lat = 35 and lon = 15'

def test_retrieve_timeseries_2(TSHandler):
    run = TSHandler.retrieve_timeseries(35, 15, model='monarch', method='netcdf', forecast=True)
    assert run.layout.title.text =='Dust Optical Depth @ lat = 35 and lon = 15'

# =================== Evaluation Statistics Figure Handler ============================
@pytest.fixture
def EvaluationStatisticsFigureHandler():
    return map_handler.EvaluationStatisticsFigureHandler('aeronet', 'bias', 'median', '{edate}'.format(edate=EDATE_OBJ.strftime("%Y%m")))

# =================== Visibility Figure Handler ============================
@pytest.fixture
def VisFigureHandler():
    return map_handler.VisFigureHandler(selected_date=END_DATE)

def test_vis_get_figure_layers_empty(VisFigureHandler):
    VisFigureHandler.path_tpl = "fakepath"
    VisFigureHandler.get_figure_layers(tstep=0)
    assert VisFigureHandler.info.id == 'vis-info'
    assert str(VisFigureHandler.info.children) == "P(B('DATA NOT AVAILABLE'))"

def test_vis_get_figure_layers(VisFigureHandler):
    VisFigureHandler.get_figure_layers(tstep=0)
    assert str(type(VisFigureHandler.geojson)) == "<class 'dash_leaflet.GeoJSON.GeoJSON'>"

def test_vis_get_title(VisFigureHandler):
    assert str(VisFigureHandler.get_title(tstep=0)) == "Visibility reduced by airborne dust<br>{edate} 00-06 UTC".format(edate=EDATE_OBJ.strftime(FMT_MON))
    assert str(VisFigureHandler.get_title(tstep=9)) == "Visibility reduced by airborne dust<br>{edate} 09-15 UTC".format(edate=EDATE_OBJ.strftime(FMT_MON))
    assert str(VisFigureHandler.get_title(tstep=39)) == "Visibility reduced by airborne dust<br>{edate} 39-45 UTC".format(edate=EDATE_OBJ.strftime(FMT_MON))
    assert str(VisFigureHandler.get_title(tstep=72)) == "Visibility reduced by airborne dust<br>{edate} 72-78 UTC".format(edate=EDATE_OBJ.strftime(FMT_MON))

# =================== Prob Handler ============================
@pytest.fixture
def ForecastProbFigureHandler():
    ForecastProbFigureHandler_OD550_DUST = map_handler.ForecastProbFigureHandler(var='OD550_DUST', prob=0.1, selected_date=END_DATE)
    ForecastProbFigureHandler_SCONC_DUST = map_handler.ForecastProbFigureHandler(var='SCONC_DUST', prob=50, selected_date=END_DATE)
    return ForecastProbFigureHandler_OD550_DUST, ForecastProbFigureHandler_SCONC_DUST

# def test_prob_set_data(ForecastProbFigureHandler):
#     assert ForecastProbFigureHandler[0].set_data(tstep=0)[0].data[0] == -24.75
#     assert ForecastProbFigureHandler[0].set_data(tstep=0)[0].data[9] == -20.25
#     assert ForecastProbFigureHandler[0].set_data(tstep=0)[1].data[9] == 5.25

def test_prob_retrieve_cdatetime(ForecastProbFigureHandler):
    assert str(ForecastProbFigureHandler[0].retrieve_cdatetime(tstep=0)) == '{edate} 00:00:00'.format(edate=EDATE_OBJ.strftime(FMT_DASH))
    assert str(ForecastProbFigureHandler[0].retrieve_cdatetime(tstep=1)) == '{edate} 00:00:00'.format(edate=(EDATE_OBJ + timedelta(days=1)).strftime(FMT_DASH))

def test_prob_get_title(ForecastProbFigureHandler):
    assert ForecastProbFigureHandler[0].get_title(tstep=0)[-30:] == '{edate} Valid: {edate}'.format(edate=EDATE_OBJ.strftime(FMT_MON))
    assert ForecastProbFigureHandler[1].get_title(tstep=1)[-30:] == '{edate} Valid: {edate_next}'.format(edate=EDATE_OBJ.strftime(FMT_MON), edate_next=(EDATE_OBJ + timedelta(days=1)).strftime(FMT_MON))

def test_prob_get_figure_layers(ForecastProbFigureHandler):
    # day 0 for od550_dust
    ForecastProbFigureHandler[0].get_figure_layers(day=0)
    assert ForecastProbFigureHandler[0].geojson.url == '/dashboard/assets/geojsons/prob/od550_dust/0.1/geojson/{edate}/00_{edate}_OD550_DUST.geojson'.format(edate=END_DATE)
    assert ForecastProbFigureHandler[0].geojson.options == {'style': {'variable': 'forecastTab.forecastMaps.styleHandle'}}
    
    # day 1 for od550_dust
    ForecastProbFigureHandler[0].get_figure_layers(day=1)
    assert ForecastProbFigureHandler[0].geojson.url =='/dashboard/assets/geojsons/prob/od550_dust/0.1/geojson/{edate}/01_{edate}_OD550_DUST.geojson'.format(edate=END_DATE)
    assert ForecastProbFigureHandler[0].geojson.options == {'style': {'variable': 'forecastTab.forecastMaps.styleHandle'}}

    # day 0 for sconc_dust
    ForecastProbFigureHandler[1].get_figure_layers(day=0)
    assert ForecastProbFigureHandler[1].geojson.url == '/dashboard/assets/geojsons/prob/sconc_dust/50/geojson/{edate}/00_{edate}_SCONC_DUST.geojson'.format(edate=END_DATE)
    assert ForecastProbFigureHandler[1].geojson.options == {'style': {'variable': 'forecastTab.forecastMaps.styleHandle'}}
    
    # day 1 for sconc_dust
    ForecastProbFigureHandler[1].get_figure_layers(day=1)
    assert ForecastProbFigureHandler[1].geojson.url =='/dashboard/assets/geojsons/prob/sconc_dust/50/geojson/{edate}/01_{edate}_SCONC_DUST.geojson'.format(edate=END_DATE)
    assert ForecastProbFigureHandler[1].geojson.options == {'style': {'variable': 'forecastTab.forecastMaps.styleHandle'}}

# =================== Was Handler ============================
@pytest.fixture
def ForecastWasFigureHandler():
    return map_handler.ForecastWasFigureHandler(was='burkinafaso', model='median', var='SCONC_DUST', 
                                                 selected_date=END_DATE)

def test_was_get_regions_data(ForecastWasFigureHandler):
    # day 1
    assert ForecastWasFigureHandler.get_regions_data(day=1)[0][0] == 'Boucle du Mouhoun'
    assert ForecastWasFigureHandler.get_regions_data(day=1)[0][1] == 'Cascades'
    assert ForecastWasFigureHandler.get_regions_data(day=1)[0][-1] == 'Sud-Ouest'

    assert ForecastWasFigureHandler.get_regions_data(day=1)[1][0] == 'green'
    assert ForecastWasFigureHandler.get_regions_data(day=1)[1][1] == 'green'
    assert ForecastWasFigureHandler.get_regions_data(day=1)[1][-1] == 'green'

    assert ForecastWasFigureHandler.get_regions_data(day=1)[2][0] == 'Normal'
    assert ForecastWasFigureHandler.get_regions_data(day=1)[2][1] == 'Normal'
    assert ForecastWasFigureHandler.get_regions_data(day=1)[2][-1] =='Normal'

    # day 2
    assert ForecastWasFigureHandler.get_regions_data(day=2)[0][0] == 'Boucle du Mouhoun'
    assert ForecastWasFigureHandler.get_regions_data(day=2)[0][1] == 'Cascades'
    assert ForecastWasFigureHandler.get_regions_data(day=2)[0][-1] == 'Sud-Ouest'

    assert ForecastWasFigureHandler.get_regions_data(day=2)[1][0] == 'green'
    assert ForecastWasFigureHandler.get_regions_data(day=2)[1][1] == 'green'
    assert ForecastWasFigureHandler.get_regions_data(day=2)[1][-1] == 'green'

    assert ForecastWasFigureHandler.get_regions_data(day=2)[2][0] == 'Normal'
    assert ForecastWasFigureHandler.get_regions_data(day=2)[2][1] == 'Normal'
    assert ForecastWasFigureHandler.get_regions_data(day=2)[2][-1] =='Normal'

def test_was_get_geojson_url(ForecastWasFigureHandler):
    assert ForecastWasFigureHandler.get_geojson_url(day=1) == 'geojsons/was/burkinafaso/geojson/{edate}/{edate}_SCONC_DUST_1.geojson'.format(edate=END_DATE)
    assert ForecastWasFigureHandler.get_geojson_url(day=2) == 'geojsons/was/burkinafaso/geojson/{edate}/{edate}_SCONC_DUST_2.geojson'.format(edate=END_DATE)
    
def test_was_retrieve_cdatetime(ForecastWasFigureHandler):
    assert str(ForecastWasFigureHandler.retrieve_cdatetime(tstep=0)) == '{edate} 00:00:00'.format(edate=EDATE_OBJ.strftime(FMT_DASH))

def test_was_get_figure_layers(ForecastWasFigureHandler):
    
    ForecastWasFigureHandler.get_figure_layers(day=1)
    assert ForecastWasFigureHandler.geojson.options == {'style': {'variable': 'forecastTab.wasMaps.styleHandle'}}
    assert ForecastWasFigureHandler.geojson.url == '/dashboard/assets/geojsons/was/burkinafaso/geojson/{edate}/{edate}_SCONC_DUST_1.geojson'.format(edate=END_DATE)
    assert ForecastWasFigureHandler.legend.className == 'was-legend'

    ForecastWasFigureHandler.get_figure_layers(day=2)
    assert ForecastWasFigureHandler.geojson.options == {'style': {'variable': 'forecastTab.wasMaps.styleHandle'}}
    assert ForecastWasFigureHandler.geojson.url == '/dashboard/assets/geojsons/was/burkinafaso/geojson/{edate}/{edate}_SCONC_DUST_2.geojson'.format(edate=END_DATE)
    assert ForecastWasFigureHandler.legend.className == 'was-legend'
    
def test_was_get_title(ForecastWasFigureHandler):
    assert str(ForecastWasFigureHandler.get_title(day=0)) =="Barcelona Dust Regional Center - Burkina Faso WAS.<br>Expected concentration of airborne dust.<br>Issued: {edate}. Valid: {edate}".format(edate=EDATE_OBJ.strftime(FMT_MON))
    assert str(ForecastWasFigureHandler.get_title(day=1)) =="Barcelona Dust Regional Center - Burkina Faso WAS.<br>Expected concentration of airborne dust.<br>Issued: {edate}. Valid: {edate_next}".format(edate=EDATE_OBJ.strftime(FMT_MON), edate_next=(EDATE_OBJ + timedelta(days=1)).strftime(FMT_MON))
