import type { CircuitGroupCategory } from "../../shared/constants/circuit-group.js"; import { formatCircuitGroupPrefix, getNextGroupedCircuitIdentifier, parseGroupedEquipmentIdentifier, } from "./circuit-group-numbering.js"; export interface CircuitMoveGroupIdentity { id: string; category: CircuitGroupCategory; groupNumber: number; prefix: string; } export interface CircuitGroupMovePlan { circuitId: string; circuitListId: string; expectedSectionId: string; targetSectionId: string; expectedEquipmentIdentifier: string; targetEquipmentIdentifier: string; expectedSortOrder: number; targetSortOrder: number; } export function createCircuitGroupMovePlan(input: { circuit: { id: string; circuitListId: string; sectionId: string; equipmentIdentifier: string; sortOrder: number; }; sourceGroup: CircuitMoveGroupIdentity; targetGroup: CircuitMoveGroupIdentity; targetCircuitEquipmentIdentifiers: Iterable; targetSortOrder: number; }): CircuitGroupMovePlan { assertGroupIdentity(input.sourceGroup); assertGroupIdentity(input.targetGroup); if ( input.sourceGroup.id === input.targetGroup.id || input.sourceGroup.category !== input.targetGroup.category ) { throw new Error( "Circuits can move only between different groups of the same category." ); } if ( input.circuit.sectionId !== input.sourceGroup.id || !input.circuit.id.trim() || !input.circuit.circuitListId.trim() || !Number.isFinite(input.circuit.sortOrder) || !Number.isFinite(input.targetSortOrder) ) { throw new Error("Circuit move source or target position is invalid."); } const parsed = parseGroupedEquipmentIdentifier( input.circuit.equipmentIdentifier ); if ( parsed?.kind !== "circuit" || parsed.category !== input.sourceGroup.category || parsed.groupNumber !== input.sourceGroup.groupNumber ) { throw new Error("Circuit BMK does not match its source group."); } return { circuitId: input.circuit.id, circuitListId: input.circuit.circuitListId, expectedSectionId: input.sourceGroup.id, targetSectionId: input.targetGroup.id, expectedEquipmentIdentifier: input.circuit.equipmentIdentifier, targetEquipmentIdentifier: getNextGroupedCircuitIdentifier( input.targetGroup.category, input.targetGroup.groupNumber, input.targetCircuitEquipmentIdentifiers ), expectedSortOrder: input.circuit.sortOrder, targetSortOrder: input.targetSortOrder, }; } function assertGroupIdentity(group: CircuitMoveGroupIdentity) { if ( !group.id.trim() || !Number.isInteger(group.groupNumber) || group.groupNumber < 1 || group.prefix !== formatCircuitGroupPrefix(group.category, group.groupNumber) ) { throw new Error("Circuit move group identity is invalid."); } }