import type { NativeMultiTransformHistoryStep, NativeTopologyHistoryInput, NativeTopologyHistoryRecord, ShapeHandle, SubshapeRef } from './types'
import type { NativeStageNamingEvidence } from './nativeNamingEvidence'
import type { NativeFreeCadNamingAbiModule } from './nativeNamingAbi'

export type NativeOcctMultiTransformStep = NativeMultiTransformHistoryStep

export type NativeOcctHistoryRecord = {
  relation: 'modified' | 'generated' | 'deleted'
  /** Legacy values are object/tool; newer providers may use an inputId. */
  source: string
  sourceId?: string
  sourceStageId?: string
  resultStageId?: string
  kind: string
  resultKind?: string
  sourceIndex: number
  resultIndex?: number
  resultIndexes?: number[]
}

export type NativeOcctHistoryStage = {
  stageId: string
  operation?: NativeOcctHistoryOperation
  inputIds: string[]
  resultStageId?: string
  ordinal: number
}

export type NativeOcctHistoryResponse = {
  provider: 'occt-native'
  occtVersion: string
  resultStep?: string
  /** Native OCCT BREP preserves pcurves that STEP round-trips may omit. */
  resultBrep?: string
  summary?: {
    shapeType: string
    isNull: boolean
    isValid: boolean
    solids: number
    faces: number
    edges: number
    vertices: number
    volume: number
    area: number
    boundingBox: { min: [number, number, number]; max: [number, number, number] }
  }
  records: NativeOcctHistoryRecord[]
  hasModified: boolean
  hasGenerated: boolean
  hasDeleted: boolean
  stages?: NativeOcctHistoryStage[]
  /** Optional FreeCAD MappedNameRef/StringHasher evidence from a native provider. */
  namingEvidence?: NativeStageNamingEvidence
}

export type NativeOcctHistoryOperation = 'fuse' | 'cut' | 'common' | 'rotate' | 'pad' | 'pocket' | 'loft' | 'pipe' | 'revolution' | 'groove' | 'fillet' | 'chamfer' | 'hole' | 'draft' | 'thickness' | 'linear-pattern' | 'polar-pattern' | 'mirrored' | 'multi-transform'

export type NativeOcctHistoryStepProvider = NativeFreeCadNamingAbiModule & {
  occtVersion(): string
  booleanHistoryFromStep(objectStep: string, toolStep: string, operation: NativeOcctHistoryOperation): NativeOcctHistoryResponse
  rotateHistoryFromStep?(shapeStep: string, axisOriginX: number, axisOriginY: number, axisOriginZ: number, axisDirectionX: number, axisDirectionY: number, axisDirectionZ: number, angleDegrees: number): NativeOcctHistoryResponse
  prismHistoryFromStep?(profileStep: string, dx: number, dy: number, dz: number): NativeOcctHistoryResponse
  pocketHistoryFromStep?(baseStep: string, profileStep: string, dx: number, dy: number, dz: number): NativeOcctHistoryResponse
  loftHistoryFromStep?(firstSectionStep: string, secondSectionStep: string, ruled: boolean): NativeOcctHistoryResponse
  pipeHistoryFromStep?(profileStep: string, spineStep: string): NativeOcctHistoryResponse
  revolutionHistoryFromStep?(profileStep: string, axisOriginX: number, axisOriginY: number, axisOriginZ: number, axisDirectionX: number, axisDirectionY: number, axisDirectionZ: number, angleDegrees: number): NativeOcctHistoryResponse
  grooveHistoryFromStep?(baseStep: string, profileStep: string, axisOriginX: number, axisOriginY: number, axisOriginZ: number, axisDirectionX: number, axisDirectionY: number, axisDirectionZ: number, angleDegrees: number): NativeOcctHistoryResponse
  filletHistoryFromStep?(baseStep: string, radius: number): NativeOcctHistoryResponse
  chamferHistoryFromStep?(baseStep: string, distance: number): NativeOcctHistoryResponse
  holeHistoryFromStep?(baseStep: string, radius: number, depth: number, positionX: number, positionY: number, positionZ: number, directionX: number, directionY: number, directionZ: number): NativeOcctHistoryResponse
  draftHistoryFromStep?(baseStep: string, faceIndex: number, angle: number, directionX: number, directionY: number, directionZ: number, neutralPlaneOriginX: number, neutralPlaneOriginY: number, neutralPlaneOriginZ: number, neutralPlaneDirectionX: number, neutralPlaneDirectionY: number, neutralPlaneDirectionZ: number, reversed: boolean): NativeOcctHistoryResponse
  thicknessHistoryFromStep?(baseStep: string, faceIndex: number, offset: number, intersectionJoin: boolean): NativeOcctHistoryResponse
  linearPatternHistoryFromStep?(baseStep: string, dx: number, dy: number, dz: number): NativeOcctHistoryResponse
  polarPatternHistoryFromStep?(baseStep: string, axisOriginX: number, axisOriginY: number, axisOriginZ: number, axisDirectionX: number, axisDirectionY: number, axisDirectionZ: number, angleDegrees: number): NativeOcctHistoryResponse
  mirroredHistoryFromStep?(baseStep: string, planeOriginX: number, planeOriginY: number, planeOriginZ: number, planeNormalX: number, planeNormalY: number, planeNormalZ: number): NativeOcctHistoryResponse
  multiTransformHistoryFromStep?(baseStep: string, steps: NativeOcctMultiTransformStep[]): NativeOcctHistoryResponse
}

export type NativeOcctHistoryStepGeometry = {
  exportStep(shape: ShapeHandle, fileName?: string): Promise<{ format: 'step'; fileName: string; mediaType: string; text: string }>
}

const kinds: SubshapeRef['kind'][] = ['vertex', 'edge', 'face']
const isKind = (value: string): value is SubshapeRef['kind'] => kinds.includes(value as SubshapeRef['kind'])

export const mapNativeOcctHistoryRecords = (
  response: NativeOcctHistoryResponse,
  sourceObjectIds: { object: string; tool: string } | Record<string, string>,
  stageContext?: Pick<NativeTopologyHistoryInput, 'inputs' | 'stages'>,
): NativeTopologyHistoryRecord[] => {
  if (response.provider !== 'occt-native' || !/^8\./.test(response.occtVersion)) throw new Error('Unsupported native OCCT history provider response.')
  const observed = new Set(response.records.map((record) => record.relation))
  if (observed.has('modified') && response.hasModified !== true) throw new Error('Native OCCT history modified flag is inconsistent with records.')
  if (observed.has('generated') && response.hasGenerated !== true) throw new Error('Native OCCT history generated flag is inconsistent with records.')
  if (observed.has('deleted') && response.hasDeleted !== true) throw new Error('Native OCCT history deleted flag is inconsistent with records.')
  const mapped: NativeTopologyHistoryRecord[] = []
  const grouped = new Map<string, NativeTopologyHistoryRecord>()
  for (const record of response.records) {
    if (!isKind(record.kind)) throw new Error(`Unsupported native OCCT subshape kind: ${record.kind}`)
    if (!Number.isSafeInteger(record.sourceIndex) || record.sourceIndex < 0) throw new RangeError('Native OCCT sourceIndex must be a non-negative safe integer.')
    const sourceLookup = sourceObjectIds as Record<string, string>
    const sourceObjectId = record.sourceId ? sourceLookup[record.sourceId] : sourceLookup[record.source]
    if (!sourceObjectId) throw new Error(`Missing native OCCT source object ID for ${record.source}.`)
    const resultIndexes = record.resultIndexes ?? (record.resultIndex === undefined ? undefined : [record.resultIndex])
    if (record.relation === 'deleted') {
      const deleted: NativeTopologyHistoryRecord = {
        sourceObjectId,
        sourceKind: record.kind,
        sourceIndex: record.sourceIndex,
        relation: 'deleted',
        ...(record.sourceStageId ? { sourceStageId: record.sourceStageId } : {}),
        ...(record.resultStageId ? { resultStageId: record.resultStageId } : {}),
      }
      const key = [deleted.relation, deleted.sourceObjectId, deleted.sourceKind, deleted.sourceIndex, deleted.sourceStageId ?? '', deleted.resultStageId ?? ''].join('|')
      if (!grouped.has(key)) {
        grouped.set(key, deleted)
        mapped.push(deleted)
      }
      continue
    }
    if (!resultIndexes?.length || resultIndexes.some((index) => !Number.isSafeInteger(index) || index < 0)) throw new RangeError('Native OCCT resultIndexes must contain non-negative safe integers.')
    if (record.resultKind !== undefined && !isKind(record.resultKind)) throw new Error(`Unsupported native OCCT result kind: ${record.resultKind}`)
    const normalizedIndexes = [...new Set(resultIndexes)]
    const current: NativeTopologyHistoryRecord = {
      sourceObjectId,
      sourceKind: record.kind,
      sourceIndex: record.sourceIndex,
      relation: record.relation,
      resultKind: (record.resultKind as SubshapeRef['kind'] | undefined) ?? record.kind,
      resultIndexes: normalizedIndexes,
      ...(record.sourceStageId ? { sourceStageId: record.sourceStageId } : {}),
      ...(record.resultStageId ? { resultStageId: record.resultStageId } : {}),
    }
    const key = [current.relation, current.sourceObjectId, current.sourceKind, current.sourceIndex, current.resultKind ?? '', current.sourceStageId ?? '', current.resultStageId ?? ''].join('|')
    const previous = grouped.get(key)
    if (previous && previous.relation !== 'deleted') {
      previous.resultIndexes = [...new Set([...(previous.resultIndexes ?? []), ...normalizedIndexes])]
    } else if (!previous) {
      grouped.set(key, current)
      mapped.push(current)
    }
  }
  const resultStageId = stageContext?.stages?.length
    ? [...stageContext.stages].sort((left, right) => right.ordinal - left.ordinal)[0].stageId
    : undefined
  if (!resultStageId && !stageContext?.inputs.some((input) => input.stageId)) return mapped
  return mapped.map((record) => {
    const sourceStageId = record.sourceStageId ?? stageContext?.inputs.find((input) => input.objectId === record.sourceObjectId)?.stageId
    return {
      ...record,
      ...(sourceStageId ? { sourceStageId } : {}),
      ...(record.resultStageId || resultStageId ? { resultStageId: record.resultStageId ?? resultStageId } : {}),
    }
  })
}

/**
 * Adapts Bitbybit STEP exports to the standalone OCCT history WASM module.
 * ShapeHandle values never cross this boundary; only versioned STEP text does.
 */
export const createNativeOcctStepHistoryBridge = (
  geometry: NativeOcctHistoryStepGeometry,
  provider: NativeOcctHistoryStepProvider,
) => async (input: NativeTopologyHistoryInput): Promise<NativeTopologyHistoryRecord[]> => {
  if (!input.operation) throw new Error('Native OCCT STEP history requires a supported operation.')
  if (input.operation === 'rotate') {
    const axisOrigin = input.axisOrigin
    const direction = input.direction
    const angle = input.angle
    if (input.inputs.length !== 1 || !axisOrigin || axisOrigin.some((value) => !Number.isFinite(value)) || !direction || direction.some((value) => !Number.isFinite(value)) || Math.hypot(...direction) <= 0 || typeof angle !== 'number' || !Number.isFinite(angle) || angle === 0 || Math.abs(angle) > 360) throw new Error('Native OCCT STEP Rotate history requires one shape, a finite axis and a non-zero angle within 360 degrees.')
    if (!provider.rotateHistoryFromStep) throw new Error('Native OCCT history provider does not expose Rotate history.')
    const [shapeInput] = input.inputs
    const shapeStep = await geometry.exportStep(shapeInput.shape, `${shapeInput.objectId}.step`)
    if (shapeStep.format !== 'step' || typeof shapeStep.text !== 'string') throw new Error('Bitbybit STEP export returned an invalid Rotate transport payload.')
    const response = provider.rotateHistoryFromStep(shapeStep.text, ...axisOrigin, ...direction, angle)
    return mapNativeOcctHistoryRecords(response, { object: shapeInput.objectId, tool: shapeInput.objectId }, input)
  }
  if (input.operation === 'pad') {
    if (input.inputs.length !== 1 || !input.direction || input.direction.some((value) => !Number.isFinite(value)) || Math.hypot(...input.direction) <= 0) throw new Error('Native OCCT STEP Pad history requires one profile and a finite non-zero direction.')
    if (!provider.prismHistoryFromStep) throw new Error('Native OCCT history provider does not expose Pad history.')
    const [profileInput] = input.inputs
    const profileStep = await geometry.exportStep(profileInput.shape, `${profileInput.objectId}.step`)
    if (profileStep.format !== 'step' || typeof profileStep.text !== 'string') throw new Error('Bitbybit STEP export returned an invalid Pad profile transport payload.')
    const response = provider.prismHistoryFromStep(profileStep.text, ...input.direction)
    return mapNativeOcctHistoryRecords(response, { object: profileInput.objectId, tool: profileInput.objectId }, input)
  }
  if (input.operation === 'pocket') {
    if (input.inputs.length !== 2 || !input.direction || input.direction.some((value) => !Number.isFinite(value)) || Math.hypot(...input.direction) <= 0) throw new Error('Native OCCT STEP Pocket history requires a base, profile and finite non-zero direction.')
    if (!provider.pocketHistoryFromStep) throw new Error('Native OCCT history provider does not expose Pocket history.')
    const [baseInput, profileInput] = input.inputs
    const [baseStep, profileStep] = await Promise.all([
      geometry.exportStep(baseInput.shape, `${baseInput.objectId}.step`),
      geometry.exportStep(profileInput.shape, `${profileInput.objectId}.step`),
    ])
    if (baseStep.format !== 'step' || profileStep.format !== 'step' || typeof baseStep.text !== 'string' || typeof profileStep.text !== 'string') throw new Error('Bitbybit STEP export returned an invalid Pocket transport payload.')
    const response = provider.pocketHistoryFromStep(baseStep.text, profileStep.text, ...input.direction)
    return mapNativeOcctHistoryRecords(response, { object: baseInput.objectId, tool: profileInput.objectId }, input)
  }
  if (input.operation === 'loft') {
    if (input.inputs.length !== 2) throw new Error('Native OCCT STEP Loft history requires exactly two section inputs.')
    if (!provider.loftHistoryFromStep) throw new Error('Native OCCT history provider does not expose Loft history.')
    const [firstInput, secondInput] = input.inputs
    const [firstStep, secondStep] = await Promise.all([
      geometry.exportStep(firstInput.shape, `${firstInput.objectId}.step`),
      geometry.exportStep(secondInput.shape, `${secondInput.objectId}.step`),
    ])
    if (firstStep.format !== 'step' || secondStep.format !== 'step' || typeof firstStep.text !== 'string' || typeof secondStep.text !== 'string') throw new Error('Bitbybit STEP export returned an invalid Loft transport payload.')
    const response = provider.loftHistoryFromStep(firstStep.text, secondStep.text, input.ruled === true)
    return mapNativeOcctHistoryRecords(response, { object: firstInput.objectId, tool: secondInput.objectId }, input)
  }
  if (input.operation === 'pipe') {
    if (input.inputs.length !== 2) throw new Error('Native OCCT STEP Pipe history requires exactly one profile and one spine input.')
    if (!provider.pipeHistoryFromStep) throw new Error('Native OCCT history provider does not expose Pipe history.')
    const [profileInput, spineInput] = input.inputs
    const [profileStep, spineStep] = await Promise.all([
      geometry.exportStep(profileInput.shape, `${profileInput.objectId}.step`),
      geometry.exportStep(spineInput.shape, `${spineInput.objectId}.step`),
    ])
    if (profileStep.format !== 'step' || spineStep.format !== 'step' || typeof profileStep.text !== 'string' || typeof spineStep.text !== 'string') throw new Error('Bitbybit STEP export returned an invalid Pipe transport payload.')
    const response = provider.pipeHistoryFromStep(profileStep.text, spineStep.text)
    return mapNativeOcctHistoryRecords(response, { object: profileInput.objectId, tool: spineInput.objectId }, input)
  }
  if (input.operation === 'revolution') {
    if (input.inputs.length !== 1) throw new Error('Native OCCT STEP Revolution history requires one profile, a finite axis and an angle in (0, 360].')
    const axisOrigin = input.axisOrigin
    const direction = input.direction
    const angle = input.angle
    if (!axisOrigin || axisOrigin.some((value) => !Number.isFinite(value))) throw new Error('Native OCCT STEP Revolution history requires a finite axis origin.')
    if (!direction || direction.some((value) => !Number.isFinite(value)) || Math.hypot(...direction) <= 0) throw new Error('Native OCCT STEP Revolution history requires a finite non-zero axis direction.')
    if (typeof angle !== 'number' || !Number.isFinite(angle) || angle <= 0 || angle > 360) throw new Error('Native OCCT STEP Revolution history requires an angle in (0, 360].')
    if (!provider.revolutionHistoryFromStep) throw new Error('Native OCCT history provider does not expose Revolution history.')
    const [profileInput] = input.inputs
    const profileStep = await geometry.exportStep(profileInput.shape, `${profileInput.objectId}.step`)
    if (profileStep.format !== 'step' || typeof profileStep.text !== 'string') throw new Error('Bitbybit STEP export returned an invalid Revolution profile transport payload.')
    const response = provider.revolutionHistoryFromStep(profileStep.text, ...axisOrigin, ...direction, angle)
    return mapNativeOcctHistoryRecords(response, { object: profileInput.objectId, tool: profileInput.objectId }, input)
  }
  if (input.operation === 'groove') {
    if (input.inputs.length !== 2) throw new Error('Native OCCT STEP Groove history requires a base, profile, finite axis and angle in (0, 360].')
    const axisOrigin = input.axisOrigin
    const direction = input.direction
    const angle = input.angle
    if (!axisOrigin || axisOrigin.some((value) => !Number.isFinite(value))) throw new Error('Native OCCT STEP Groove history requires a finite axis origin.')
    if (!direction || direction.some((value) => !Number.isFinite(value)) || Math.hypot(...direction) <= 0) throw new Error('Native OCCT STEP Groove history requires a finite non-zero axis direction.')
    if (typeof angle !== 'number' || !Number.isFinite(angle) || angle <= 0 || angle > 360) throw new Error('Native OCCT STEP Groove history requires an angle in (0, 360].')
    if (!provider.grooveHistoryFromStep) throw new Error('Native OCCT history provider does not expose Groove history.')
    const [baseInput, profileInput] = input.inputs
    const [baseStep, profileStep] = await Promise.all([
      geometry.exportStep(baseInput.shape, `${baseInput.objectId}.step`),
      geometry.exportStep(profileInput.shape, `${profileInput.objectId}.step`),
    ])
    if (baseStep.format !== 'step' || profileStep.format !== 'step' || typeof baseStep.text !== 'string' || typeof profileStep.text !== 'string') throw new Error('Bitbybit STEP export returned an invalid Groove transport payload.')
    const response = provider.grooveHistoryFromStep(baseStep.text, profileStep.text, ...axisOrigin, ...direction, angle)
    return mapNativeOcctHistoryRecords(response, { object: baseInput.objectId, tool: profileInput.objectId }, input)
  }
  if (input.operation === 'fillet') {
    if (input.inputs.length !== 1 || typeof input.radius !== 'number' || !Number.isFinite(input.radius) || input.radius <= 0) throw new Error('Native OCCT STEP Fillet history requires one base and a finite positive radius.')
    if (!provider.filletHistoryFromStep) throw new Error('Native OCCT history provider does not expose Fillet history.')
    const [baseInput] = input.inputs
    const baseStep = await geometry.exportStep(baseInput.shape, `${baseInput.objectId}.step`)
    if (baseStep.format !== 'step' || typeof baseStep.text !== 'string') throw new Error('Bitbybit STEP export returned an invalid Fillet transport payload.')
    const response = provider.filletHistoryFromStep(baseStep.text, input.radius)
    return mapNativeOcctHistoryRecords(response, { object: baseInput.objectId, tool: baseInput.objectId }, input)
  }
  if (input.operation === 'chamfer') {
    if (input.inputs.length !== 1 || typeof input.distance !== 'number' || !Number.isFinite(input.distance) || input.distance <= 0) throw new Error('Native OCCT STEP Chamfer history requires one base and a finite positive distance.')
    if (!provider.chamferHistoryFromStep) throw new Error('Native OCCT history provider does not expose Chamfer history.')
    const [baseInput] = input.inputs
    const baseStep = await geometry.exportStep(baseInput.shape, `${baseInput.objectId}.step`)
    if (baseStep.format !== 'step' || typeof baseStep.text !== 'string') throw new Error('Bitbybit STEP export returned an invalid Chamfer transport payload.')
    const response = provider.chamferHistoryFromStep(baseStep.text, input.distance)
    return mapNativeOcctHistoryRecords(response, { object: baseInput.objectId, tool: baseInput.objectId }, input)
  }
  if (input.operation === 'hole') {
    const position = input.position
    const direction = input.direction
    if (input.inputs.length !== 1 || typeof input.radius !== 'number' || !Number.isFinite(input.radius) || input.radius <= 0 || typeof input.depth !== 'number' || !Number.isFinite(input.depth) || input.depth <= 0 || !position || position.some((value) => !Number.isFinite(value)) || !direction || direction.some((value) => !Number.isFinite(value)) || Math.hypot(...direction) <= 0) throw new Error('Native OCCT STEP Hole history requires one base, finite positive radius/depth, position and direction.')
    if (!provider.holeHistoryFromStep) throw new Error('Native OCCT history provider does not expose Hole history.')
    const [baseInput] = input.inputs
    const baseStep = await geometry.exportStep(baseInput.shape, `${baseInput.objectId}.step`)
    if (baseStep.format !== 'step' || typeof baseStep.text !== 'string') throw new Error('Bitbybit STEP export returned an invalid Hole transport payload.')
    const response = provider.holeHistoryFromStep(baseStep.text, input.radius, input.depth, ...position, ...direction)
    return mapNativeOcctHistoryRecords(response, { object: baseInput.objectId, tool: baseInput.objectId }, input)
  }
  if (input.operation === 'draft') {
    if (input.inputs.length !== 1 || !input.faceIndexes || input.faceIndexes.length !== 1 || !Number.isSafeInteger(input.faceIndexes[0]) || input.faceIndexes[0] < 0 || typeof input.angle !== 'number' || !Number.isFinite(input.angle) || input.angle === 0 || input.angle <= -89.999 || input.angle >= 89.999 || !input.direction || input.direction.some((value) => !Number.isFinite(value)) || Math.hypot(...input.direction) <= 0 || !input.axisOrigin || input.axisOrigin.some((value) => !Number.isFinite(value)) || !input.neutralPlaneDirection || input.neutralPlaneDirection.some((value) => !Number.isFinite(value)) || Math.hypot(...input.neutralPlaneDirection) <= 0) throw new Error('Native OCCT STEP Draft history requires one base, one face index, finite angle, direction and neutral plane.')
    if (!provider.draftHistoryFromStep) throw new Error('Native OCCT history provider does not expose Draft history.')
    const [baseInput] = input.inputs
    const baseStep = await geometry.exportStep(baseInput.shape, `${baseInput.objectId}.step`)
    const response = provider.draftHistoryFromStep(baseStep.text, input.faceIndexes[0], input.angle, ...input.direction, ...input.axisOrigin, ...input.neutralPlaneDirection, input.reversed === true)
    return mapNativeOcctHistoryRecords(response, { object: baseInput.objectId, tool: baseInput.objectId }, input)
  }
  if (input.operation === 'thickness') {
    if (input.inputs.length !== 1 || !input.faceIndexes || input.faceIndexes.length !== 1 || !Number.isSafeInteger(input.faceIndexes[0]) || input.faceIndexes[0] < 0 || typeof input.offset !== 'number' || !Number.isFinite(input.offset) || input.offset === 0 || (input.joinType !== undefined && input.joinType !== 'Arc' && input.joinType !== 'Intersection')) throw new Error('Native OCCT STEP Thickness history requires one base, one face index, finite non-zero offset and a supported join type.')
    if (!provider.thicknessHistoryFromStep) throw new Error('Native OCCT history provider does not expose Thickness history.')
    const [baseInput] = input.inputs
    const baseStep = await geometry.exportStep(baseInput.shape, `${baseInput.objectId}.step`)
    const response = provider.thicknessHistoryFromStep(baseStep.text, input.faceIndexes[0], input.offset, input.joinType === 'Intersection')
    return mapNativeOcctHistoryRecords(response, { object: baseInput.objectId, tool: baseInput.objectId }, input)
  }
  if (input.operation === 'linear-pattern') {
    if (input.inputs.length !== 1 || !input.direction || input.direction.some((value) => !Number.isFinite(value)) || Math.hypot(...input.direction) <= 0) throw new Error('Native OCCT STEP LinearPattern history requires one base and a finite non-zero translation vector.')
    if (!provider.linearPatternHistoryFromStep) throw new Error('Native OCCT history provider does not expose LinearPattern history.')
    const [baseInput] = input.inputs
    const baseStep = await geometry.exportStep(baseInput.shape, `${baseInput.objectId}.step`)
    const response = provider.linearPatternHistoryFromStep(baseStep.text, ...input.direction)
    return mapNativeOcctHistoryRecords(response, { object: baseInput.objectId, tool: baseInput.objectId }, input)
  }
  if (input.operation === 'polar-pattern') {
    if (input.inputs.length !== 1 || !input.axisOrigin || input.axisOrigin.some((value) => !Number.isFinite(value)) || !input.direction || input.direction.some((value) => !Number.isFinite(value)) || Math.hypot(...input.direction) <= 0 || typeof input.angle !== 'number' || !Number.isFinite(input.angle) || input.angle === 0 || Math.abs(input.angle) > 360) throw new Error('Native OCCT STEP PolarPattern history requires one base, a finite axis and a non-zero angle within 360 degrees.')
    if (!provider.polarPatternHistoryFromStep) throw new Error('Native OCCT history provider does not expose PolarPattern history.')
    const [baseInput] = input.inputs
    const baseStep = await geometry.exportStep(baseInput.shape, `${baseInput.objectId}.step`)
    const response = provider.polarPatternHistoryFromStep(baseStep.text, ...input.axisOrigin, ...input.direction, input.angle)
    return mapNativeOcctHistoryRecords(response, { object: baseInput.objectId, tool: baseInput.objectId }, input)
  }
  if (input.operation === 'mirrored') {
    if (input.inputs.length !== 1 || !input.axisOrigin || input.axisOrigin.some((value) => !Number.isFinite(value)) || !input.direction || input.direction.some((value) => !Number.isFinite(value)) || Math.hypot(...input.direction) <= 0) throw new Error('Native OCCT STEP Mirrored history requires one base and a finite mirror plane.')
    if (!provider.mirroredHistoryFromStep) throw new Error('Native OCCT history provider does not expose Mirrored history.')
    const [baseInput] = input.inputs
    const baseStep = await geometry.exportStep(baseInput.shape, `${baseInput.objectId}.step`)
    const response = provider.mirroredHistoryFromStep(baseStep.text, ...input.axisOrigin, ...input.direction)
    return mapNativeOcctHistoryRecords(response, { object: baseInput.objectId, tool: baseInput.objectId }, input)
  }
  if (input.operation === 'multi-transform') {
    if (input.inputs.length !== 1) throw new Error('Native OCCT STEP MultiTransform history requires one base and supported transform steps.')
    const [baseInput] = input.inputs
    const baseStep = await geometry.exportStep(baseInput.shape, `${baseInput.objectId}.step`)
    if (input.transforms && input.transforms.length >= 2) {
      if (!provider.multiTransformHistoryFromStep) throw new Error('Native OCCT history provider does not expose ordered MultiTransform history.')
      return mapNativeOcctHistoryRecords(provider.multiTransformHistoryFromStep(baseStep.text, input.transforms), { object: baseInput.objectId, tool: baseInput.objectId }, input)
    }
    if (!input.transformKind || !['linear', 'polar', 'mirrored'].includes(input.transformKind)) throw new Error('Native OCCT STEP MultiTransform history requires one supported transform step.')
    let response: NativeOcctHistoryResponse
    if (input.transformKind === 'linear') {
      if (!input.direction || input.direction.some((value) => !Number.isFinite(value)) || Math.hypot(...input.direction) <= 0 || !provider.linearPatternHistoryFromStep) throw new Error('Native OCCT STEP MultiTransform linear history requires a finite non-zero translation vector.')
      response = provider.linearPatternHistoryFromStep(baseStep.text, ...input.direction)
    } else if (input.transformKind === 'polar') {
      if (!input.axisOrigin || input.axisOrigin.some((value) => !Number.isFinite(value)) || !input.direction || input.direction.some((value) => !Number.isFinite(value)) || Math.hypot(...input.direction) <= 0 || typeof input.angle !== 'number' || !Number.isFinite(input.angle) || input.angle === 0 || Math.abs(input.angle) > 360 || !provider.polarPatternHistoryFromStep) throw new Error('Native OCCT STEP MultiTransform polar history requires a finite axis and a non-zero angle within 360 degrees.')
      response = provider.polarPatternHistoryFromStep(baseStep.text, ...input.axisOrigin, ...input.direction, input.angle)
    } else if (input.transformKind === 'mirrored') {
      if (!input.axisOrigin || input.axisOrigin.some((value) => !Number.isFinite(value)) || !input.direction || input.direction.some((value) => !Number.isFinite(value)) || Math.hypot(...input.direction) <= 0 || !provider.mirroredHistoryFromStep) throw new Error('Native OCCT STEP MultiTransform mirrored history requires a finite mirror plane.')
      response = provider.mirroredHistoryFromStep(baseStep.text, ...input.axisOrigin, ...input.direction)
    } else throw new Error('Native OCCT STEP MultiTransform history requires one supported transform step.')
    return mapNativeOcctHistoryRecords(response, { object: baseInput.objectId, tool: baseInput.objectId }, input)
  }
  if (input.inputs.length !== 2) throw new Error('Native OCCT STEP history requires exactly an object and a tool input.')
  const [objectInput, toolInput] = input.inputs
  const [objectStep, toolStep] = await Promise.all([
    geometry.exportStep(objectInput.shape, `${objectInput.objectId}.step`),
    geometry.exportStep(toolInput.shape, `${toolInput.objectId}.step`),
  ])
  if (objectStep.format !== 'step' || toolStep.format !== 'step' || typeof objectStep.text !== 'string' || typeof toolStep.text !== 'string') {
    throw new Error('Bitbybit STEP export returned an invalid transport payload.')
  }
  const response = provider.booleanHistoryFromStep(objectStep.text, toolStep.text, input.operation)
  return mapNativeOcctHistoryRecords(response, { object: objectInput.objectId, tool: toolInput.objectId }, input)
}
