import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { Plus, Save, Trash2, RotateCcw, Pencil } from 'lucide-react';
import { useUi } from '../../context/ui-context.jsx';
import { useAsync, useAction } from '../../hooks/useAsync.js';
import {
listRecurringTasks, createRecurringTask, updateRecurringTask, deleteRecurringTask,
completeRecurringTaskCycle,
} from '../../services/recurringTasks.js';
import { listUsers } from '../../services/users.js';
import { listProjectOptions } from '../../services/projects.js';
import { ListView } from '../../components/ListView.jsx';
import { Button } from '../../components/Button.jsx';
import { Field, FieldRow } from '../../components/Field.jsx';
import { ComboBox } from '../../components/ComboBox.jsx';
import { Badge } from '../../components/Badge.jsx';
import { DetailPopup } from '../../components/DetailPopup.jsx';
import { DraftNotice } from '../../components/DraftNotice.jsx';
import { DraftMark, useGuardedClose } from '../../components/NavigationGuard.jsx';
import { useDraftForm, useUserDrafts, hasDraftFor, useReopenDraft } from '../../hooks/useDraftForm.js';
const HOUR_OPTIONS = Array.from({ length: 24 }, (_, h) => ({ value: h, label: `${String(h).padStart(2, '0')}:00` }));
const EMPTY_FORM = {
name: '', description: '', projectId: '', responsibleUserId: '',
intervalUnit: 'months', intervalValue: 1, nextDueDate: '', endDate: '',
reminderDaysBefore: 7, reminderHour: 9,
};
function toForm(r) {
return {
name: r.name, description: r.description || '', projectId: r.project_id || '',
responsibleUserId: r.responsible_user_id || '', intervalUnit: r.interval_unit,
intervalValue: r.interval_value, nextDueDate: r.next_due_date, endDate: r.end_date || '',
reminderDaysBefore: r.reminder_days_before, reminderHour: r.reminder_hour, editVersion: r.edit_version,
};
}
export default function RecurringTasksPage() {
const { t, pushToast, openDialog } = useUi();
const runAction = useAction();
const { data: items, reload } = useAsync(listRecurringTasks, []);
const { data: users } = useAsync(listUsers, []);
const { data: projects } = useAsync(listProjectOptions, []);
const [editing, setEditing] = useState(false);
const [selected, setSelected] = useState(null);
const [searchParams, setSearchParams] = useSearchParams();
// Borrador del popup (nueva o edicion de una existente).
const draft = useDraftForm({
formId: selected ? 'recurring-edit' : 'recurring-new', entityId: selected?.id ?? null,
initial: selected ? toForm(selected) : EMPTY_FORM,
label: selected ? `${t('common_edit')}: ${selected.name}` : t('recurring_task_new'), enabled: editing,
});
const form = draft.values;
const setForm = draft.setValues;
const guardedClose = useGuardedClose();
const pendingNew = hasDraftFor(useUserDrafts(), 'recurring-new', null);
useReopenDraft({
newFormId: 'recurring-new', editFormId: 'recurring-edit', items,
openNew: () => startNew(), openEdit: (r) => startEdit(r),
});
const userOptions = (users || []).map((u) => ({ value: u.id, label: u.name }));
const projectOptions = (projects || []).map((p) => ({ value: p.id, label: `${p.code} — ${p.name}` }));
const unitOptions = [
{ value: 'days', label: t('recurring_task_unit_days') },
{ value: 'months', label: t('recurring_task_unit_months') },
{ value: 'years', label: t('recurring_task_unit_years') },
];
const unitLabel = { days: t('recurring_task_unit_days'), months: t('recurring_task_unit_months'), years: t('recurring_task_unit_years') };
// Llegada desde el Calendario (?task=id): abre esa tarea como un clic en su fila.
useEffect(() => {
const id = Number(searchParams.get('task'));
if (!id || !items) return;
const found = items.find((r) => r.id === id);
if (found) startEdit(found);
setSearchParams((prev) => { const next = new URLSearchParams(prev); next.delete('task'); return next; }, { replace: true });
}, [searchParams, items]); // eslint-disable-line react-hooks/exhaustive-deps
function startNew() {
setSelected(null);
setEditing(true);
}
function startEdit(r) {
setSelected(r);
setEditing(true);
}
async function save() {
if (!form.name.trim() || !form.nextDueDate) return;
const run = () => runAction(async () => {
const payload = { ...form, projectId: form.projectId || null, responsibleUserId: form.responsibleUserId || null, endDate: form.endDate || null };
if (selected) await updateRecurringTask(selected.id, payload);
else await createRecurringTask(payload);
draft.clear();
setEditing(false);
pushToast({ tone: 'success', message: t('common_saved') });
await reload();
});
// Edicion: si el registro cambio en el servidor desde que se empezo a editar, se confirma.
if (selected) await draft.guardSave(run); else await run();
}
function confirmDelete(r) {
openDialog({
tone: 'warning',
title: t('common_confirm_delete_title'),
message: t('common_confirm_delete_msg'),
actions: [
{ label: t('common_cancel'), variant: 'standard' },
{
label: t('common_delete'), variant: 'danger',
onClick: () => runAction(async () => { await deleteRecurringTask(r.id); await reload(); }),
},
],
});
}
function confirmComplete(r) {
openDialog({
tone: 'info',
title: t('recurring_task_complete_cycle'),
message: t('recurring_task_complete_confirm'),
actions: [
{ label: t('common_cancel'), variant: 'standard' },
{
label: t('recurring_task_complete_cycle'), variant: 'accent',
onClick: () => runAction(async () => {
await completeRecurringTaskCycle(r.id);
await reload();
pushToast({ tone: 'success', message: t('common_saved') });
}),
},
],
});
}
const columns = [
{ key: 'name', label: t('common_name') },
{ key: 'project_name', label: t('recurring_task_project'), render: (r) => r.project_name || '—' },
{
key: 'interval_value', label: t('recurring_task_interval'),
render: (r) => `${t('recurring_task_every')} ${r.interval_value} ${unitLabel[r.interval_unit]}`,
},
{ key: 'next_due_date', label: t('recurring_task_next_due'), render: (r) => String(r.next_due_date).slice(0, 10) },
{ key: 'end_date', label: t('recurring_task_end_date'), render: (r) => r.end_date ? String(r.end_date).slice(0, 10) : t('recurring_task_unlimited') },
{
key: 'reminder_hour', label: t('recurring_task_reminder'),
render: (r) => `${r.reminder_days_before}d / ${String(r.reminder_hour).padStart(2, '0')}:00`,
},
{ key: 'responsible_name', label: t('common_responsible'), render: (r) => r.responsible_name || '—' },
{ key: 'is_active', label: t('recurring_task_active'), render: (r) =>