<?php
/*
** Copyright (C) 2021-2026 initMAX s.r.o.
**
** This program is free software: you can redistribute it and/or modify it under the terms of
** the GNU Affero General Public License as published by the Free Software Foundation, version 3.
**
** This program 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 Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License along with this program.
** If not, see <https://www.gnu.org/licenses/>.
**/


namespace Modules\uxMAX\Includes;

/**
 * WHICH assets and which body attributes a request needs - decided once, for
 * both module trees.
 *
 * The two trees differ only in HOW they deliver the answer:
 *   6.4+ (manifest v2)  return it from Module::getAssets(); the frontend emits
 *                       the <script>/<link> tags itself.
 *   6.0/6.2 (v1)        have no `assets` block at all, so legacy/Module.php
 *                       injects the same files itself, in order.
 * Deciding it twice is how a feature ends up switched on for one line and off
 * for the other with nothing to show for it.
 *
 * Script paths are given relative to assets/js/. The v1 package flattens that
 * tree, so basename() is the correct mapping there - not a guess.
 */
final class Presentation {

    /**
     * Body (documentElement) attributes that gate the purely-CSS features.
     *
     * @return array<string,string>
     */
    public static function bodyAttributes(array $prefs, string $action): array {
        $state = $prefs['state'];
        $attributes = [];

        if ($state['bodybg']) {
            $attributes['uxmax-coloring-body'] = 'on';
        }

        if ($state['asidebg']) {
            $attributes['uxmax-coloring-sidebar'] = 'on';
        }

        if ($state['latestshowdisabled'] && $action === 'latest.view') {
            $attributes['uxmax-latest-show-disabled'] = 'on';
        }

        if ($state['hidewidgetheader']) {
            $attributes['uxmax-hide-widget-header'] = 'on';
        }

        if ($state['compactdashboard']) {
            $attributes['uxmax-compact-dashboard'] = 'on';
        }

        return $attributes;
    }

    /**
     * Scripts this request needs, IN LOAD ORDER (ace's core before its modes,
     * modes before the code that calls ace.edit()).
     *
     * @return string[]  paths relative to assets/js/
     */
    public static function scripts(array $prefs, string $action): array {
        $state = $prefs['state'];
        $on_form = $action === 'mod.uxmax.form';
        $scripts = [];

        if ($state['exprhighlight'] || $state['syntax'] || $on_form) {
            $scripts[] = 'ace.1.5.0/ace.js';
        }

        if ($state['syntax'] || $on_form) {
            $scripts = array_merge($scripts, [
                'ace.1.5.0/ext-language_tools.js',
                'ace.1.5.0/worker-base.js',
                'ace.1.5.0/worker-javascript.js',
                'ace.1.5.0/mode-javascript.js',
                'ace.1.5.0/worker-css.js',
                'ace.1.5.0/mode-css.js',
                'ace.1.5.0/theme-twilight.js',
                'uxmax.ace.js'
            ]);
        }

        if ($state['exprhighlight']) {
            $scripts[] = 'ace.1.5.0/mode-zabbix_expr.js';
            $scripts[] = 'uxmax.expr.js';
        }

        if ($state['windrag'] || $on_form) {
            $scripts[] = 'uxmax.dragm.js';
        }

        // Only where the frontend does NOT put the tag text into
        // data-hintbox-contents (6.0 - 6.4). On 7.x the colour rules are pure
        // CSS and this script would be a MutationObserver for nothing.
        if ($state['colortags'] && !Compat::tagsCarryHintAttribute()) {
            $scripts[] = 'uxmax.colortags.js';
        }

        // Last: it drives controls the other scripts define behaviour for.
        if ($on_form) {
            $scripts[] = 'uxmax.form.js';
        }

        return array_values(array_unique($scripts));
    }

    /**
     * Is the generated, preference-dependent stylesheet
     * (zabbix.php?action=mod.uxmax.css) needed at all? The static uxmax.css is
     * always loaded; this one carries the colours, the fonts and the tag rules.
     */
    public static function needsGeneratedCss(array $prefs): bool {
        $state = $prefs['state'];

        return (bool) ($state['colortags'] || $state['bodybg'] || $state['asidebg']
            || $state['syntax'] || $state['exprhighlight'] || $state['customfont']
            || $state['modalwidth']);
    }
}
