<?php

use dokuwiki\Extension\AdminPlugin;
use dokuwiki\StyleUtils;

/**
 * DokuWiki Plugin styling (Admin Component)
 * Mejorado con organizacion por categorias y soporte para plugins NICC
 *
 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
 * @author  Andreas Gohr <andi@splitbrain.org>
 * @author  SIE Asesorias (mejoras)
 */
class admin_plugin_styling extends AdminPlugin
{
    public $ispopup = false;

    /**
     * Define las categorias y sus variables correspondientes
     * El orden aqui determina el orden de visualizacion
     * Organizado segun prioridad de aplicacion de estilos
     */
    protected function getCategories()
    {
        return [
            // 1. COLORES DE TITULOS SUPERIORES (barra de navegacion superior)
            'cat_topbar_colors' => [
                '__topbar_bg__',
                '__topbar_bg_hover__',
                '__topbar_text__',
                '__topbar_text_hover__',
                '__topbar_border__',
                '__topbar_active_bg__',
            ],
            // 2. COLORES Y EFECTOS DE TITULOS DE MENU
            'cat_menu_titles' => [
                '__menu_title_color__',
                '__menu_title_bg__',
                '__menu_title_border__',
                '__menu_title_shadow__',
            ],
            // 3. EFECTOS DE TITULOS DE MENU
            'cat_menu_effects' => [
                '__menu_title_radius__',
                '__menu_title_padding__',
                '__menu_hover_scale__',
            ],
            // 4. COLORES Y EFECTOS BOTONES LATERALES (menu gestion)
            'cat_lateral_buttons' => [
                '__lateral_bg__',
                '__lateral_bg_hover__',
                '__lateral_text__',
                '__lateral_border__',
                '__lateral_icon_color__',
                '__lateral_shadow__',
                '__lateral_radius__',
            ],
            // 5. COLORES Y EFECTOS BOTONES HIPERVINCULOS
            'cat_hiper_buttons' => [
                '__hiper_bg__',
                '__hiper_bg_hover__',
                '__hiper_text__',
                '__hiper_border__',
                '__hiper_icon_bg__',
                '__hiper_shadow__',
                '__hiper_radius__',
            ],
            // 6. COLORES BOTONES PROYECTOS (menu circular)
            'cat_proyectos_colors' => [
                '__proy_item_bg__',
                '__proy_item_bg_hover__',
                '__proy_item_text__',
                '__proy_item_border__',
                '__proy_center_bg__',
                '__proy_btn_letter_start__',
                '__proy_btn_letter_end__',
                '__proy_highlight_bg_start__',
                '__proy_highlight_bg_end__',
                '__proy_item_number_color__',
                '__proy_item_text_color__',
            ],
            // 7. EFECTOS BOTONES PROYECTOS
            'cat_proyectos_effects' => [
                '__proy_item_shadow__',
                '__proy_item_radius__',
                '__proy_hover_scale__',
                '__proy_container_size__',
            ],
            // 8. COLORES BARRA SUPERIOR (top-tabs menu)
            'cat_topbar_menu' => [
                '__topbar_menu_color__',
                '__topbar_menu_shadow__',
                '__topbar_hover_bg_start__',
                '__topbar_hover_bg_end__',
                '__topbar_hover_color__',
                '__topbar_hover_shadow__',
            ],
            // Categorias adicionales del sistema
            'cat_text_colors' => [
                '__text__',
                '__text_alt__',
                '__text_neu__',
            ],
            'cat_background_colors' => [
                '__background__',
                '__background_alt__',
                '__background_neu__',
                '__background_site__',
                '__border__',
                '__highlight__',
            ],
            'cat_links' => [
                '__link__',
                '__existing__',
                '__missing__',
            ],
            'cat_dimensions' => [
                '__site_width__',
                '__sidebar_width__',
                '__tablet_width__',
                '__phone_width__',
            ],
            // 9. COLORES TARJETA INFO PROYECTO (thread_box)
            'cat_project_card' => [
                '__project_sidebar_start__',
                '__project_sidebar_end__',
                '__project_avatar_bg__',
                '__project_status_open__',
                '__project_status_closed__',
                '__project_icon_type__',
                '__project_icon_year__',
                '__project_icon_norm__',
                '__project_icon_creator__',
                '__project_icon_coord__',
                '__project_btn_start__',
                '__project_btn_end__',
                '__project_btn_active__',
            ],
        ];
    }

    /**
     * Iconos para cada categoria
     */
    protected function getCategoryIcons()
    {
        return [
            'cat_topbar_colors'     => '1&#65039;&#8419;',  // 1
            'cat_menu_titles'       => '2&#65039;&#8419;',  // 2
            'cat_menu_effects'      => '3&#65039;&#8419;',  // 3
            'cat_lateral_buttons'   => '4&#65039;&#8419;',  // 4
            'cat_hiper_buttons'     => '5&#65039;&#8419;',  // 5
            'cat_proyectos_colors'  => '6&#65039;&#8419;',  // 6
            'cat_proyectos_effects' => '7&#65039;&#8419;',  // 7
            'cat_topbar_menu'       => '8&#65039;&#8419;',  // 8
            'cat_project_card'      => '9&#65039;&#8419;',  // 9 - Tarjeta Info Proyecto
            'cat_text_colors'       => '&#128394;', // Lapiz
            'cat_background_colors' => '&#127912;', // Paleta
            'cat_links'             => '&#128279;', // Enlace
            'cat_dimensions'        => '&#128207;', // Regla
        ];
    }

    /**
     * @return int sort number in admin menu
     */
    public function getMenuSort()
    {
        return 1000;
    }

    /**
     * @return bool true if only access for superuser, false is for superusers and moderators
     */
    public function forAdminOnly()
    {
        return true;
    }

    /**
     * handle the different actions (also called from ajax)
     */
    public function handle()
    {
        global $INPUT;
        $run = $INPUT->extract('run')->str('run');
        if (!$run) return;
        if (!checkSecurityToken()) return;
        $run = 'run' . ucfirst($run);
        $this->$run();
    }

    /**
     * Render HTML output, e.g. helpful text and a form
     */
    public function html()
    {
        $class = 'nopopup';
        if ($this->ispopup) $class = 'ispopup page';

        echo '<div id="plugin__styling" class="' . $class . '">';
        echo '<h1>' . $this->getLang('menu') . '</h1>';
        $this->form();
        echo '</div>';
    }

    /**
     * Create the actual editing form with categories
     */
    public function form()
    {
        global $conf;
        global $ID;

        $styleUtil = new StyleUtils($conf['template'], true, true);
        $styleini = $styleUtil->cssStyleini();
        $replacements = $styleini['replacements'];

        if ($this->ispopup) {
            $target = DOKU_BASE . 'lib/plugins/styling/popup.php';
        } else {
            $target = wl($ID, ['do' => 'admin', 'page' => 'styling']);
        }

        if (empty($replacements)) {
            echo '<p class="error">' . $this->getLang('error') . '</p>';
        } else {
            echo $this->locale_xhtml('intro');

            echo '<form class="styling" method="post" action="' . $target . '">';
            formSecurityToken();

            // Obtener categorias y sus iconos
            $categories = $this->getCategories();
            $icons = $this->getCategoryIcons();

            // Agrupar variables por categoria
            $categorized = [];
            $uncategorized = [];

            foreach ($replacements as $key => $value) {
                $found = false;
                foreach ($categories as $cat => $vars) {
                    if (in_array($key, $vars)) {
                        if (!isset($categorized[$cat])) {
                            $categorized[$cat] = [];
                        }
                        $categorized[$cat][$key] = $value;
                        $found = true;
                        break;
                    }
                }
                if (!$found) {
                    $uncategorized[$key] = $value;
                }
            }

            // Renderizar cada categoria
            foreach ($categories as $cat => $vars) {
                if (!isset($categorized[$cat]) || empty($categorized[$cat])) {
                    continue;
                }

                $catName = $this->getLang($cat);
                $icon = isset($icons[$cat]) ? $icons[$cat] : '';

                echo '<fieldset class="styling-category">';
                echo '<legend>';
                if ($icon) echo '<span class="cat-icon">' . $icon . '</span> ';
                echo hsc($catName);
                echo '</legend>';

                echo '<table><tbody>';
                foreach ($categorized[$cat] as $key => $value) {
                    $this->renderInputRow($key, $value);
                }
                echo '</tbody></table>';
                echo '</fieldset>';
            }

            // Variables no categorizadas (si las hay)
            if (!empty($uncategorized)) {
                echo '<fieldset class="styling-category">';
                echo '<legend><span class="cat-icon">&#9881;</span> Otras Configuraciones</legend>';
                echo '<table><tbody>';
                foreach ($uncategorized as $key => $value) {
                    $this->renderInputRow($key, $value);
                }
                echo '</tbody></table>';
                echo '</fieldset>';
            }

            // Botones de accion
            echo '<div class="styling-buttons">';
            echo '<button type="submit" name="run[preview]" class="btn_preview primary">' .
                $this->getLang('btn_preview') . '</button> ';
            echo '<button type="submit" name="run[reset]">' . $this->getLang('btn_reset') . '</button>';
            echo '</div>';

            echo '<div class="styling-buttons">';
            echo '<button type="submit" name="run[save]" class="primary btn-save">' . $this->getLang('btn_save') . '</button>';
            echo '</div>';

            echo '<div class="styling-buttons">';
            echo '<button type="submit" name="run[revert]" class="btn-danger">' . $this->getLang('btn_revert') . '</button>';
            echo '</div>';

            echo '</form>';

            echo tpl_locale_xhtml('style');
        }

        // Estilos CSS adicionales para las categorias
        $this->printStyles();
    }

    /**
     * Renderiza una fila de input
     */
    protected function renderInputRow($key, $value)
    {
        $name = tpl_getLang($key);
        if (empty($name)) $name = $this->getLang($key);
        if (empty($name)) $name = $this->formatKeyName($key);

        echo '<tr>';
        echo '<td class="label-cell"><label for="tpl__' . hsc($key) . '">' . hsc($name) . '</label></td>';
        echo '<td class="input-cell"><input type="' . $this->colorType($value) . '" name="tpl[' . hsc($key) . ']" ' .
            'id="tpl__' . hsc($key) . '" value="' . hsc($this->colorValue($value)) . '" ' .
            'dir="ltr" required="required"/></td>';
        echo '</tr>';
    }

    /**
     * Formatea el nombre de una variable para mostrar
     * Convierte __nombre_variable__ a "Nombre Variable"
     */
    protected function formatKeyName($key)
    {
        // Remover guiones bajos del inicio y fin
        $name = trim($key, '_');
        // Reemplazar guiones bajos por espacios
        $name = str_replace('_', ' ', $name);
        // Capitalizar cada palabra
        $name = ucwords($name);
        return $name;
    }

    /**
     * Imprime los estilos CSS para el formulario
     */
    protected function printStyles()
    {
        echo '<style>
            #plugin__styling {
                max-width: 1200px;
            }

            #plugin__styling h1 {
                color: #2c3e50;
                border-bottom: 3px solid #3498db;
                padding-bottom: 10px;
                margin-bottom: 20px;
            }

            #plugin__styling .styling-category {
                margin-bottom: 25px;
                border: 1px solid #e0e0e0;
                border-radius: 8px;
                padding: 15px 20px;
                background: #fafafa;
            }

            #plugin__styling .styling-category legend {
                font-size: 1.1em;
                font-weight: bold;
                color: #34495e;
                padding: 0 10px;
                background: #fafafa;
            }

            #plugin__styling .styling-category .cat-icon {
                font-size: 1.2em;
                margin-right: 5px;
            }

            #plugin__styling .styling-category table {
                width: 100%;
                border-collapse: collapse;
            }

            #plugin__styling .styling-category tr {
                border-bottom: 1px solid #eee;
            }

            #plugin__styling .styling-category tr:last-child {
                border-bottom: none;
            }

            #plugin__styling .styling-category td {
                padding: 10px 5px;
                vertical-align: middle;
            }

            #plugin__styling .styling-category .label-cell {
                width: 60%;
                font-size: 0.95em;
                color: #555;
            }

            #plugin__styling .styling-category .input-cell {
                width: 40%;
                text-align: right;
            }

            #plugin__styling .styling-category input[type="color"] {
                width: 50px;
                height: 35px;
                padding: 2px;
                border: 1px solid #ccc;
                border-radius: 4px;
                cursor: pointer;
            }

            #plugin__styling .styling-category input[type="text"] {
                width: 150px;
                padding: 8px 10px;
                border: 1px solid #ccc;
                border-radius: 4px;
                font-size: 0.9em;
            }

            #plugin__styling .styling-buttons {
                margin: 15px 0;
                padding: 10px 0;
            }

            #plugin__styling button {
                padding: 10px 20px;
                font-size: 1em;
                border: none;
                border-radius: 5px;
                cursor: pointer;
                margin-right: 10px;
                transition: all 0.3s ease;
            }

            #plugin__styling button.primary {
                background: #3498db;
                color: white;
            }

            #plugin__styling button.primary:hover {
                background: #2980b9;
            }

            #plugin__styling button.btn-save {
                background: #27ae60;
                color: white;
                font-weight: bold;
            }

            #plugin__styling button.btn-save:hover {
                background: #219a52;
            }

            #plugin__styling button.btn-danger {
                background: #e74c3c;
                color: white;
            }

            #plugin__styling button.btn-danger:hover {
                background: #c0392b;
            }

            #plugin__styling button:not(.primary):not(.btn-save):not(.btn-danger) {
                background: #95a5a6;
                color: white;
            }

            #plugin__styling button:not(.primary):not(.btn-save):not(.btn-danger):hover {
                background: #7f8c8d;
            }

            /* Responsive */
            @media (max-width: 768px) {
                #plugin__styling .styling-category .label-cell,
                #plugin__styling .styling-category .input-cell {
                    display: block;
                    width: 100%;
                    text-align: left;
                }

                #plugin__styling .styling-category .input-cell {
                    padding-top: 5px;
                }
            }
        </style>';
    }

    /**
     * Adjust three char color codes to the 6 char one supported by browser's color input
     *
     * @param string $value
     * @return string
     */
    protected function colorValue($value)
    {
        if (preg_match('/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/', $value, $match)) {
            return '#' . $match[1] . $match[1] . $match[2] . $match[2] . $match[3] . $match[3];
        }
        return $value;
    }

    /**
     * Decide the input type based on the value
     *
     * @param string $value
     * @return string color|text
     */
    protected function colorType($value)
    {
        if (preg_match('/^#([0-9a-fA-F]{3}){1,2}$/', $value)) {
            return 'color';
        } else {
            return 'text';
        }
    }

    /**
     * saves the preview.ini (also called from ajax directly)
     */
    public function runPreview()
    {
        global $conf;
        $ini = $conf['cachedir'] . '/preview.ini';
        io_saveFile($ini, $this->makeini());
    }

    /**
     * deletes the preview.ini
     */
    protected function runReset()
    {
        global $conf;
        $ini = $conf['cachedir'] . '/preview.ini';
        io_saveFile($ini, '');
    }

    /**
     * deletes the local style.ini replacements
     */
    protected function runRevert()
    {
        $this->replaceIni('');
        $this->runReset();
    }

    /**
     * save the local style.ini replacements
     */
    protected function runSave()
    {
        $this->replaceIni($this->makeini());
        $this->runReset();
    }

    /**
     * create the replacement part of a style.ini from submitted data
     *
     * @return string
     */
    protected function makeini()
    {
        global $INPUT;

        $ini = "[replacements]\n";
        $ini .= ";Estas configuraciones fueron generadas desde la interfaz de Personalizacion Visual\n";
        $ini .= ";Los valores en esta seccion seran sobreescritos por esa herramienta\n";
        foreach ($INPUT->arr('tpl') as $key => $val) {
            $ini .= $key . ' = "' . addslashes($val) . '"' . "\n";
        }

        return $ini;
    }

    /**
     * replaces the replacement parts in the local ini
     *
     * @param string $new the new ini contents
     */
    protected function replaceIni($new)
    {
        global $conf;
        $ini = DOKU_CONF . "tpl/" . $conf['template'] . "/style.ini";
        if (file_exists($ini)) {
            $old = io_readFile($ini);
            $old = preg_replace('/\[replacements\]\n.*?(\n\[.*]|$)/s', '\\1', $old);
            $old = trim($old);
        } else {
            $old = '';
        }

        io_makeFileDir($ini);
        io_saveFile($ini, "$old\n\n$new");
    }
}
