# callbacks/strategy/update_callback.py
from dash import Input, Output, State
import dash
from .constants import STRATEGY_OUTPUTS
from .helpers import (
    get_default_outputs,
    handle_mode_change,
    get_date_range,
    get_filtered_data,
    update_strategy_selection,
    get_backtest_results,
    create_output_components,
    handle_error
)

def register_update_callback(app):
    @app.callback(
        STRATEGY_OUTPUTS,
        [Input('combined-heatmap', 'clickData'),
         Input('apply-date-range', 'n_clicks'),
         Input('reset-date-range', 'n_clicks'),
         Input('dashboard-mode', 'value'),
         Input('strategy-clear-selection', 'n_clicks')],
        [State('bt-end-date', 'date'),
         State('time-factor', 'value'),
         State('commission', 'value'),
         State('date-range-picker', 'start_date'),
         State('date-range-picker', 'end_date'),
         State('selected-strategies', 'data')],
        prevent_initial_call=True
    )
    def update_all_outputs(click_data, apply_clicks, reset_clicks, mode, clear_clicks,
                          bt_end_date, time_factor, commission,
                          start_date, end_date, current_selection):
        """Main callback function that updates all dashboard components."""
        # Get trigger context
        ctx = dash.callback_context
        if not ctx.triggered:
            return get_default_outputs()

        trigger_id = ctx.triggered[0]['prop_id'].split('.')[0]

        # Handle mode changes and clear selection
        if trigger_id in ['dashboard-mode', 'strategy-clear-selection']:
            return handle_mode_change(trigger_id, mode, current_selection)

        try:
            # Process date range and data
            start_date, end_date = get_date_range(trigger_id, start_date, end_date)
            data = get_filtered_data(start_date, end_date)
            commission = commission / 100

            # Update strategy selection and get results
            current_selection = update_strategy_selection(mode, trigger_id, click_data, current_selection)
            result_dict = get_backtest_results(mode, current_selection, data, click_data, time_factor, commission)

            # Create and return components
            return create_output_components(result_dict, mode, current_selection, start_date, end_date, click_data)

        except ZeroDivisionError:
            return handle_error("zero_division", start_date, end_date, current_selection, mode)
        except Exception as e:
            print(f"Error in strategy details update: {str(e)}")
            return handle_error("general", start_date, end_date, current_selection, mode, str(e))