type MultiSelectStateLike = {
  isSelecting: boolean;
  startX: number;
  startY: number;
  currentX: number;
  currentY: number;
  selectedAllocationIds: string[];
  selectedResourceIds: string[];
  dateRange: { start: Date; end: Date } | null;
  multiDragDaysDelta: number;
  isMultiDragging: boolean;
  multiDragMode: string;
};

export function createMultiSelectState<TState extends MultiSelectStateLike>(
  currentX: number,
  currentY: number,
  defaults: Pick<
    TState,
    | "selectedAllocationIds"
    | "selectedResourceIds"
    | "dateRange"
    | "multiDragDaysDelta"
    | "isMultiDragging"
    | "multiDragMode"
  >,
): TState {
  return {
    isSelecting: true,
    startX: currentX,
    startY: currentY,
    currentX,
    currentY,
    ...defaults,
  } as TState;
}

export function updateMultiSelectDraft<TState extends MultiSelectStateLike>(
  state: TState,
  currentX: number,
  currentY: number,
): TState {
  return {
    ...state,
    currentX,
    currentY,
  };
}

export function finalizeMultiSelectDraft<TState extends MultiSelectStateLike>(
  state: TState,
  currentX: number,
  currentY: number,
  minDistancePx = 5,
): TState | null {
  const distance = Math.hypot(currentX - state.startX, currentY - state.startY);
  if (distance < minDistancePx) {
    return null;
  }

  return {
    ...state,
    isSelecting: false,
    currentX,
    currentY,
  };
}

export function completeMultiSelectDraft<TState extends MultiSelectStateLike>(
  state: TState,
  currentX: number,
  currentY: number,
  emptyState: TState,
  minDistancePx = 5,
): { nextState: TState; shouldClear: boolean } {
  const finished = finalizeMultiSelectDraft(state, currentX, currentY, minDistancePx);
  if (!finished) {
    return {
      nextState: emptyState,
      shouldClear: true,
    };
  }

  return {
    nextState: finished,
    shouldClear: false,
  };
}
