import type { NpcGroupId, NpcId, ProjectNpc, ProjectNpcGroup } from '../../shared/types'; export function reorderNpcIds( npcs: ProjectNpc[], dragId: NpcId, targetId: NpcId, place: 'before' | 'after', ): NpcId[] { const ids = npcs.map((n) => n.id); const from = ids.indexOf(dragId); if (from < 0) return ids; ids.splice(from, 1); let to = ids.indexOf(targetId); if (to < 0) return npcs.map((n) => n.id); if (place === 'after') to += 1; ids.splice(to, 0, dragId); return ids; } /** Move NPC to end of its group block in global order. */ export function moveNpcToGroupEnd(npcs: ProjectNpc[], dragId: NpcId, groupId: NpcGroupId | null): NpcId[] { const updated = npcs.map((n) => (n.id === dragId ? { ...n, groupId } : n)); const ids = updated.map((n) => n.id); const from = ids.indexOf(dragId); if (from < 0) return ids; ids.splice(from, 1); let insertAt = ids.length; for (let i = ids.length - 1; i >= 0; i -= 1) { const npc = updated.find((n) => n.id === ids[i]); if (npc?.groupId === groupId) { insertAt = i + 1; break; } } if (groupId === null) { for (let i = ids.length - 1; i >= 0; i -= 1) { const npc = updated.find((n) => n.id === ids[i]); if (npc?.groupId === null) { insertAt = i + 1; break; } } } ids.splice(insertAt, 0, dragId); return ids; } export function reorderSiblingGroups( groups: ProjectNpcGroup[], dragId: NpcGroupId, targetId: NpcGroupId, place: 'before' | 'after', ): NpcGroupId[] { const drag = groups.find((g) => g.id === dragId); const target = groups.find((g) => g.id === targetId); if (!drag || drag.parentId !== target?.parentId) return groups.map((g) => g.id); const parentId = drag.parentId; const siblingIds = groups.filter((g) => g.parentId === parentId).map((g) => g.id); const from = siblingIds.indexOf(dragId); if (from < 0) return groups.map((g) => g.id); siblingIds.splice(from, 1); let to = siblingIds.indexOf(targetId); if (to < 0) return groups.map((g) => g.id); if (place === 'after') to += 1; siblingIds.splice(to, 0, dragId); const result: NpcGroupId[] = []; let inserted = false; for (const g of groups) { if (g.parentId === parentId) { if (!inserted) { result.push(...siblingIds); inserted = true; } continue; } result.push(g.id); } return result; } export function flattenGroupOptions( nodes: { group: ProjectNpcGroup; children: unknown[] }[], depth = 0, ): { id: NpcGroupId; label: string }[] { const out: { id: NpcGroupId; label: string }[] = []; for (const node of nodes) { const prefix = depth > 0 ? ' '.repeat(depth) : ''; out.push({ id: node.group.id, label: `${prefix}${node.group.name}` }); out.push(...flattenGroupOptions(node.children as typeof nodes, depth + 1)); } return out; }