<template>
  <svg
    ref="svgRef"
    data-testid="curve-editor"
    viewBox="-0.04 -0.04 1.08 1.08"
    preserveAspectRatio="xMidYMid meet"
    :class="
      cn(
        'aspect-square w-full rounded-[5px] bg-node-component-surface',
        disabled ? 'cursor-default' : 'cursor-crosshair'
      )
    "
    @pointerdown.stop="onSvgPointerDown"
    @contextmenu.prevent.stop
  >
    <line
      v-for="v in [0.25, 0.5, 0.75]"
      :key="'h' + v"
      :x1="0"
      :y1="v"
      :x2="1"
      :y2="v"
      stroke="currentColor"
      stroke-opacity="0.1"
      stroke-width="0.003"
    />
    <line
      v-for="v in [0.25, 0.5, 0.75]"
      :key="'v' + v"
      :x1="v"
      :y1="0"
      :x2="v"
      :y2="1"
      stroke="currentColor"
      stroke-opacity="0.1"
      stroke-width="0.003"
    />

    <line
      x1="0"
      y1="1"
      x2="1"
      y2="0"
      stroke="currentColor"
      stroke-opacity="0.15"
      stroke-width="0.003"
    />

    <path
      v-if="histogramPath"
      data-testid="histogram-path"
      :d="histogramPath"
      :fill="curveColor"
      fill-opacity="0.15"
      stroke="none"
    />

    <path
      data-testid="curve-path"
      :d="curvePath"
      fill="none"
      :stroke="curveColor"
      stroke-width="0.008"
      stroke-linecap="round"
      :opacity="disabled ? 0.5 : 1"
    />

    <template v-if="!disabled">
      <circle
        v-for="(point, i) in modelValue"
        :key="i"
        data-testid="curve-point"
        :cx="point[0]"
        :cy="1 - point[1]"
        r="0.02"
        :fill="curveColor"
        stroke="white"
        stroke-width="0.004"
        class="cursor-grab"
        @pointerdown.stop="startDrag(i, $event)"
      />
    </template>
  </svg>
</template>

<script setup lang="ts">
import { computed, toRef, useTemplateRef } from 'vue'

import { useCurveEditor } from '@/composables/useCurveEditor'
import { cn } from '@comfyorg/tailwind-utils'

import type { CurveInterpolation, CurvePoint } from './types'

import { histogramToPath } from '@/utils/histogramUtil'

const {
  curveColor = 'white',
  histogram,
  disabled = false,
  interpolation = 'monotone_cubic'
} = defineProps<{
  curveColor?: string
  histogram?: Uint32Array | null
  disabled?: boolean
  interpolation?: CurveInterpolation
}>()

const modelValue = defineModel<CurvePoint[]>({
  required: true
})

const svgRef = useTemplateRef<SVGSVGElement>('svgRef')

const { curvePath, handleSvgPointerDown, startDrag } = useCurveEditor({
  svgRef,
  modelValue,
  interpolation: toRef(() => interpolation)
})

function onSvgPointerDown(e: PointerEvent) {
  if (!disabled) handleSvgPointerDown(e)
}

const histogramPath = computed(() =>
  histogram ? histogramToPath(histogram) : ''
)
</script>
