import { defineComponent, h, PropType } from 'vue'

import type { Option, Search } from './types'

const CMultiSelectSelection = defineComponent({
  name: 'CMultiSelectSelection',
  props: {
    disabled: Boolean,
    multiple: {
      type: Boolean,
      default: true,
    },
    placeholder: String,
    search: {
      type: [Boolean, String, Object] as PropType<Search>,
      default: true,
      validator: (value: boolean | object | string) => {
        if (typeof value == 'boolean') {
          return true
        }
        if (typeof value == 'string') {
          return ['external', 'global'].includes(value)
        }
        if (typeof value === 'object' && value !== null) {
          const validKeys = ['external', 'global']
          const keys = Object.keys(value)
          const allKeysValid = keys.every((key) => validKeys.includes(key))

          if (!allKeysValid) {
            return false
          }

          const allValuesBoolean = keys.every(
            (key) => typeof value[key as keyof typeof value] === 'boolean',
          )

          return allValuesBoolean
        }
        return false
      },
    },
    selected: {
      type: Array as PropType<Option[]>,
      default: () => [],
    },
    selectionType: {
      type: String,
      default: 'tags',
      validator: (value: string) => {
        return ['counter', 'tags', 'text'].includes(value)
      },
    },
    selectionTypeCounterText: {
      type: String,
      default: 'item(s) selected',
    },
  },
  emits: ['remove'],
  setup(props, { emit, slots }) {
    const handleRemove = (option: Option) => {
      emit('remove', option as Option)
    }
    return () =>
      h(
        'div',
        {
          class: [
            'form-multi-select-selection',
            {
              'form-multi-select-selection-tags': props.multiple && props.selectionType === 'tags',
            },
          ],
        },
        [
          props.multiple &&
            props.selectionType === 'counter' &&
            !props.search &&
            props.selected.length === 0 &&
            props.placeholder,
          props.multiple &&
            props.selectionType === 'counter' &&
            !props.search &&
            props.selected.length > 0 &&
            `${props.selected.length} ${props.selectionTypeCounterText}`,
          props.multiple &&
            props.selectionType === 'tags' &&
            props.selected.map((option: Option) => {
              if (props.selectionType === 'tags') {
                return h('span', { class: 'form-multi-select-tag' }, [
                  option.label,
                  !props.disabled &&
                    !option.disabled &&
                    h('button', {
                      class: 'form-multi-select-tag-delete',
                      type: 'button',
                      ariaLabel: 'Close',
                      onClick: () => handleRemove(option),
                    }),
                ])
              }
              return
            }),
          props.multiple &&
            props.selectionType === 'text' &&
            props.selected.map((option, index) =>
              h('span', `${option.label}${index === props.selected.length - 1 ? '' : ','}\xA0`),
            ),
          !props.multiple && !props.search && props.selected.map((option) => option.label)[0],
          slots.default && slots.default(),
        ],
      )
  },
})

export { CMultiSelectSelection }
