import deepmerge from 'deepmerge'
import type { LayerType } from '../../types'
import { DEFAULT_LAYER_PROPS, MapMeasurementUnitTurf } from './const'
import type { MeasurementToolsLayerProps, MeasurementToolsState } from './types'
import type { LayerProps } from '@deck.gl/core'
import { CustomEditableGeojsonLayer } from '../custom-editable-geojson-layer'

/**
 * Creates a layer configuration for the measurement tools editable layer.
 *
 * @returns A `LayerType` object with the `CustomEditableGeojsonLayer` type and merged props.
 */
export function getMeasurementToolsLayer({
  mode,
  ...defaultProps
}: MeasurementToolsLayerProps & {}): LayerType {
  const props = getLayerProps({
    mode,
    ...defaultProps,
  })
  return {
    type: CustomEditableGeojsonLayer,
    props: {
      ...props,
      mode,
      data: [],
    } as unknown as LayerProps,
  }
}

/**
 * Gets the layer props for the MapMeasurementToolsLayer component.
 * @param layerProps - The layer props.
 * @param locale - The locale.
 * @param unit - The unit.
 * @param onHover - The onHover event handler.
 * @param onEdit - The onEdit event handler.
 * @param guideColor - The guide color.
 * @returns The layer props for the component.
 */
function getLayerProps({
  mode,
  layerProps,
  locale,
  enabled,
  unit,
  onEdit,
  guideColor,
  pointColor,
  textOptions,
}: MeasurementToolsLayerProps) {
  const _layerProps = deepmerge(layerProps, {
    visible: enabled,
    pickable: enabled,
    modeConfig: {
      // We force distance due to conversion is addressed at feature getText level
      formatTooltip: (_distance: number) => {
        return _distance
      },
      turfOptions: {
        units: MapMeasurementUnitTurf.meters,
      },
    },
    ...(enabled && { onEdit }),
    _subLayerProps: {
      tooltips: {
        outlineColor: [255, 255, 255, 255],
        outlineWidth: 6,
        fontSettings: {
          sdf: true, // needed for the outlineWidth and outlineColor attributes to be effective
          smoothing: 0.1,
        },
        getText: (properties: { text: MeasurementToolsState['distance'] }) => {
          // @ts-expect-error - fix EditGeoJSON methods
          // eslint-disable-next-line @typescript-eslint/no-unsafe-call
          return mode?.getTooltipText?.({
            meters: properties.text,
            locale,
            unit,
            options: textOptions,
          }) as string
        },
        updateTriggers: {
          getText: [unit, locale, textOptions],
        },
      },
    },
  })
  const defaultLayerProps = deepmerge(DEFAULT_LAYER_PROPS, {
    _subLayerProps: {
      guides: {
        getLineColor: guideColor,
        getFillColor: guideColor.with(3, 20),
      },
    },
    getEditHandlePointColor: pointColor,
    getEditHandlePointOutlineColor: guideColor,
  })

  const props = deepmerge(defaultLayerProps, _layerProps)
  return props
}
