<?php

if (!defined('DOKU_INC')) die();

use dokuwiki\Extension\AdminPlugin;

/**
 * Plugin de Administracion para Aprobacion Masiva de Documentos
 *
 * Interfaz simplificada con dos grupos de aprobacion:
 * - OPERACIONES: proyectos
 * - PROCEDIMIENTOS: administrativa, auditorias, comercial, compartidos, manual_funciones, operativo, rrhh, acta, encargos
 */
class admin_plugin_publishadmin extends AdminPlugin
{
    /** @var helper_plugin_publish */
    protected $publishHelper = null;

    /** @var array Mensajes de resultado */
    protected $messages = [];

    /** @var array Definicion de grupos de aprobacion */
    protected $approvalGroups = [
        'OPERACIONES' => [
            'namespaces' => ['proyectos'],
            'description' => 'Aprueba todas las paginas de Proyectos',
            'color' => '#0275d8'
        ],
        'PROCEDIMIENTOS' => [
            'namespaces' => [
                'administrativa',
                'auditorias',
                'comercial',
                'compartidos',
                'manual_funciones',
                'operativo',
                'rrhh',
                'acta',
                'encargos'
            ],
            'description' => 'Aprueba paginas de procedimientos: Administrativa, Auditorias, Comercial, Compartidos, Manual de Funciones, Operativo, RRHH, Actas y Encargos',
            'color' => '#5cb85c'
        ]
    ];

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->publishHelper = plugin_load('helper', 'publish');
    }

    /**
     * Determina el orden en el menu de admin
     */
    public function getMenuSort()
    {
        return 50;
    }

    /**
     * Acceso solo para managers y admins
     */
    public function forAdminOnly()
    {
        return false;
    }

    /**
     * Nombre del menu
     */
    public function getMenuText($language)
    {
        return 'Aprobacion Masiva de Documentos';
    }

    /**
     * Icono del menu (opcional)
     */
    public function getMenuIcon()
    {
        return DOKU_BASE . 'lib/plugins/publishadmin/images/icon.svg';
    }

    /**
     * Maneja las acciones del formulario
     */
    public function handle()
    {
        global $INPUT;

        if (!$this->publishHelper) {
            $this->messages[] = ['type' => 'error', 'msg' => 'El plugin Publish no esta instalado o no se pudo cargar.'];
            return;
        }

        // Verificar si hay accion de grupo
        $action = null;
        foreach (array_keys($this->approvalGroups) as $groupName) {
            if ($INPUT->has('approve_' . $groupName)) {
                $action = $groupName;
                break;
            }
        }

        if (!$action) {
            return;
        }

        // Verificar token de seguridad
        if (!checkSecurityToken()) {
            $this->messages[] = ['type' => 'error', 'msg' => 'Token de seguridad invalido. Por favor recarga la pagina e intenta de nuevo.'];
            return;
        }

        // Aprobar el grupo seleccionado
        $this->approveGroup($action);
    }

    /**
     * Aprueba todas las paginas pendientes de un grupo
     */
    protected function approveGroup($groupName)
    {
        if (!isset($this->approvalGroups[$groupName])) {
            $this->messages[] = ['type' => 'error', 'msg' => "Grupo '$groupName' no encontrado."];
            return;
        }

        $group = $this->approvalGroups[$groupName];
        $namespaces = $group['namespaces'];
        $allPages = [];

        // Obtener paginas pendientes de todos los namespaces del grupo
        foreach ($namespaces as $ns) {
            $pages = $this->getPendingPagesFromNamespace($ns);
            $allPages = array_merge($allPages, $pages);
        }

        if (empty($allPages)) {
            $this->messages[] = ['type' => 'success', 'msg' => "No hay paginas pendientes en el grupo $groupName."];
            return;
        }

        // Aprobar todas las paginas
        $pageIds = array_column($allPages, 0);
        $pageIds = array_unique($pageIds);

        $this->approvePages($pageIds, $groupName);
    }

    /**
     * Obtiene paginas pendientes de un namespace especifico
     */
    protected function getPendingPagesFromNamespace($namespace)
    {
        return $this->publishHelper->getPagesFromNamespace($namespace);
    }

    /**
     * Aprueba una lista de paginas especificas
     */
    protected function approvePages($pageIds, $groupName = '')
    {
        global $ID, $INFO;
        $original_id = $ID;
        $approved = 0;
        $failed = 0;

        foreach ($pageIds as $pageId) {
            $ID = $pageId;
            $INFO = pageinfo();

            if (!$this->publishHelper->canApprove()) {
                $failed++;
                continue;
            }

            if ($this->addApproval($pageId)) {
                $approved++;
            } else {
                $failed++;
            }
        }

        $ID = $original_id;

        $groupText = $groupName ? " del grupo $groupName" : "";
        $this->messages[] = [
            'type' => $approved > 0 ? 'success' : 'warning',
            'msg' => "Aprobacion$groupText completada: $approved paginas aprobadas" . ($failed > 0 ? ", $failed fallidas" : "")
        ];
    }

    /**
     * Agrega aprobacion a una pagina
     */
    protected function addApproval($pageId)
    {
        global $USERINFO, $INFO;

        if (!$INFO['exists']) {
            return false;
        }

        $approvalRevision = $this->publishHelper->getRevision($pageId);
        $approvals = $this->publishHelper->getApprovals($pageId);

        if (!isset($approvals[$approvalRevision])) {
            $approvals[$approvalRevision] = array();
        }

        // Verificar si el usuario ya aprobo esta revision
        foreach ($approvals[$approvalRevision] as $approval) {
            if ($approval[1] == $_SERVER['REMOTE_USER']) {
                return true; // Ya aprobada por este usuario
            }
        }

        $approvals[$approvalRevision][$INFO['client']] = array(
            $INFO['client'],
            $_SERVER['REMOTE_USER'],
            $USERINFO['mail'],
            time()
        );

        return p_set_metadata($pageId, array('approval' => $approvals), true, true);
    }

    /**
     * Renderiza la interfaz de administracion
     */
    public function html()
    {
        echo '<h1>Aprobacion Masiva de Documentos</h1>';

        // Mostrar mensajes
        foreach ($this->messages as $msg) {
            $class = $msg['type'] == 'success' ? 'success' : ($msg['type'] == 'error' ? 'error' : 'info');
            echo '<div class="' . $class . '">' . hsc($msg['msg']) . '</div>';
        }

        if (!$this->publishHelper) {
            echo '<div class="error">El plugin Publish no esta instalado.</div>';
            return;
        }

        // Obtener estadisticas por grupo
        $groupStats = $this->getGroupStatistics();
        $totalPending = array_sum(array_column($groupStats, 'count'));

        // Resumen general
        echo '<div class="level2">';
        echo '<p style="font-size: 16px; margin-bottom: 20px;">';
        echo 'Total de paginas pendientes de aprobacion: <strong>' . $totalPending . '</strong>';
        echo '</p>';
        echo '</div>';

        if ($totalPending == 0) {
            echo '<div class="success" style="padding: 20px; font-size: 16px;">';
            echo '<strong>No hay paginas pendientes de aprobacion.</strong>';
            echo '</div>';
            return;
        }

        // Mostrar grupos de aprobacion
        echo '<div class="level2" style="margin-top: 20px;">';
        echo '<h2>Grupos de Aprobacion</h2>';
        echo '<p style="color: #666; margin-bottom: 20px;">Seleccione un grupo para aprobar todas sus paginas pendientes.</p>';

        echo '<form method="post" action="">';
        echo '<input type="hidden" name="sectok" value="' . getSecurityToken() . '" />';

        echo '<div style="display: flex; flex-wrap: wrap; gap: 20px;">';

        foreach ($this->approvalGroups as $groupName => $group) {
            $stats = $groupStats[$groupName];
            $count = $stats['count'];
            $color = $group['color'];
            $disabled = $count == 0 ? 'disabled' : '';
            $opacity = $count == 0 ? '0.5' : '1';

            echo '<div style="flex: 1; min-width: 300px; max-width: 500px; border: 2px solid ' . $color . '; border-radius: 8px; padding: 20px; opacity: ' . $opacity . ';">';

            // Titulo del grupo
            echo '<h3 style="margin: 0 0 10px 0; color: ' . $color . ';">' . hsc($groupName) . '</h3>';

            // Descripcion
            echo '<p style="color: #666; margin: 0 0 15px 0; font-size: 13px;">' . hsc($group['description']) . '</p>';

            // Estadisticas
            echo '<div style="background: #f5f5f5; padding: 10px; border-radius: 4px; margin-bottom: 15px;">';
            echo '<strong>' . $count . '</strong> paginas pendientes';
            if ($count > 0) {
                echo '<br><small style="color: #888;">en ' . count($group['namespaces']) . ' namespace(s)</small>';
            }
            echo '</div>';

            // Lista de namespaces incluidos
            echo '<div style="margin-bottom: 15px;">';
            echo '<small style="color: #888;">Incluye: ';
            echo implode(', ', array_map('hsc', $group['namespaces']));
            echo '</small>';
            echo '</div>';

            // Boton de aprobar
            echo '<button type="submit" name="approve_' . hsc($groupName) . '" class="button" ' . $disabled . ' ';
            echo 'style="background: ' . $color . '; color: white; padding: 12px 24px; font-size: 14px; width: 100%; border: none; border-radius: 4px; cursor: ' . ($count == 0 ? 'not-allowed' : 'pointer') . ';" ';
            if ($count > 0) {
                echo 'onclick="return confirm(\'¿Esta seguro de aprobar las ' . $count . ' paginas pendientes del grupo ' . hsc($groupName) . '?\');"';
            }
            echo '>';
            echo 'APROBAR ' . hsc($groupName);
            echo '</button>';

            echo '</div>';
        }

        echo '</div>';
        echo '</form>';
        echo '</div>';

        // Detalle de paginas pendientes por namespace
        echo '<div class="level2" style="margin-top: 40px;">';
        echo '<h2>Detalle de Paginas Pendientes</h2>';

        foreach ($this->approvalGroups as $groupName => $group) {
            $stats = $groupStats[$groupName];
            if (empty($stats['pages'])) continue;

            $color = $group['color'];
            echo '<div style="margin-bottom: 30px;">';
            echo '<h3 style="color: ' . $color . '; border-bottom: 2px solid ' . $color . '; padding-bottom: 5px;">';
            echo hsc($groupName) . ' (' . $stats['count'] . ' paginas)';
            echo '</h3>';

            // Agrupar por namespace
            $pagesByNs = [];
            foreach ($stats['pages'] as $page) {
                $ns = getNS($page[0]);
                if ($ns === false || $ns === '') $ns = '(raiz)';
                if (!isset($pagesByNs[$ns])) {
                    $pagesByNs[$ns] = [];
                }
                $pagesByNs[$ns][] = $page;
            }
            ksort($pagesByNs);

            foreach ($pagesByNs as $ns => $pages) {
                $nsId = preg_replace('/[^a-z0-9]/i', '_', $ns);

                echo '<div style="margin-left: 20px; margin-bottom: 15px;">';
                echo '<h4 style="margin: 0; cursor: pointer; background: #f0f0f0; padding: 8px;" onclick="toggleDetail(\'' . $nsId . '\')">';
                echo '<span id="arrow_' . $nsId . '">&#9654;</span> ';
                echo hsc($ns) . ' <span style="color: #888;">(' . count($pages) . ')</span>';
                echo '</h4>';

                echo '<div id="detail_' . $nsId . '" style="display: none; border: 1px solid #ddd; border-top: none;">';
                echo '<table class="inline" style="width: 100%; margin: 0;">';
                echo '<thead><tr><th>Pagina</th><th style="width: 180px;">Ultima Modificacion</th></tr></thead>';
                echo '<tbody>';

                foreach ($pages as $page) {
                    $pageId = $page[0];
                    $lastMod = isset($page[2]) ? $page[2] : 0;
                    echo '<tr>';
                    echo '<td><a href="' . wl($pageId) . '" target="_blank">' . hsc($pageId) . '</a></td>';
                    echo '<td>' . ($lastMod ? dformat($lastMod) : '-') . '</td>';
                    echo '</tr>';
                }

                echo '</tbody></table>';
                echo '</div>';
                echo '</div>';
            }

            echo '</div>';
        }

        echo '</div>';

        // JavaScript
        echo '<script>
        function toggleDetail(nsId) {
            var div = document.getElementById("detail_" + nsId);
            var arrow = document.getElementById("arrow_" + nsId);
            if (div.style.display === "none") {
                div.style.display = "block";
                arrow.innerHTML = "&#9660;";
            } else {
                div.style.display = "none";
                arrow.innerHTML = "&#9654;";
            }
        }
        </script>';
    }

    /**
     * Obtiene estadisticas de paginas pendientes por grupo
     */
    protected function getGroupStatistics()
    {
        $stats = [];

        foreach ($this->approvalGroups as $groupName => $group) {
            $allPages = [];

            foreach ($group['namespaces'] as $ns) {
                $pages = $this->getPendingPagesFromNamespace($ns);
                $allPages = array_merge($allPages, $pages);
            }

            // Eliminar duplicados
            $unique = [];
            foreach ($allPages as $page) {
                $unique[$page[0]] = $page;
            }

            $stats[$groupName] = [
                'count' => count($unique),
                'pages' => array_values($unique)
            ];
        }

        return $stats;
    }
}
