package dev.lions.user.manager.client.view;

import dev.lions.user.manager.client.api.AuditRestClient;
import dev.lions.user.manager.client.api.HealthRestClient;
import dev.lions.user.manager.client.api.UserRestClient;
import dev.lions.user.manager.enums.audit.TypeActionAudit;
import jakarta.annotation.PostConstruct;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import software.xdev.chartjs.model.charts.BarChart;
import software.xdev.chartjs.model.data.BarData;
import software.xdev.chartjs.model.dataset.BarDataset;
import software.xdev.chartjs.model.options.BarOptions;
import software.xdev.chartjs.model.options.Plugins;
import software.xdev.chartjs.model.options.Title;
import software.xdev.chartjs.model.options.scale.Scales;
import software.xdev.chartjs.model.options.scale.cartesian.linear.LinearScaleOptions;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Named
@ViewScoped
@Slf4j
public class DashboardView implements Serializable {

    @Inject
    @RestClient
    AuditRestClient auditRestClient;

    @Inject
    @RestClient
    HealthRestClient healthRestClient;

    @Inject
    @RestClient
    UserRestClient userRestClient;

    @ConfigProperty(name = "lions.user.manager.default.realm", defaultValue = "test-realm")
    String defaultRealm;

    @Getter
    private long totalSuccesses;

    @Getter
    private long totalFailures;

    @Getter
    private long activeUsers;

    @Getter
    private boolean systemHealthy;

    @Getter
    private String barModelJson;

    @PostConstruct
    public void init() {
        loadStats();
        createBarModel();
    }

    public void loadStats() {
        try {
            totalSuccesses = auditRestClient.getSuccessCount(null, null);
            totalFailures = auditRestClient.getFailureCount(null, null);

            // Assuming we display active users for default realm
            // Ideally we would have an endpoint for global stats
            activeUsers = 0; // Placeholder until we have count endpoint in UserRestClient or general stats

            try {
                Map<String, Object> health = healthRestClient.getServiceStatus();
                systemHealthy = "UP".equals(health.get("status"));
            } catch (Exception e) {
                systemHealthy = false;
            }

        } catch (Exception e) {
            log.error("Error loading stats", e);
        }
    }

    public void createBarModel() {
        BarDataset barDataSet = new BarDataset()
                .setLabel("Activités par type")
                .setBorderWidth(1);

        BarData data = new BarData();

        try {
            Map<TypeActionAudit, Long> stats = auditRestClient.getActionStatistics(null, null);

            for (Map.Entry<TypeActionAudit, Long> entry : stats.entrySet()) {
                data.addLabel(entry.getKey().name());
                barDataSet.addData(entry.getValue().intValue());
                barDataSet.addBackgroundColor("rgba(75, 192, 192, 0.2)");
                barDataSet.addBorderColor("rgb(75, 192, 192)");
            }
        } catch (Exception e) {
            log.error("Error loading chart data", e);
        }

        data.addDataset(barDataSet);

        // Options
        LinearScaleOptions linearScaleOptions = new LinearScaleOptions().setBeginAtZero(true);
        
        Scales scales = new Scales()
                .addScale(Scales.ScaleAxis.Y, linearScaleOptions);

        Title title = new Title()
                .setDisplay(true)
                .setText("Audit Actions");

        Plugins plugins = new Plugins()
                .setTitle(title);

        BarOptions options = new BarOptions()
                .setScales(scales)
                .setPlugins(plugins);

        BarChart chart = new BarChart(data, options);
        this.barModelJson = chart.toJson();
    }
}
