import TrimText from '../TrimText/TrimText'
import { c } from '../../translations/LibraryTranslationService'

export const getTextWidth = (text: string) => {
  const canvas = document.createElement('canvas')
  const context = canvas.getContext('2d')
  if (context) {
    context.font = '12px "Wix Madefor Display", sans-serif'
    return context.measureText(text).width + 16 // For padding on tag (8px left + 8px right)
  }
  return 0
}

export const getPlaceholder = (placeholder?: string) => (
  <TrimText
    customClass='text-purple'
    limit={20}
    text={placeholder || c('none')}
  />
)

// Shared layout defaults/utilities used by ExposedFilter variants
export const DEFAULT_CONTAINER_WIDTH_MOBILE = 240
export const DEFAULT_CONTAINER_WIDTH_DESKTOP = 300
export const DEFAULT_HORIZONTAL_PADDING = 16 + 16
export const DEFAULT_CLEAR_BUTTON_WIDTH = 38
export const DEFAULT_RIGHT_PADDING = 8
export const DEFAULT_MORE_INDICATOR_RESERVED_WIDTH = 40

// This function is used to get the maximum width of the filter container.
export function getMaxFilterContainerWidth(isMobile: boolean): number {
  return (
    (isMobile
      ? DEFAULT_CONTAINER_WIDTH_MOBILE
      : DEFAULT_CONTAINER_WIDTH_DESKTOP) - DEFAULT_HORIZONTAL_PADDING
  )
}

// Return type for the calculateSelectedTagsLayout function
export interface SelectedTagsLayoutResult<ItemType> {
  selectedTags: ItemType[]
  hasMore: boolean
  truncateTagIndex: number
  truncatedTagWidth: number
}

// Refactored to a common function as it will also be used for modal-based and MultiSelect based filter options in ExposedFilterGroup.
// This function is used to calculate the layout of selected tags.
export interface CalculateSelectedTagsLayoutOptions<ItemType> {
  containerMaxWidth: number
  clearButtonWidth?: number
  rightPadding?: number
  moreIndicatorReservedWidth?: number
  getItemLabel: (item: ItemType) => string
}

export function calculateSelectedTagsLayout<ItemType>(
  selectedOptions: ItemType[],
  labelText: string,
  {
    containerMaxWidth,
    clearButtonWidth = DEFAULT_CLEAR_BUTTON_WIDTH,
    rightPadding = DEFAULT_RIGHT_PADDING,
    moreIndicatorReservedWidth = DEFAULT_MORE_INDICATOR_RESERVED_WIDTH,
    getItemLabel,
  }: CalculateSelectedTagsLayoutOptions<ItemType>,
): SelectedTagsLayoutResult<ItemType> {
  const labelWidth = getTextWidth(labelText)
  const currentAvailableWidth =
    containerMaxWidth - labelWidth - clearButtonWidth - rightPadding

  let totalWidth = 0
  const updatedTags: ItemType[] = []
  let truncateLastTagIndex = -1
  let remainingWidthForTruncatedTag = 0

  for (let i = 0; i < selectedOptions.length; i++) {
    const option = selectedOptions[i]
    const tagWidth = getTextWidth(getItemLabel(option))
    const remainingTags = selectedOptions.length - i - 1

    const reservedWidth = remainingTags > 0 ? moreIndicatorReservedWidth : 0

    const gap = updatedTags.length > 1 ? 4 : 0

    if (totalWidth + tagWidth + gap <= currentAvailableWidth - reservedWidth) {
      totalWidth += tagWidth + gap
      updatedTags.push(option)
    } else {
      const remainingSpace =
        currentAvailableWidth - totalWidth - gap - moreIndicatorReservedWidth
      if (remainingSpace >= 20) {
        updatedTags.push(option)
        truncateLastTagIndex = updatedTags.length - 1
        remainingWidthForTruncatedTag = remainingSpace
      }
      break
    }
  }

  return {
    selectedTags: updatedTags,
    hasMore: updatedTags.length < selectedOptions.length,
    truncateTagIndex: truncateLastTagIndex,
    truncatedTagWidth: remainingWidthForTruncatedTag,
  }
}
