import pytest
import importlib
import dash
from contextvars import copy_context
from dash._callback_context import context_value
from dash._utils import AttributeDict
code = importlib.import_module('tabs.observations_callbacks')
from map_handler import START_DATE
from unittest.mock import MagicMock

#============ TEST render_evaluation_tab=================================
def test_render_observations_tab():
    # CASE 1, RGB 1 CLICK, VISIBILITY NO CLICK
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": [{"prop_id": "rgb.n_clicks"}, {"prop_id": "visibility.n_clicks"}]}))
        code.START_DATE = '20120120'
        code.END_DATE = '20220831'
        return code.render_observations_tab(1, 0) 

    ctx = copy_context()
    output = ctx.run(run_callback)
    assert output[0].id == 'observations-tab'
    assert output[0].children[0].className == 'description-title' 
    check_date = output[0].children[3].children[1].children.children[0].children[0].children[0].date
    assert check_date == code.END_DATE
    check_id = output[0].children[3].children[1].children.children[0].children[0].children[0].id
    assert check_id == 'obs-date-picker'
    assert "All observations are kindly offered by Partners of the WMO Barcelona Dust Regional Center. RGB is a qualitative satellite product that indicates desert dust in the entire atmospheric column (represented by pink colour).']), className='description-body'), Div(children=[Button(children='HEMISPHERIC', id='btn-fulldisc', active=True), Button(children='MIDDLE EAST', id='btn-middleeast', active=False)], id='rgb-buttons'), " in str(output[0]) 
    assert ", className='timesliderline')], className='timeslider')], id='rgb-navbar', className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True), className='layout-dropdown')], className='centered-image'), Div(Interval(id='obs-slider-interval', disabled=True, interval=1000, n_intervals=0))], id='observations-tab', className='horizontal-menu', label='Observations', value='observations-tab')" in str(output[0])
    assert output[1:] == ({ 'font-weight': 'bold' }, { 'font-weight': 'normal' }, 'rgb')


def test_render_observations_tab_visibility():
    # CASE 2, RGB NO CLICK, VISIBILITY 1 CLICK
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": [{"prop_id": "visibility.n_clicks"}]}))
        code.END_DATE = '20220831'
        return code.render_observations_tab(0, 1) 

    from tabs.observations import get_vis_edate
    from datetime import datetime
    hour = datetime.now().hour
    _, default_tstep = get_vis_edate('20220831', hour=hour)
    ctx = copy_context()
    output = ctx.run(run_callback)
    assert "Slider(min=0, max=18, step=6, marks={0: {'label': '00-06'}, 6: {'label': '06-12'}, 12: {'label': '12-18'}, 18: {'label': '18-24', 'style': {'left': '', 'right': '-32px'}}}, value=%(default_tstep)s, id='obs-vis-slider-graph'), className='timesliderline')], className='timeslider')], id='rgb-navbar', className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True), Br(None), Br(None), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='models-disclaimer')], className='disclaimer')], className='layout-dropdown rgb-layout-dropdown')], id='observations-tab', className='horizontal-menu', label='Observations', value='observations-tab')" % { 'default_tstep': default_tstep } in str(output[0]) 
    assert output[1:] == ({ 'font-weight': 'normal' }, { 'font-weight': 'bold' }, 'visibility')


def test_update_image_src_fulldisc(mocker):
    # Mocking dash.get_asset_url
    mocked_get_asset_url = mocker.patch('dash.get_asset_url')
    mocked_get_asset_url.return_value = 'mocked_url'

    def run_callback():
        # Set up the inputs for the callback
        context_value.set(AttributeDict(**{"triggered_inputs": 
            [{"prop_id": "btn-fulldisc.n_clicks"},
                {"prop_id": "btn-middleeast.n_clicks"},
                {"prop_id": "eval-date-picker.date"},
                {"prop_id": "obs-slider-graph.value"},
                {"prop_id": "btn-fulldisc.active"},
                {"prop_id": "btn-middleeast.active"}]}))

        return code.update_image_src.uncached(1, None, START_DATE, 3, False, True)

    ctx = copy_context()
    url, btn_fulldisc_active, btn_middleeast_active  = ctx.run(run_callback)
    
    # Assert the expected behavior
    assert url == 'mocked_url'
    assert btn_fulldisc_active == True
    assert btn_middleeast_active == False

def test_update_image_src_middleeast(mocker):
    # Mocking dash.get_asset_url
    mocked_get_asset_url = mocker.patch('dash.get_asset_url')
    mocked_get_asset_url.return_value = 'mocked_url'

    def run_callback():
        # Set up the inputs for the callback
        context_value.set(AttributeDict(**{"triggered_inputs": 
            [{"prop_id": "btn-middleeast.n_clicks"},
                {"prop_id": "eval-date-picker.date"},
                {"prop_id": "obs-slider-graph.value"},
                {"prop_id": "btn-fulldisc.active"},
                {"prop_id": "btn-middleeast.active"}]}))

        return code.update_image_src.uncached(None, 1, START_DATE, 0, True, False)

    ctx = copy_context()
    url, btn_fulldisc_active, btn_middleeast_active = ctx.run(run_callback)
    
    # Assert the expected behavior
    assert url == 'mocked_url'
    assert btn_fulldisc_active == False
    assert btn_middleeast_active == True

def test_start_stop_obs_autoslider_True():
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": 
            [{"prop_id": "btn-obs-play.n_clicks"},
                {"prop_id": "obs-slider-interval.disabled"},
                {"prop_id": "obs-slider-graph.value"}]}))
        return code.start_stop_obs_autoslider.uncached(1, True, '3')

    ctx = copy_context()
    output = ctx.run(run_callback)
    assert output == (False, 3, 'fa fa-pause text-center') 

def test_start_stop_obs_autoslider_False():
    def run_callback():
        context_value.set(AttributeDict(**{"triggered_inputs": 
            [{"prop_id": "btn-obs-play.n_clicks"},
                {"prop_id": "obs-slider-interval.disabled"},
                {"prop_id": "obs-slider-graph.value"}]}))
        return code.start_stop_obs_autoslider.uncached(1, False, '6')

    ctx = copy_context()
    output = ctx.run(run_callback)
    assert output == (True, 6, 'fa fa-play text-center') 

def test_update_obs_slider():
    assert code.update_obs_slider.uncached(0) == 0 
    assert code.update_obs_slider.uncached(13) == 13 
    assert code.update_obs_slider.uncached(23) == 23 
    assert code.update_obs_slider.uncached(24) == 0
    assert code.update_obs_slider.uncached(36) == 12 
    assert code.update_obs_slider.uncached(39) == 15 
    assert code.update_obs_slider.uncached(49) == 1 

def test_update_vis_figure():
    run = code.update_vis_figure.uncached('20220808', 1, [5], [45,45])
    assert "Map(children=[TileLayer(id={'tag': 'obs-vis-tile-layer', 'index': 'None'}" in str(run)

    assert "id='vis-info', className='info', style={'position': 'absolute', 'top': '10px', 'left': '10px', 'zIndex': '1000', 'fontFamily'" in str(run)
                                                    
def test_update_vis_figure_date_none():
    run = code.update_vis_figure.uncached(None, 1, [5], [45,45])
    assert "id={'tag': 'obs-vis-map', 'index': 'None'}, animate=False, center=45, inertia=True, minZoom=2, preferCanvas=True, wheelDebounceTime=80, wheelPxPerZoomLevel=120, zoom=5, zoomSnap=0.1)" in str(run)


                                                
