import type { LayerProps } from 'react-map-gl/maplibre'
import type { ClusterLayerOptions } from '../types'

const DEFAULT_COLORS: [string, string, string] = ['#51bbd6', '#f1f075', '#f28cb1']
const DEFAULT_RADII: [number, number, number] = [20, 30, 40]
const DEFAULT_THRESHOLDS: [number, number] = [100, 750]
const DEFAULT_HOVER_COLOR = '#3b82f6' // blue-500

export function createClusterLayers(options: ClusterLayerOptions): {
  cluster: LayerProps
  clusterCount: LayerProps
  unclusteredPoint: LayerProps
} {
  const {
    sourceId,
    colors = DEFAULT_COLORS,
    radii = DEFAULT_RADII,
    thresholds = DEFAULT_THRESHOLDS,
    hoverColor = DEFAULT_HOVER_COLOR,
  } = options

  const cluster: LayerProps = {
    id: `${sourceId}-clusters`,
    type: 'circle',
    source: sourceId,
    filter: ['has', 'point_count'],
    paint: {
      'circle-color': [
        'case',
        ['boolean', ['feature-state', 'hover'], false],
        hoverColor,
        [
          'step',
          ['get', 'point_count'],
          colors[0],
          thresholds[0],
          colors[1],
          thresholds[1],
          colors[2],
        ],
      ],
      'circle-radius': [
        'step',
        ['get', 'point_count'],
        radii[0],
        thresholds[0],
        radii[1],
        thresholds[1],
        radii[2],
      ],
      'circle-stroke-width': 2,
      'circle-stroke-color': '#fff',
    },
  }

  const clusterCount: LayerProps = {
    id: `${sourceId}-cluster-count`,
    type: 'symbol',
    source: sourceId,
    filter: ['has', 'point_count'],
    layout: {
      'text-field': ['get', 'point_count_abbreviated'],
      'text-size': 12,
    },
    paint: {
      'text-color': '#000',
    },
  }

  const unclusteredPoint: LayerProps = {
    id: `${sourceId}-unclustered-point`,
    type: 'circle',
    source: sourceId,
    filter: ['!', ['has', 'point_count']],
    paint: {
      'circle-color': [
        'case',
        ['boolean', ['feature-state', 'hover'], false],
        hoverColor,
        colors[0],
      ],
      'circle-radius': [
        'case',
        ['boolean', ['feature-state', 'hover'], false],
        10,
        8,
      ],
      'circle-stroke-width': 2,
      'circle-stroke-color': '#fff',
    },
  }

  return { cluster, clusterCount, unclusteredPoint }
}
