import createPlanegcs from '/native/planegcs/freecad-planegcs.js'

let modulePromise

const getModule = () => {
  modulePromise ??= createPlanegcs()
  return modulePromise
}

self.addEventListener('message', async (event) => {
  const { requestId, operation, input } = event.data ?? {}
  if (!requestId || !['solve-horizontal-distance', 'solve-vertical-distance', 'solve-distance-x', 'solve-distance-y', 'solve-angle', 'solve-circle-radius', 'solve-circle-diameter', 'solve-equal-lines', 'solve-equal-circles', 'solve-tangent-circles', 'solve-point-symmetry', 'solve-point-on-line', 'solve-point-on-circle', 'solve-point-on-arc', 'solve-point-on-ellipse', 'solve-point-on-cubic-bspline', 'solve-cubic-bspline-weight', 'solve-parallel-lines', 'solve-perpendicular-lines', 'solve-coincident-lines', 'solve-coincident-line-points', 'solve-snells-law-lines', 'solve-ellipse-internal-alignment'].includes(operation)) {
    self.postMessage({ requestId, ok: false, error: 'Unsupported planegcs Worker request.' })
    return
  }
  try {
    const module = await getModule()
    const result = operation === 'solve-vertical-distance'
      ? module.solveVerticalDistance(input.startX, input.startY, input.endX, input.endY, input.targetLength)
      : operation === 'solve-distance-x'
        ? module.solveDistanceX(input.startX, input.startY, input.endX, input.endY, input.targetDistance)
      : operation === 'solve-distance-y'
        ? module.solveDistanceY(input.startX, input.startY, input.endX, input.endY, input.targetDistance)
      : operation === 'solve-angle'
        ? module.solveAngle(input.startX, input.startY, input.endX, input.endY, input.targetLength, input.targetAngle)
      : operation === 'solve-circle-radius'
        ? module.solveCircleRadius(input.centerX, input.centerY, input.radius, input.targetRadius)
      : operation === 'solve-circle-diameter'
        ? module.solveCircleDiameter(input.centerX, input.centerY, input.radius, input.targetDiameter)
      : operation === 'solve-equal-lines'
        ? module.solveEqualLines(input.firstStartX, input.firstStartY, input.firstEndX, input.firstEndY, input.secondStartX, input.secondStartY, input.secondEndX, input.secondEndY)
      : operation === 'solve-equal-circles'
        ? module.solveEqualCircles(input.firstCenterX, input.firstCenterY, input.firstRadius, input.secondCenterX, input.secondCenterY, input.secondRadius)
      : operation === 'solve-tangent-circles'
        ? module.solveTangentCircles(input.firstCenterX, input.firstCenterY, input.firstRadius, input.secondCenterX, input.secondCenterY, input.secondRadius)
      : operation === 'solve-point-symmetry'
        ? module.solvePointSymmetry(input.firstX, input.firstY, input.secondX, input.secondY, input.centerX, input.centerY)
      : operation === 'solve-point-on-line'
        ? module.solvePointOnLine(input.pointX, input.pointY, input.startX, input.startY, input.endX, input.endY, input.vertical)
      : operation === 'solve-point-on-circle'
        ? module.solvePointOnCircle(input.pointX, input.pointY, input.centerX, input.centerY, input.radius)
      : operation === 'solve-point-on-arc'
        ? module.solvePointOnArc(input.pointX, input.pointY, input.centerX, input.centerY, input.radius, input.startAngle, input.endAngle)
      : operation === 'solve-point-on-ellipse'
        ? module.solvePointOnEllipse(input.pointX, input.pointY, input.centerX, input.centerY, input.focusX, input.focusY, input.minorRadius)
      : operation === 'solve-point-on-cubic-bspline'
        ? module.solvePointOnCubicBspline(input.pointX, input.pointY, input.pole0X, input.pole0Y, input.pole1X, input.pole1Y, input.pole2X, input.pole2Y, input.pole3X, input.pole3Y, input.pointParameter)
      : operation === 'solve-cubic-bspline-weight'
        ? module.solveCubicBsplineWeight(input.pole0X, input.pole0Y, input.pole1X, input.pole1Y, input.pole2X, input.pole2Y, input.pole3X, input.pole3Y, input.weight0, input.weight1, input.weight2, input.weight3, input.controlPointIndex, input.targetWeight)
      : operation === 'solve-parallel-lines'
        ? module.solveParallelLines(input.firstStartX, input.firstStartY, input.firstEndX, input.firstEndY, input.secondStartX, input.secondStartY, input.secondEndX, input.secondEndY, input.secondLength)
        : operation === 'solve-coincident-lines'
          ? module.solveCoincidentLines(input.firstStartX, input.firstStartY, input.firstEndX, input.firstEndY, input.secondStartX, input.secondStartY, input.secondEndX, input.secondEndY, input.secondLength)
          : operation === 'solve-coincident-line-points'
            ? module.solveCoincidentLinePoints(input.firstStartX, input.firstStartY, input.firstEndX, input.firstEndY, input.secondStartX, input.secondStartY, input.secondEndX, input.secondEndY, input.secondLength, input.firstEnd, input.secondEnd)
          : operation === 'solve-snells-law-lines'
            ? module.solveSnellsLawLines(input.firstStartX, input.firstStartY, input.firstEndX, input.firstEndY, input.secondStartX, input.secondStartY, input.secondEndX, input.secondEndY, input.boundaryStartX, input.boundaryStartY, input.boundaryEndX, input.boundaryEndY, input.refractiveRatio, input.firstEnd, input.secondEnd)
          : operation === 'solve-ellipse-internal-alignment'
            ? module.solveEllipseInternalAlignment(input.centerX, input.centerY, input.majorRadius, input.minorRadius, input.rotation, input.alignmentType)
          : operation === 'solve-perpendicular-lines'
            ? module.solvePerpendicularLines(input.firstStartX, input.firstStartY, input.firstEndX, input.firstEndY, input.secondStartX, input.secondStartY, input.secondEndX, input.secondEndY, input.secondLength)
          : module.solveHorizontalDistance(input.startX, input.startY, input.endX, input.endY, input.targetLength)
    const values = Array.from({ length: result.size() }, (_, index) => result.get(index))
    result.delete()
    self.postMessage({ requestId, ok: true, values })
  } catch (error) {
    self.postMessage({ requestId, ok: false, error: error instanceof Error ? `${error.name}: ${error.message}` : String(error) })
  }
})
