import { makeComponentProps } from '@/composables/component'
import { computed, ref } from 'vue'
import { makeRouterProps, useLink } from '@/composables/router'

import { makeTagProps } from '@/composables/tag'
import { UIcon } from '@/components/UIcon/UIcon'
import { UBadge } from '@/components/UBadge/UBadge'

import { genericComponent, propsFactory, useRender } from '@/utils'
import { useEventListener } from '@vueuse/core'

export const makeUListItemProps = propsFactory(
  {
    disabled: {
      type: Boolean,
      default: false,
    },
    key: Number,
    badge: Number,
    itemId: {
      type: String,
      required: true,
    },
    isActive: Boolean,
    prependIcon: String,
    type: {
      type: String,
      default: 'default',
    },
    subTitle: String,
    nav: Boolean,
    ...makeComponentProps(),
    ...makeTagProps(),
    ...makeRouterProps(),
  },
  'UListItem'
)

export type UListItemSlots = {
  default: never
  header: never
}

export const UListItem = genericComponent<UListItemSlots>()({
  name: 'UListItem',

  props: makeUListItemProps(),

  emits: {
    click: (e: MouseEvent) => true,
    currentItemId: (value: string) => true,
    'keydown:enter': () => true,
  },

  setup(props, { emit, slots, attrs }) {
    const link = useLink(props, attrs)
    const isHover = ref(false)
    const isFocused = ref(false)

    const navItemTextClasses = computed(() => ({
      'text-text-md font-semibold select-none whitespace-nowrap': true,
      ...(isHover.value === false && {
        'text-gray-700': true,
      }),
      ...(isHover.value === true &&
        !props.disabled && {
          'text-gray-700': true,
        }),
      ...(props.isActive === true &&
        !props.disabled && {
          'text-gray-700': true,
        }),
    }))

    const listItemClasses = computed(() => ({
      // eslint-disable-next-line max-len
      'flex items-center shrink-0 text-text-md font-semibold select-none text-gray-700 py-3 w-full rounded-md overflow-hidden':
        true,
      ...(!props.disabled && {
        'active:shadow-xs-btn active:shadow-gray-100 cursor-pointer': true,
      }),
      ...(props.disabled && {
        'cursor-not-allowed': true,
      }),
      ...(props.prependIcon != '' && {
        'px-3': true,
      }),
      ...(props.prependIcon === '' && {
        'pr-3 pl-[48px]': true,
      }),
      ...(props.isActive === false &&
        !props.disabled && {
          'active:bg-transparent hover:bg-gray-50': true,
        }),
      ...(props.isActive === true && {
        'bg-gray-200 hover:bg-gray-100 active:bg-gray-50': true,
      }),
      ...(props.type !== 'small' && {
        'justify-between': true,
      }),
      ...(props.type === 'small' && {
        'h-48 max-w-[48px] shrink-0 justify-center': true,
      }),
    }))

    const prependIconColor = () => {
      if (
        (props.isActive === true || isHover.value === true) &&
        !props.disabled
      ) {
        return 'gray-500'
      }
      return 'gray-500'
    }

    function onClick(e: MouseEvent) {
      if (props.disabled) return
      emit('click', e)
      link.navigate?.(e)
    }

    function changeCurrentIndex(id: string) {
      if (props.disabled) return
      emit('currentItemId', id)
    }

    const handleKeyDown = (event: KeyboardEvent) => {
      if (isFocused.value && event.key === 'Enter') {
        emit('keydown:enter')
        changeCurrentIndex(props.itemId)
        event.preventDefault()
      }
    }

    useEventListener('keydown', handleKeyDown)

    useRender(() => {
      const Tag = link.isLink.value ? 'a' : props.tag

      return (
        <Tag
          class={listItemClasses.value}
          href={link.href.value}
          onClick={(event: MouseEvent) => {
            changeCurrentIndex(props.itemId)
            if (onClick && typeof onClick === 'function') {
              onClick(event)
            }
          }}
          onMouseover={() => (isHover.value = true)}
          onMouseleave={() => (isHover.value = false)}
          onFocus={() => (isFocused.value = true)}
          onBlur={() => (isFocused.value = false)}
          onKeydown={handleKeyDown}
        >
          <div class="flex items-center gap-3">
            {props.prependIcon ? (
              <UIcon
                color={prependIconColor()}
                size="24"
                icon={`$${props.prependIcon}`}
              ></UIcon>
            ) : null}
            {slots.default && props.type !== 'small' ? (
              <div class={navItemTextClasses.value}>{slots.default?.()}</div>
            ) : null}
          </div>
          {props.badge && props.type !== 'small' ? (
            <div>
              <UBadge color="gray">{props.badge}</UBadge>
            </div>
          ) : null}
        </Tag>
      )
    })
    return {
      changeCurrentIndex,
      isHover,
    }
  },
})

export type UListItem = InstanceType<typeof UListItem>
