import {
  ShapeUtil,
  TLHandle,
  TLShapePartial,
  Rectangle2d,
  HTMLContainer,
  IndexKey,
} from 'tldraw'
import { KreiselShape, kreiselShapeProps } from './shape-types'
import { KREISEL_CONFIG as CFG } from './shape-config'

/**
 * Kreisel: Zwei Kreise (links/rechts) mit tangentialen Verbindungslinien.
 * Handles im Zentrum beider Kreise zum Ändern des Abstands.
 */
export class KreiselShapeUtil extends ShapeUtil<KreiselShape> {
  static override type = 'kreisel' as const
  static override props = kreiselShapeProps

  getDefaultProps(): KreiselShape['props'] {
    return { abstand: CFG.defaultAbstand, radius: CFG.defaultRadius, label: 'Kreisel' }
  }

  getGeometry(shape: KreiselShape) {
    const { abstand, radius } = shape.props
    return new Rectangle2d({
      width: 2 * radius + abstand,
      height: 2 * radius,
      isFilled: false,
    })
  }

  override canResize() {
    return false
  }

  override onRotate(initial: KreiselShape, current: KreiselShape): TLShapePartial<KreiselShape> {
    const HALF_PI = Math.PI / 2
    const snapped = Math.round(current.rotation / HALF_PI) * HALF_PI
    return { id: current.id, type: 'kreisel', x: initial.x, y: initial.y, rotation: snapped }
  }

  override getHandles(shape: KreiselShape): TLHandle[] {
    const { abstand, radius } = shape.props
    return [
      {
        id: 'left',
        type: 'vertex',
        x: radius,
        y: radius,
        index: 'a1' as IndexKey,
        canSnap: true,
      },
      {
        id: 'right',
        type: 'vertex',
        x: radius + abstand,
        y: radius,
        index: 'a2' as IndexKey,
        canSnap: true,
      },
    ]
  }

  override onHandleDrag(
    shape: KreiselShape,
    { handle }: { handle: TLHandle }
  ): TLShapePartial<KreiselShape> | void {
    const r = shape.props.radius

    if (handle.id === 'right') {
      const newAbstand = Math.min(CFG.maxAbstand, Math.max(CFG.minAbstand, handle.x - r))
      return {
        id: shape.id,
        type: 'kreisel',
        props: { ...shape.props, abstand: newAbstand },
      }
    }

    if (handle.id === 'left') {
      const oldRightX = r + shape.props.abstand
      const raw = oldRightX - handle.x
      const newAbstand = Math.min(CFG.maxAbstand, Math.max(CFG.minAbstand, raw))
      const dx = shape.props.abstand - newAbstand
      return {
        id: shape.id,
        type: 'kreisel',
        x: shape.x + dx,
        props: { ...shape.props, abstand: newAbstand },
      }
    }
  }

  component(shape: KreiselShape) {
    const { abstand, radius: r } = shape.props
    const totalW = 2 * r + abstand
    const totalH = 2 * r

    return (
      <HTMLContainer>
        <svg
          width={totalW}
          height={totalH}
          style={{ overflow: 'visible' }}
        >
          {/* Linker Kreis */}
          <circle cx={r} cy={r} r={r} fill="none" stroke="black" strokeWidth={2} />
          {/* Rechter Kreis */}
          <circle cx={r + abstand} cy={r} r={r} fill="none" stroke="black" strokeWidth={2} />
          {/* Obere Tangentiallinie */}
          <line x1={r} y1={0} x2={r + abstand} y2={0} stroke="black" strokeWidth={2} />
          {/* Untere Tangentiallinie */}
          <line x1={r} y1={totalH} x2={r + abstand} y2={totalH} stroke="black" strokeWidth={2} />
          {/* Label */}
          <text
            x={totalW / 2}
            y={r}
            textAnchor="middle"
            dominantBaseline="central"
            fontSize={36}
            fill="#666"
            style={{ pointerEvents: 'none', userSelect: 'none' }}
          >
            {shape.props.label}
          </text>
        </svg>
      </HTMLContainer>
    )
  }

  indicator(shape: KreiselShape) {
    const { abstand, radius: r } = shape.props
    return (
      <rect
        x={0}
        y={0}
        width={2 * r + abstand}
        height={2 * r}
      />
    )
  }
}
