package vassistent.controller;

import vassistent.model.AppState;
import vassistent.model.RatioPoint;
import vassistent.service.StatisticsService;
import vassistent.ui.DashboardView;
import vassistent.util.Logger;

import javax.swing.*;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Updates the dashboard chart and level bar whenever application state changes.
 */
public class DashboardController {

    private final StatisticsService statisticsService;
    private final DashboardView dashboardView;
    private final ExecutorService dashboardUpdateExecutor;

    /**
     * Creates a dashboard controller and subscribes to app state changes.
     *
     * @param statisticsService service used to compute chart data
     * @param dashboardView dashboard UI component
     * @param appState observable application state
     */
    public DashboardController(
            StatisticsService statisticsService,
            DashboardView dashboardView,
            AppState appState
    ) {
        this.statisticsService = statisticsService;
        this.dashboardView = dashboardView;
        this.dashboardUpdateExecutor =
                Executors.newSingleThreadExecutor(runnable -> {
                    Thread thread = new Thread(runnable, "dashboard-update");
                    thread.setDaemon(true);
                    return thread;
                });

        appState.addListener(this::onStateChanged);
    }

    /**
     * Recomputes dashboard content when state changes.
     *
     * @param state latest application state
     */
    private void onStateChanged(AppState state) {
        dashboardUpdateExecutor.execute(() -> {
            List<RatioPoint> points =
                    statisticsService.getLastNAverages(120);

            SwingUtilities.invokeLater(() -> {

                Logger.info("STATISTICS",
                        "Entries loaded: " + points.size());

                dashboardView.updateChart(points);

                if (!points.isEmpty()) {
                    double ratio = points.get(points.size() - 1).getRatio();
                    dashboardView.updateProblemLevel(ratio);
                }
            });
        });
    }
}
