<?php
/**
 * Controlador para ver un Proyecto Administrativo
 *
 * Ruta: es:bez:admin_thread:id:X
 *
 * @author NICC
 * @date 2026-01-31
 */

/** @var \dokuwiki\plugin\bez\meta\action $this */

use dokuwiki\plugin\bez\mdl\AdminThreadFactory;

// Verificar permisos
if ($this->model->get_level() < BEZ_AUTH_USER) {
    throw new \dokuwiki\plugin\bez\meta\PermissionDeniedException();
}

// Obtener ID del proyecto
$id = $this->get_param('id');
if (empty($id)) {
    throw new \Exception('ID de proyecto requerido');
}

// Liberar sesión PHP para evitar bloqueo durante queries pesadas (previene error 520)
if (session_status() === PHP_SESSION_ACTIVE) {
    session_write_close();
}

// Inicializar DB + Factory (consolidado en helper)
list($sqlite, $factory) = helper_plugin_bez_db::initAdmin('AdminThreadFactory');

// ── Permisos específicos para TAREAS ADMINISTRATIVAS ──
// DIOS en admin_thread: manager, admin (grupo DW)
// SIN permisos: director (solo lectura del listado, NO puede operar)
// LEADER: puede operar si es creador o coordinador
$_userGrps = $GLOBALS['USERINFO']['grps'] ?? [];
$_isAdminThreadGod = in_array('manager', $_userGrps) || in_array('admin', $_userGrps)
    || (class_exists('action_plugin_managerprotect') && action_plugin_managerprotect::shouldHaveManagerGroup($_SERVER['REMOTE_USER'] ?? ''));
$_isDirector = in_array('director', $_userGrps);

// Procesar acciones
$action = $this->get_param('action');

// Helper: verificar si el usuario actual puede operar sobre este proyecto.
// Manager/Admin(DW) = DIOS, puede todo.
// Director = NO puede operar (explícitamente excluido).
// LEADER = puede si es creador O coordinador.
$_checkOwnership = function() use ($factory, $id, $_isAdminThreadGod, $_isDirector) {
    if ($_isAdminThreadGod) return true; // Manager/Admin(DW) puede todo
    if ($_isDirector) return false; // Director NO tiene permisos en admin_thread
    // LEADER: solo si es creador o coordinador
    if ($this->model->get_level() < BEZ_AUTH_LEADER) return false;
    $proy = $factory->get($id);
    if (!$proy) return false;
    $currentUser = $_SERVER['REMOTE_USER'] ?? '';
    return ($proy['created_by'] === $currentUser || (!empty($proy['trabajador_id']) && $proy['trabajador_id'] === $currentUser));
};

if ($action === 'delete' && $_checkOwnership()) {
    $factory->delete($id);
    header('Location: ' . $this->url('admin_threads'));
    exit;
}

if ($action === 'close' && $_checkOwnership()) {
    $factory->update($id, ['state' => 'closed']);
    header('Location: ' . $this->url('admin_thread', 'id', $id));
    exit;
}

if ($action === 'reopen' && $_checkOwnership()) {
    $factory->update($id, ['state' => 'opened']);
    header('Location: ' . $this->url('admin_thread', 'id', $id));
    exit;
}

if ($action === 'compilar' && $_checkOwnership()) {
    $factory->update($id, ['state' => 'compilado']);
    header('Location: ' . $this->url('admin_thread', 'id', $id));
    exit;
}

if ($action === 'recalcular' && $_checkOwnership()) {
    $factory->recalcularProgresoDesdeDoPlugin($id);
    header('Location: ' . $this->url('admin_thread', 'id', $id));
    exit;
}

// Recalcular progreso de TODAS las secciones antes de mostrar el proyecto.
// Esto asegura que secciones no interactuadas (total_requerimientos=0)
// se actualicen con las tareas DO reales de sus páginas wiki,
// evitando un porcentaje general inflado por ignorar secciones vacías.
$factory->recalcularProgresoDesdeDoPlugin($id);

// Obtener proyecto (con porcentaje_total ya recalculado)
$proyecto = $factory->get($id);
if (!$proyecto) {
    throw new \Exception('Proyecto no encontrado');
}

// Obtener secciones con progreso
$secciones = $factory->getSecciones($id);

// ── Permisos para UI (botones editar/eliminar/compilar) ──
// DIOS (manager/admin DW): siempre puede editar
// Director: NO puede editar (sin permisos en admin_thread)
// LEADER: puede editar si es creador o trabajador asignado
$puedeEditar = false;
if ($_isAdminThreadGod) {
    $puedeEditar = true;
} elseif (!$_isDirector && $this->model->get_level() >= BEZ_AUTH_LEADER) {
    $currentUser = $_SERVER['REMOTE_USER'] ?? '';
    $puedeEditar = ($proyecto['created_by'] === $currentUser || (!empty($proyecto['trabajador_id']) && $proyecto['trabajador_id'] === $currentUser));
}

// DIOS ya está incluido en $puedeEditar, no necesita OR adicional
$puedeRecalcular = $puedeEditar;
$puedeFinalizar = $puedeEditar;

// Asegurar que las tablas de tareas/comentarios/participantes existan
// (necesario si la migración 30 no corrió por fallo en migración 28)
try {
    $sqlite->query("CREATE TABLE IF NOT EXISTS admin_thread_task (id INTEGER PRIMARY KEY AUTOINCREMENT, admin_thread_id INTEGER NOT NULL, content TEXT NOT NULL, content_html TEXT, assignee TEXT, plan_date TEXT, state TEXT DEFAULT 'opened', created_by TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, closed_at DATETIME, closed_by TEXT, seccion_id INTEGER DEFAULT NULL, FOREIGN KEY (admin_thread_id) REFERENCES admin_thread(id) ON DELETE CASCADE)");
    $sqlite->query("CREATE TABLE IF NOT EXISTS admin_thread_comment (id INTEGER PRIMARY KEY AUTOINCREMENT, admin_thread_id INTEGER NOT NULL, content TEXT NOT NULL, content_html TEXT, author TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT NULL, updated_by TEXT DEFAULT NULL, parent_id INTEGER DEFAULT NULL, FOREIGN KEY (admin_thread_id) REFERENCES admin_thread(id) ON DELETE CASCADE)");
    $sqlite->query("CREATE TABLE IF NOT EXISTS admin_thread_participant (id INTEGER PRIMARY KEY AUTOINCREMENT, admin_thread_id INTEGER NOT NULL, user_id TEXT NOT NULL, role TEXT DEFAULT 'participant', added_by TEXT NOT NULL, added_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE(admin_thread_id, user_id), FOREIGN KEY (admin_thread_id) REFERENCES admin_thread(id) ON DELETE CASCADE)");
} catch (\Exception $e) { /* Ignorar si ya existen */ }

// Cargar tareas, comentarios y participantes del proyecto administrativo
$tareas = [];
$comentarios = [];
$participantes = [];
try {
    $resTareas = $sqlite->query("SELECT * FROM admin_thread_task WHERE admin_thread_id = ? ORDER BY seccion_id ASC, state ASC, created_at DESC", $id);
    $tareas = $sqlite->res2arr($resTareas) ?: [];
} catch (\Exception $e) { /* Tabla puede no existir aún */ }
try {
    $resComentarios = $sqlite->query("SELECT * FROM admin_thread_comment WHERE admin_thread_id = ? ORDER BY created_at ASC", $id);
    $comentarios = $sqlite->res2arr($resComentarios) ?: [];
} catch (\Exception $e) { /* Tabla puede no existir aún */ }
try {
    $resParticipantes = $sqlite->query("SELECT * FROM admin_thread_participant WHERE admin_thread_id = ? ORDER BY role ASC, added_at ASC", $id);
    $participantes = $sqlite->res2arr($resParticipantes) ?: [];

    // Auto-insertar creador si el proyecto no tiene participantes (proyectos creados antes de migración 30)
    if (empty($participantes) && !empty($proyecto['created_by'])) {
        $sqlite->query("INSERT OR IGNORE INTO admin_thread_participant (admin_thread_id, user_id, role, added_by) VALUES (?, ?, 'creator', ?)",
            [$id, $proyecto['created_by'], $proyecto['created_by']]);
        // Recargar
        $resParticipantes = $sqlite->query("SELECT * FROM admin_thread_participant WHERE admin_thread_id = ? ORDER BY role ASC, added_at ASC", $id);
        $participantes = $sqlite->res2arr($resParticipantes) ?: [];
    }
} catch (\Exception $e) { /* Tabla puede no existir aún */ }

// Cargar todos los usuarios del sistema para el dropdown de asignación de tareas
$allUsers = [];
global $auth;
if ($auth && method_exists($auth, 'retrieveUsers')) {
    $userList = $auth->retrieveUsers(0, 0, []);
    if (!empty($userList)) {
        foreach ($userList as $username => $userData) {
            $allUsers[] = [
                'username' => $username,
                'name' => isset($userData['name']) ? $userData['name'] : $username
            ];
        }
        usort($allUsers, function($a, $b) { return strcasecmp($a['username'], $b['username']); });
    }
}

// Mapa username → nombre completo para mostrar en tareas y comentarios
$userNamesMap = [];
foreach ($allUsers as $u) {
    $userNamesMap[$u['username']] = $u['name'];
}

// Verificar si el usuario actual es participante del proyecto
$currentUser = $_SERVER['REMOTE_USER'] ?? '';
$esParticipante = false;
foreach ($participantes as $p) {
    if ($p['user_id'] === $currentUser) {
        $esParticipante = true;
        break;
    }
}

// Mapa de sección ID → nombre para clasificación de tareas
$seccionesMap = [];
foreach ($secciones as $s) {
    $seccionesMap[intval($s['seccion_id'])] = $s['seccion_nombre'];
}

// Pasar datos al template
$this->tpl->set('proyecto', $proyecto);
$this->tpl->set('secciones', $secciones);
$this->tpl->set('seccionesMap', $seccionesMap);
$this->tpl->set('puedeEditar', $puedeEditar);
$this->tpl->set('puedeRecalcular', $puedeRecalcular);
$this->tpl->set('puedeFinalizar', $puedeFinalizar);
$this->tpl->set('tareas', $tareas);
$this->tpl->set('comentarios', $comentarios);
$this->tpl->set('participantes', $participantes);
$this->tpl->set('allUsers', $allUsers);
$this->tpl->set('isAdminThreadGod', $_isAdminThreadGod);
$this->tpl->set('esParticipante', $esParticipante);
$this->tpl->set('currentUser', $currentUser);
$this->tpl->set('userNamesMap', $userNamesMap);
