// ================================
// INTENCIONES DE ORACIÓN
// Ámbitos: personal / parroquia / grupo
// Requiere: api-config.js, auth.js
// ================================
const iconos = ["vela.png", "flor.png", "cruz.png"];
let ambitoActual = "personal";
let grupoActualId = null;
let usuario = null;
// ── INICIALIZACIÓN ──────────────────────────────────────────
function init() {
usuario = verificarAuth();
if (!usuario) return; // verificarAuth ya redirige a login si no hay sesión
migrarDifuntosAnonimos();
configurarPestanas();
configurarSelectorGrupo();
cargarIntenciones();
document.getElementById("btn-guardar").addEventListener("click", guardarIntencion);
document.getElementById("nueva-intencion").addEventListener("keydown", e => {
if (e.key === "Enter") guardarIntencion();
});
document.getElementById("btn-guardar-difunto").addEventListener("click", agregarDifunto);
document.getElementById("difunto-nombre").addEventListener("keydown", e => {
if (e.key === "Enter") agregarDifunto();
});
}
// ── PESTAÑAS ────────────────────────────────────────────────
function configurarPestanas() {
// Mostrar pestaña de parroquia si el usuario pertenece a una
if (usuario.parroquia) {
const tabParroquia = document.getElementById("tab-parroquia");
tabParroquia.style.display = "";
tabParroquia.textContent = `⛪ ${usuario.parroquia.nombre}`;
}
// Mostrar pestaña de comunidad si el usuario tiene grupos
if (usuario.grupos && usuario.grupos.length > 0) {
document.getElementById("tab-grupo").style.display = "";
}
document.querySelectorAll(".pestana").forEach(btn => {
btn.addEventListener("click", () => {
document.querySelectorAll(".pestana").forEach(b => b.classList.remove("activa"));
btn.classList.add("activa");
ambitoActual = btn.dataset.ambito;
const esDifuntos = ambitoActual === "difuntos";
document.getElementById("panel-difuntos").style.display = esDifuntos ? "block" : "none";
document.getElementById("formulario-intencion").style.display = esDifuntos ? "none" : "flex";
document.getElementById("muro-intenciones").style.display = esDifuntos ? "none" : "flex";
document.getElementById("sin-intenciones").style.display = "none";
if (esDifuntos) {
cargarDifuntos();
} else {
actualizarSelectorGrupo();
cargarIntenciones();
}
});
});
}
// ── SELECTOR DE GRUPO ───────────────────────────────────────
function configurarSelectorGrupo() {
if (!usuario.grupos || usuario.grupos.length === 0) return;
const select = document.getElementById("select-grupo");
usuario.grupos.forEach(g => {
const option = document.createElement("option");
option.value = g.id;
option.textContent = g.nombre;
select.appendChild(option);
});
grupoActualId = usuario.grupos[0].id;
select.addEventListener("change", () => {
grupoActualId = parseInt(select.value);
cargarIntenciones();
});
}
function actualizarSelectorGrupo() {
const selector = document.getElementById("selector-grupo");
selector.style.display = ambitoActual === "grupo" ? "block" : "none";
}
// La clave del fallback de intenciones también es por usuario
function keyIntenciones() {
return `intenciones_${usuario ? usuario.id : "anonimo"}`;
}
// ── CARGA DE INTENCIONES ─────────────────────────────────────
async function cargarIntenciones() {
const muro = document.getElementById("muro-intenciones");
const sinIntenciones = document.getElementById("sin-intenciones");
muro.innerHTML = "";
let endpoint;
if (ambitoActual === "personal") {
endpoint = "/intenciones/personales";
} else if (ambitoActual === "parroquia") {
endpoint = `/intenciones/parroquia/${usuario.parroquia.id}`;
} else {
if (!grupoActualId) return;
endpoint = `/intenciones/grupo/${grupoActualId}`;
}
try {
const response = await apiCall(endpoint);
if (!response || !response.ok) {
sinIntenciones.style.display = "block";
return;
}
const intenciones = await response.json();
if (intenciones.length === 0) {
sinIntenciones.style.display = "block";
return;
}
sinIntenciones.style.display = "none";
intenciones.forEach(i => crearHexagono(i));
} catch (e) {
// Si no hay conexión, mostrar las intenciones personales del localStorage como fallback
if (ambitoActual === "personal") {
const local = JSON.parse(localStorage.getItem(keyIntenciones()) || localStorage.getItem("intenciones") || "[]");
if (local.length === 0) {
sinIntenciones.style.display = "block";
} else {
local.forEach(i => crearHexagono({ texto: i.texto, icono: i.icono, esPropia: true }));
}
} else {
sinIntenciones.style.display = "block";
}
}
}
// ── GUARDAR INTENCIÓN ────────────────────────────────────────
async function guardarIntencion() {
const input = document.getElementById("nueva-intencion");
const texto = input.value.trim();
if (!texto) return;
const icono = iconos[Math.floor(Math.random() * iconos.length)];
const body = { texto, icono, ambito: ambitoActual };
if (ambitoActual === "parroquia") body.parroquiaId = usuario.parroquia.id;
if (ambitoActual === "grupo") body.grupoId = grupoActualId;
try {
const response = await apiCall("/intenciones", {
method: "POST",
body: JSON.stringify(body)
});
if (response && response.ok) {
const nueva = await response.json();
crearHexagono({ ...nueva, esPropia: true });
document.getElementById("sin-intenciones").style.display = "none";
}
} catch (e) {
// Fallback local solo para intenciones personales
if (ambitoActual === "personal") {
const local = JSON.parse(localStorage.getItem(keyIntenciones()) || "[]");
local.push({ texto, icono });
localStorage.setItem(keyIntenciones(), JSON.stringify(local));
crearHexagono({ texto, icono, esPropia: true, id: null });
document.getElementById("sin-intenciones").style.display = "none";
}
}
input.value = "";
}
// ── HEXÁGONO ─────────────────────────────────────────────────
function crearHexagono(intencion) {
const muro = document.getElementById("muro-intenciones");
const hex = document.createElement("div");
hex.className = "hexagono";
hex.dataset.texto = intencion.texto;
hex.dataset.icono = intencion.icono || iconos[0];
hex.dataset.autor = intencion.autorNombre || "";
hex.dataset.id = intencion.id || "";
hex.dataset.esPropia = intencion.esPropia || (intencion.usuarioId === usuario?.id) ? "true" : "false";
hex.innerHTML = ``;
muro.appendChild(hex);
}
// ── DIFUNTOS ─────────────────────────────────────────────────
// Caché en memoria para evitar peticiones redundantes
let _difuntosCache = null;
let _mesDifuntos = new Date().getMonth(); // 0-11, mes visible actualmente
const MESES_ES = ['Enero','Febrero','Marzo','Abril','Mayo','Junio',
'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'];
async function _apiGetDifuntos() {
try {
const res = await apiCall('/difuntos/personales');
if (!res || !res.ok) throw new Error('Error al cargar difuntos');
const data = await res.json();
_difuntosCache = data;
// Sincronizar localStorage como caché offline
localStorage.setItem(keyDifuntos(), JSON.stringify(data));
return data;
} catch (e) {
// Fallback a localStorage si no hay conexión
return JSON.parse(localStorage.getItem(keyDifuntos()) || '[]');
}
}
// La clave incluye el id del usuario para que cada cuenta tenga sus propios difuntos
function keyDifuntos() {
return `difuntos_personales_${usuario ? usuario.id : 'anonimo'}`;
}
// Migra los difuntos guardados anónimamente al usuario actual via API
async function migrarDifuntosAnonimos() {
const claveAnonima = 'difuntos_personales_anonimo';
const anonimos = JSON.parse(localStorage.getItem(claveAnonima) || '[]');
if (anonimos.length === 0) return;
let migrados = 0;
for (const d of anonimos) {
try {
const res = await apiCall('/difuntos/personales', {
method: 'POST',
body: JSON.stringify({
nombre: d.nombre,
nacimiento: d.nacimiento || null,
defuncion: d.defuncion || null
})
});
if (res && res.ok) migrados++;
} catch (e) { /* si falla uno, continuar con el siguiente */ }
}
if (migrados > 0) {
localStorage.removeItem(claveAnonima);
_difuntosCache = null;
}
}
async function agregarDifunto() {
const nombre = document.getElementById("difunto-nombre").value.trim();
if (!nombre) return;
const nacimiento = document.getElementById("difunto-nacimiento").value || null;
const defuncion = document.getElementById("difunto-defuncion").value || null;
try {
const res = await apiCall('/difuntos/personales', {
method: 'POST',
body: JSON.stringify({ nombre, nacimiento, defuncion })
});
if (res && res.ok) {
_difuntosCache = null; // invalidar caché
} else {
// Guardar local si falla
const difuntos = JSON.parse(localStorage.getItem(keyDifuntos()) || '[]');
difuntos.push({ id: Date.now().toString(), nombre, nacimiento, defuncion });
localStorage.setItem(keyDifuntos(), JSON.stringify(difuntos));
}
} catch (e) {
const difuntos = JSON.parse(localStorage.getItem(keyDifuntos()) || '[]');
difuntos.push({ id: Date.now().toString(), nombre, nacimiento, defuncion });
localStorage.setItem(keyDifuntos(), JSON.stringify(difuntos));
}
document.getElementById("difunto-nombre").value = "";
document.getElementById("difunto-nacimiento").value = "";
document.getElementById("difunto-defuncion").value = "";
cargarDifuntos();
}
async function eliminarDifunto(id) {
try {
const res = await apiCall(`/difuntos/personales/${id}`, { method: 'DELETE' });
if (res && (res.ok || res.status === 204)) {
_difuntosCache = null;
// Sincronizar localStorage
const local = JSON.parse(localStorage.getItem(keyDifuntos()) || '[]');
localStorage.setItem(keyDifuntos(), JSON.stringify(local.filter(d => String(d.id) !== String(id))));
return;
}
} catch (e) { /* sin conexión: eliminar solo local */ }
// Fallback: solo localStorage
const difuntos = JSON.parse(localStorage.getItem(keyDifuntos()) || '[]').filter(d => String(d.id) !== String(id));
localStorage.setItem(keyDifuntos(), JSON.stringify(difuntos));
}
async function cargarDifuntos() {
const lista = document.getElementById("lista-difuntos");
const sinDifuntos = document.getElementById("sin-difuntos");
const todos = _difuntosCache || await _apiGetDifuntos();
// Actualizar navegador de mes
const navMes = document.getElementById("nav-mes-difuntos");
if (navMes) {
document.getElementById("nombre-mes-difuntos").textContent = MESES_ES[_mesDifuntos];
}
// Filtrar por mes seleccionado
const mesNum = _mesDifuntos + 1; // 1-12
const difuntos = todos.filter(d => {
const nacMes = d.nacimiento ? parseInt(d.nacimiento.split('-')[1]) : null;
const defMes = d.defuncion ? parseInt(d.defuncion.split('-')[1]) : null;
return nacMes === mesNum || defMes === mesNum;
});
lista.innerHTML = "";
if (difuntos.length === 0) {
sinDifuntos.style.display = "block";
sinDifuntos.textContent = `No hay difuntos con fechas en ${MESES_ES[_mesDifuntos]}.`;
return;
}
sinDifuntos.style.display = "none";
difuntos.forEach(d => {
const li = document.createElement("li");
li.className = "item-difunto";
const etiquetas = [];
if (d.nacimiento) {
const f = new Date(d.nacimiento + "T12:00:00");
etiquetas.push(`🎂 ${f.toLocaleDateString("es-ES", { day: "numeric", month: "long", year: "numeric" })}`);
}
if (d.defuncion) {
const f = new Date(d.defuncion + "T12:00:00");
let edadStr = "";
if (d.nacimiento && !d.nacimiento.includes('XXXX')) {
const nac = new Date(d.nacimiento + "T12:00:00");
let edad = f.getFullYear() - nac.getFullYear();
const cumpleEseAnio = new Date(f.getFullYear(), nac.getMonth(), nac.getDate());
if (f < cumpleEseAnio) edad--;
if (edad >= 0) edadStr = ` · ${edad} años`;
}
etiquetas.push(`✝ ${f.toLocaleDateString("es-ES", { day: "numeric", month: "long", year: "numeric" })}${edadStr}`);
}
li.innerHTML = `