/**
 * NGBVD offline-safe chart fallback.
 * This file intentionally provides a tiny Highcharts-compatible surface so the
 * dashboard does not render blank cards when CDN scripts are blocked or load late.
 * If real Highcharts loads before dashboard scripts run, this file stays out of the way.
 */
(function () {
    'use strict';

    if (window.Highcharts && typeof window.Highcharts.chart === 'function') {
        return;
    }

    function escapeHtml(value) {
        return String(value === null || value === undefined ? '' : value)
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#039;');
    }

    function number(value) {
        var n = Number(value);
        return isNaN(n) ? 0 : n;
    }

    function flattenPoints(options) {
        var points = [];
        var series = options && options.series ? options.series : [];
        series.forEach(function (serie) {
            var name = serie.name || '';
            (serie.data || []).forEach(function (point, index) {
                if (Array.isArray(point)) {
                    points.push({ name: point[0] || name || ('Item ' + (index + 1)), y: number(point[1]), series: name });
                } else if (typeof point === 'object') {
                    points.push({ name: point.name || name || ('Item ' + (index + 1)), y: number(point.y), series: name });
                } else {
                    points.push({ name: name || ('Item ' + (index + 1)), y: number(point), series: name });
                }
            });
        });
        return points;
    }

    function categories(options) {
        return options && options.xAxis && options.xAxis.categories ? options.xAxis.categories : [];
    }

    function renderColumn(container, options) {
        var series = options.series || [];
        var cats = categories(options);
        var groups = [];
        if (cats.length) {
            cats.forEach(function (cat, index) {
                var total = 0;
                series.forEach(function (serie) { total += number((serie.data || [])[index]); });
                groups.push({ name: cat, y: total });
            });
        } else {
            groups = flattenPoints(options);
        }
        groups = groups.sort(function (a, b) { return b.y - a.y; }).slice(0, 24);
        var max = Math.max.apply(null, groups.map(function (p) { return p.y; }).concat([1]));
        var bars = groups.map(function (p) {
            var width = Math.max(3, Math.round((p.y / max) * 100));
            return '<div class="ngbvd-fallback-row"><span class="ngbvd-fallback-label" title="' + escapeHtml(p.name) + '">' + escapeHtml(p.name) + '</span><span class="ngbvd-fallback-track"><span style="width:' + width + '%"></span></span><strong>' + Number(p.y).toLocaleString() + '</strong></div>';
        }).join('');
        container.innerHTML = '<div class="ngbvd-fallback-chart ngbvd-fallback-column">' + bars + '</div>';
    }

    function renderPie(container, options) {
        var points = flattenPoints(options).sort(function (a, b) { return b.y - a.y; }).slice(0, 12);
        var total = points.reduce(function (sum, p) { return sum + p.y; }, 0) || 1;
        var rows = points.map(function (p, index) {
            var percent = Math.round((p.y / total) * 1000) / 10;
            return '<div class="ngbvd-fallback-pie-row"><span class="ngbvd-fallback-dot dot-' + (index % 8) + '"></span><span>' + escapeHtml(p.name) + '</span><strong>' + Number(p.y).toLocaleString() + ' <small>(' + percent + '%)</small></strong></div>';
        }).join('');
        container.innerHTML = '<div class="ngbvd-fallback-chart"><div class="ngbvd-fallback-total"><span>Total</span><strong>' + Number(total).toLocaleString() + '</strong></div>' + rows + '</div>';
    }

    function render(containerId, options) {
        var container = typeof containerId === 'string' ? document.getElementById(containerId) : containerId;
        if (!container) { return null; }
        var title = options && options.title && options.title.text ? options.title.text : 'Chart';
        var subtitle = options && options.subtitle && options.subtitle.text ? options.subtitle.text : '';
        var type = options && options.chart && options.chart.type ? options.chart.type : 'column';
        container.classList.add('ngbvd-fallback-container');
        container.innerHTML = '<div class="ngbvd-fallback-loading">Loading chart...</div>';
        var shell = document.createElement('div');
        shell.innerHTML = '<div class="ngbvd-fallback-head"><h5>' + escapeHtml(title) + '</h5>' + (subtitle ? '<p>' + escapeHtml(subtitle) + '</p>' : '') + '</div><div class="ngbvd-fallback-body"></div>';
        container.innerHTML = '';
        container.appendChild(shell);
        var body = shell.querySelector('.ngbvd-fallback-body');
        if (type === 'pie') { renderPie(body, options); }
        else { renderColumn(body, options); }
        return {
            reflow: function () {},
            redraw: function () {}
        };
    }

    window.Highcharts = window.Highcharts || {};
    window.Highcharts.charts = window.Highcharts.charts || [];
    window.Highcharts.chart = function (containerId, options) {
        var chart = render(containerId, options || {});
        if (chart) { window.Highcharts.charts.push(chart); }
        return chart;
    };
})();
