// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * dashboard.js
 *
 * @package   local_kopere_dashboard
 * @copyright 2026 Eduardo Kraus {@link https://eduardokraus.com}
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

define(["jquery"], function ($) {
    function readJson(id) {
        var el = document.getElementById(id);
        if (!el) {
            return null;
        }
        try {
            return JSON.parse(el.textContent || "{}");
        } catch (e) {
            return null;
        }
    }

    function resizeCanvas(canvas) {
        if (!canvas) {
            return;
        }
        var rect = canvas.getBoundingClientRect();
        var dpr = window.devicePixelRatio || 1;

        var w = Math.max(240, Math.floor(rect.width));
        var h = Math.max(160, Math.floor(rect.height || canvas.height));

        canvas.width = Math.floor(w * dpr);
        canvas.height = Math.floor(h * dpr);

        var ctx = canvas.getContext("2d");
        ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }

    function drawLineChart(canvas, data) {
        if (!canvas || !data || !data.labels || !data.values) {
            return;
        }

        resizeCanvas(canvas);

        var ctx = canvas.getContext("2d");
        var w = canvas.getBoundingClientRect().width;
        var h = canvas.getBoundingClientRect().height || 180;

        ctx.clearRect(0, 0, w, h);

        var padding = 24;
        var left = padding;
        var right = w - padding;
        var top = 16;
        var bottom = h - 28;

        var max = 0;
        for (var i = 0; i < data.values.length; i++) {
            max = Math.max(max, data.values[i] || 0);
        }
        max = max <= 0 ? 1 : max;

        ctx.globalAlpha = 1;
        ctx.lineWidth = 1;
        ctx.strokeStyle = "rgba(0,0,0,.08)";
        ctx.beginPath();
        ctx.moveTo(left, bottom);
        ctx.lineTo(right, bottom);
        ctx.stroke();

        var n = data.values.length;
        var step = n > 1 ? ((right - left) / (n - 1)) : 0;

        function xy(index) {
            var x = left + (index * step);
            var y = bottom - ((data.values[index] / max) * (bottom - top));
            return {x: x, y: y};
        }

        ctx.strokeStyle = "rgba(0,188,212,.9)";
        ctx.lineWidth = 3;
        ctx.beginPath();
        for (var k = 0; k < n; k++) {
            var p = xy(k);
            if (k == 0) {
                ctx.moveTo(p.x, p.y);
            } else {
                ctx.lineTo(p.x, p.y);
            }
        }
        ctx.stroke();

        ctx.globalAlpha = 0.12;
        ctx.fillStyle = "rgba(0,188,212,.9)";
        ctx.beginPath();
        for (var m = 0; m < n; m++) {
            var p2 = xy(m);
            if (m == 0) {
                ctx.moveTo(p2.x, bottom);
                ctx.lineTo(p2.x, p2.y);
            } else {
                ctx.lineTo(p2.x, p2.y);
            }
        }
        var last = xy(n - 1);
        ctx.lineTo(last.x, bottom);
        ctx.closePath();
        ctx.fill();
        ctx.globalAlpha = 1;

        ctx.fillStyle = "rgba(0,0,0,.55)";
        ctx.font = "12px sans-serif";
        ctx.textAlign = "center";
        ctx.textBaseline = "top";

        for (var t = 0; t < n; t++) {
            var pt = xy(t);
            ctx.fillText(String(data.labels[t]), pt.x, bottom + 8);

            ctx.beginPath();
            ctx.fillStyle = "rgba(0,188,212,1)";
            ctx.arc(pt.x, pt.y, 4, 0, Math.PI * 2);
            ctx.fill();
            ctx.fillStyle = "rgba(0,0,0,.55)";
        }
    }

    function drawDonut(canvas, legendEl, data) {
        if (!canvas || !data || !data.values || !data.labels) {
            return;
        }

        resizeCanvas(canvas);

        var ctx = canvas.getContext("2d");
        var w = canvas.getBoundingClientRect().width;
        var h = canvas.getBoundingClientRect().height || 180;

        ctx.clearRect(0, 0, w, h);

        var cx = w / 2;
        var cy = h / 2;
        var r = Math.min(w, h) * 0.36;
        var inner = r * 0.62;

        var sum = 0;
        for (var i = 0; i < data.values.length; i++) {
            sum += (data.values[i] || 0);
        }
        sum = sum <= 0 ? 1 : sum;

        var colors = [
            "rgba(21,54,95,.95)",
            "rgba(0,188,212,.95)",
            "rgba(243,156,18,.95)"
        ];

        var start = -Math.PI / 2;

        for (var j = 0; j < data.values.length; j++) {
            var v = data.values[j] || 0;
            var ang = (v / sum) * (Math.PI * 2);

            ctx.beginPath();
            ctx.strokeStyle = colors[j % colors.length];
            ctx.lineWidth = r - inner;
            ctx.lineCap = "butt";
            ctx.arc(cx, cy, (r + inner) / 2, start, start + ang);
            ctx.stroke();

            start += ang;
        }

        ctx.beginPath();
        ctx.fillStyle = "white";
        ctx.arc(cx, cy, inner, 0, Math.PI * 2);
        ctx.fill();

        if (legendEl) {
            var html = "";
            for (var k = 0; k < data.labels.length; k++) {
                var pct = Math.round(((data.values[k] || 0) / sum) * 100);
                html += "<div class=\"kopere_dashboard-legend-item\">" +
                    "<span class=\"kopere_dashboard-legend-dot\" style=\"background:" + colors[k % colors.length] + ";\"></span>" +
                    "<span class=\"kopere_dashboard-legend-label\">" + escapeHtml(String(data.labels[k])) + " (" + pct + "%)</span>" +
                    "</div>";
            }
            legendEl.innerHTML = html;
        }
    }

    function escapeHtml(str) {
        return str
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;");
    }

    function init() {
        var lineData = readJson("kopere_dashboard-line-data");
        var donutData = readJson("kopere_dashboard-donut-data");

        var lineCanvas = document.getElementById("kopere_dashboard-line");
        var donutCanvas = document.getElementById("kopere_dashboard-donut");
        var donutLegend = document.getElementById("kopere_dashboard-donut-legend");

        function render() {
            drawLineChart(lineCanvas, lineData);
            drawDonut(donutCanvas, donutLegend, donutData);
        }

        render();
        $(window).on("resize", function () {
            render();
        });
    }

    return {init: init};
});