package de.nilzbu.mytimetracker.ui.component;

import com.vaadin.flow.component.HasSize;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.dependency.NpmPackage;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.AttachEvent;
import elemental.json.Json;
import elemental.json.JsonArray;
import elemental.json.JsonObject;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

@Tag("div")
@JsModule("https://cdn.jsdelivr.net/npm/chart.js")
@NpmPackage(value = "chart.js", version = "4.4.0")
public class ChartJsComponent extends Div {

    private final JsonObject chartData;
    private final String chartTitle;

    public ChartJsComponent(JsonObject chartData, String chartTitle) {
        this.chartData = chartData;
        this.chartTitle = chartTitle;
        setWidthFull();
        setHeight("500px");
    }

    @Override
    protected void onAttach(AttachEvent attachEvent) {
        getElement().executeJs(
                """
                const canvas = document.createElement('canvas');
                this.appendChild(canvas);
                const ctx = canvas.getContext('2d');
                new Chart(ctx, {
                  type: $0,
                  data: $1,
                  options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                      legend: {
                        position: 'top'
                      },
                      title: {
                        display: true,
                        text: $2
                      }
                    }
                  }
                });
                """,
                getChartTypeFromData(chartData),
                chartData,
                chartTitle
        );
    }

    private String getChartTypeFromData(JsonObject data) {
        // Default zu bar wenn keine sinnvolle Bestimmung möglich ist
        try {
            JsonArray datasets = data.getArray("datasets");
            if (datasets.length() > 0) {
                JsonObject first = datasets.getObject(0);
                if (first.hasKey("fill") && !first.getBoolean("fill")) {
                    return "line";
                }
            }
        } catch (Exception ignored) {}
        return "bar";
    }

    // Balkendiagramm für Kategorien
    public static JsonObject generateBarChartData(Map<String, Long> categoryCounts) {
        JsonObject data = Json.createObject();
        JsonArray labels = Json.createArray();
        JsonArray values = Json.createArray();
        JsonArray backgroundColors = Json.createArray();

        String[] defaultColors = {"#1e7e34", "#138496", "#ffc107", "#dc3545", "#6f42c1", "#20c997"};

        int i = 0;
        for (Map.Entry<String, Long> entry : categoryCounts.entrySet()) {
            labels.set(i, Json.create(entry.getKey()));
            values.set(i, Json.create(entry.getValue()));
            backgroundColors.set(i, Json.create(defaultColors[i % defaultColors.length]));
            i++;
        }

        JsonObject dataset = Json.createObject();
        dataset.put("label", "Einträge nach Kategorie");
        dataset.put("data", values);
        dataset.put("backgroundColor", backgroundColors);

        JsonArray datasets = Json.createArray();
        datasets.set(0, dataset);

        data.put("labels", labels);
        data.put("datasets", datasets);

        return data;
    }

    // Liniendiagramm für Überstunden-Saldo (in Stunden)
    public static JsonObject generateLineChartData(List<LocalDate> dates, List<Double> saldoValues) {
        JsonObject data = Json.createObject();
        JsonArray labels = Json.createArray();
        JsonArray values = Json.createArray();

        for (int i = 0; i < dates.size(); i++) {
            labels.set(i, Json.create(dates.get(i).toString()));
            values.set(i, Json.create(saldoValues.get(i)));
        }

        JsonObject dataset = Json.createObject();
        dataset.put("label", "Überstunden-Saldo (h)");
        dataset.put("data", values);
        dataset.put("borderColor", "rgb(54, 162, 235)");
        dataset.put("tension", 0.1);
        dataset.put("fill", false);

        JsonArray datasets = Json.createArray();
        datasets.set(0, dataset);

        data.put("labels", labels);
        data.put("datasets", datasets);

        return data;
    }
}