import { TaskService } from '../../../tasks/service'; import { ICONS } from '../../../utils/icons'; import { codeId, formatDDMM } from '../../../utils/formatting'; import { parseMultipleIds, resolveTaskIdFromInput, enforceMembership } from '../shared'; type Ctx = { sender: string; groupId: string; message: string; }; type Msg = { recipient: string; message: string; mentions?: string[]; }; export async function handleCompletar(context: Ctx): Promise { const tokens = (context.message || '').trim().split(/\s+/); const { ids, truncated } = parseMultipleIds(tokens.slice(2), 10); // Sin IDs: ayuda de uso if (ids.length === 0) { return [{ recipient: context.sender, message: 'ℹ️ Uso: `/t x 26` o múltiples: `/t x 14 19 24` o `/t x 14,19,24` (máx. 10)' }]; } // Caso de 1 ID: mantener comportamiento actual if (ids.length === 1) { const idInput = ids[0]; const resolvedId = resolveTaskIdFromInput(idInput); if (!resolvedId) { return [{ recipient: context.sender, message: `⚠️ Tarea ${codeId(idInput)} no encontrada.` }]; } const task = TaskService.getTaskById(resolvedId); if (!task) { return [{ recipient: context.sender, message: `⚠️ Tarea ${codeId(resolvedId)} no encontrada.` }]; } if (!enforceMembership(context.sender, task)) { return [{ recipient: context.sender, message: 'No puedes completar esta tarea porque no eres de este grupo.' }]; } const res = TaskService.completeTask(resolvedId, context.sender); const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : ''; if (res.status === 'not_found') { return [{ recipient: context.sender, message: `⚠️ Tarea ${codeId(resolvedId)} no encontrada.` }]; } if (res.status === 'already') { return [{ recipient: context.sender, message: `ℹ️ ${codeId(resolvedId, res.task?.display_code)} _Ya estaba completada_ — ${res.task?.description || '(sin descripción)'}${due}` }]; } return [{ recipient: context.sender, message: `${ICONS.complete} ${codeId(resolvedId, res.task?.display_code)} _completada_ — ${res.task?.description || '(sin descripción)'}${due}` }]; } // Modo múltiple let cntUpdated = 0, cntAlready = 0, cntNotFound = 0, cntBlocked = 0; const lines: string[] = []; if (truncated) { lines.push('⚠️ Se procesarán solo los primeros 10 IDs.'); } for (const idInput of ids) { const resolvedId = resolveTaskIdFromInput(idInput); if (!resolvedId) { lines.push(`⚠️ ${codeId(idInput)} no encontrada.`); cntNotFound++; continue; } const task = TaskService.getTaskById(resolvedId); if (task && !enforceMembership(context.sender, task)) { lines.push(`🚫 ${codeId(resolvedId)} — no permitido (no eres miembro activo).`); cntBlocked++; continue; } const res = TaskService.completeTask(resolvedId, context.sender); const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : ''; if (res.status === 'already') { lines.push(`ℹ️ ${codeId(resolvedId, res.task?.display_code)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}`); cntAlready++; } else if (res.status === 'updated') { lines.push(`${ICONS.complete} ${codeId(resolvedId, res.task?.display_code)} completada — ${res.task?.description || '(sin descripción)'}${due}`); cntUpdated++; } else if (res.status === 'not_found') { lines.push(`⚠️ ${codeId(resolvedId)} no encontrada.`); cntNotFound++; } } // Resumen final const summary: string[] = []; if (cntUpdated) summary.push(`completadas ${cntUpdated}`); if (cntAlready) summary.push(`ya estaban ${cntAlready}`); if (cntNotFound) summary.push(`no encontradas ${cntNotFound}`); if (cntBlocked) summary.push(`bloqueadas ${cntBlocked}`); if (summary.length) { lines.push(''); lines.push(`Resumen: ${summary.join(', ')}.`); } return [{ recipient: context.sender, message: lines.join('\n') }]; }