/** BPMN node dimensions for ELK layout spacing.
 * Ported from Flexicar BPMN_SIZES.
 * - w/h: visual shape dimensions
 * - labelH: space reserved for labels below the shape (gateways, events, data-objects)
 */
export const BPMN_SIZES: Record<
  string,
  { w: number; h: number; labelH: number }
> = {
  "start-event": { w: 36, h: 36, labelH: 32 },
  "end-event": { w: 36, h: 36, labelH: 32 },
  "event-timer": { w: 36, h: 36, labelH: 32 },
  "event-message": { w: 36, h: 36, labelH: 32 },
  "gateway-exclusive": { w: 50, h: 50, labelH: 40 },
  "gateway-parallel": { w: 50, h: 50, labelH: 40 },
  "gateway-inclusive": { w: 50, h: 50, labelH: 40 },
  "data-object": { w: 40, h: 50, labelH: 40 },
  annotation: { w: 220, h: 50, labelH: 0 },
  activity: { w: 240, h: 76, labelH: 0 },
  subprocess: { w: 240, h: 86, labelH: 0 },
};

/** Map DiagramNode.type (with or without bpmn: prefix) to @xyflow/react node type string */
export function resolveBpmnNodeType(type: string): string {
  const bare = type.startsWith("bpmn:") ? type.slice(5) : type;
  switch (bare) {
    case "activity":
      return "bpmnActivity";
    case "subprocess":
      return "bpmnSubprocess";
    case "start-event":
      return "bpmnStartEvent";
    case "end-event":
      return "bpmnEndEvent";
    case "event-timer":
      return "bpmnTimerEvent";
    case "event-message":
      return "bpmnMessageEvent";
    case "gateway-exclusive":
    case "gateway-parallel":
    case "gateway-inclusive":
      return "bpmnGateway";
    case "data-object":
      return "bpmnDataObject";
    case "annotation":
      return "bpmnAnnotation";
    default:
      return "bpmnActivity";
  }
}

/** Map DiagramEdge.type to @xyflow/react edge type string */
export function resolveBpmnEdgeType(type: string | undefined): string {
  switch (type) {
    case "message":
      return "bpmnMessage";
    case "association":
      return "bpmnAssociation";
    case "sequence":
    default:
      return "bpmnSequence";
  }
}

/** Strip the bpmn: prefix to get the bare BPMN type for size lookup */
export function bareBpmnType(type: string): string {
  return type.startsWith("bpmn:") ? type.slice(5) : type;
}

/** Get BPMN node size, falling back to activity dimensions */
export function getBpmnNodeSize(type: string): {
  w: number;
  h: number;
  labelH: number;
} {
  const bare = bareBpmnType(type);
  return BPMN_SIZES[bare] ?? BPMN_SIZES["activity"];
}

/** Whether a BPMN type has its label rendered externally (below the shape) */
export function hasExternalLabel(type: string): boolean {
  const bare = bareBpmnType(type);
  return (
    bare.startsWith("gateway") ||
    bare.startsWith("event") ||
    bare === "start-event" ||
    bare === "end-event" ||
    bare === "data-object"
  );
}
