import '@/components/UNotification/transition.scss'
import { ExtractPropTypes, watch, computed, Transition } from 'vue'

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

import { makeComponentProps } from '@/composables/component'
import { makeTagProps } from '@/composables/tag'

import { UIcon } from '@/components'

import { useNotification } from '@/components'

export const makeUNotificationProps = propsFactory(
  {
    ...makeComponentProps(),
    ...makeTagProps(),
  },
  'UNotification'
)

export type UNotificationProps = ExtractPropTypes<typeof makeUNotificationProps>

export type UNotificationSlots = {
  default: never
  notificationTitle: never
  notificationSubtitle: never
  notificationText: never
  notificationButtons: never
}

export const UNotification = genericComponent<UNotificationSlots>()({
  name: 'UNotification',

  props: makeUNotificationProps(),

  setup(props, { slots }) {
    const $useNotification = useNotification()

    const isActive = computed(() => {
      return $useNotification.isActive.value
    })

    const delay = computed(() => {
      return $useNotification?.currentNotification.value?.delay || 5000
    })

    const elevation = computed(() => {
      return (
        'shadow-' + $useNotification?.currentNotification.value?.elevation || ''
      )
    })

    const position = computed(() => {
      return (
        $useNotification?.currentNotification.value?.position || 'bottomRight'
      )
    })

    const iconLeft = computed(() => {
      return $useNotification?.currentNotification.value?.iconLeft || undefined
    })

    const iconTop = computed(() => {
      return $useNotification?.currentNotification.value?.iconTop || undefined
    })

    const color = computed(() => {
      return (
        $useNotification?.currentNotification.value?.color + '-600' ||
        'primary-600'
      )
    })

    const transformClasses = computed(() => {
      if (position.value === 'topLeft') return 'top-[24px] left-[24px]'
      if (position.value === 'topRight') return 'top-[24px] right-[24px]'
      if (position.value === 'bottomLeft') return 'bottom-[24px] left-[24px]'
      if (position.value === 'bottomRight') return 'bottom-[24px] right-[24px]'
      return ''
    })

    const transitionName = computed(() => {
      if (position.value === 'topLeft' || position.value === 'bottomLeft')
        return 'slide-in-from-left'
      if (position.value === 'topRight' || position.value === 'bottomRight')
        return 'slide-in-from-right'
      return ''
    })

    const classes = computed(() => [
      `fixed w-fit p-4 bg-white rounded-lg border border-gray-100 z-50`,
      props.class,
      elevation.value,
      transformClasses.value,
    ])

    const onClose = () => {
      $useNotification.close()
    }

    let closingTimer = 0
    watch(
      () => isActive.value,
      (newIsActive) => {
        if (newIsActive) {
          closingTimer = setTimeout(() => {
            $useNotification.close()
          }, delay.value)
        } else {
          clearTimeout(closingTimer)
        }
      }
    )

    useRender(() => (
      <Transition name={transitionName.value}>
        {isActive.value ? (
          <div class={classes.value} style={props.style}>
            <div
              class="close absolute p-2 top-8 right-8 cursor-pointer"
              onClick={onClose}
            >
              <UIcon color="gray-500" size="20">
                xClose
              </UIcon>
            </div>
            <div class="flex flex-col gap-3 pr-10">
              {iconTop.value ? (
                <UIcon
                  variant="lightCircleOutline"
                  size="20"
                  color={color.value}
                >
                  {iconTop.value}
                </UIcon>
              ) : null}
              <div class="flex gap-[16px]">
                {iconLeft.value ? (
                  <UIcon
                    variant="lightCircleOutline"
                    size="20"
                    color={color.value}
                  >
                    {iconLeft.value}
                  </UIcon>
                ) : null}
                <div class="flex flex-col gap-[16px]">
                  <div class="flex flex-col gap-1">
                    <div class="flex items-center gap-2">
                      {$useNotification?.currentNotification?.value?.title ? (
                        <div class="text-text-sm font-semibold text-gray-900">
                          {$useNotification?.currentNotification?.value?.title}
                        </div>
                      ) : null}
                      {$useNotification?.currentNotification.value?.subTitle ? (
                        <div class="text-text-sm text-gray-500">
                          {
                            $useNotification?.currentNotification?.value
                              ?.subTitle
                          }
                        </div>
                      ) : null}
                    </div>
                    {$useNotification?.currentNotification?.value?.text ? (
                      <div class="text-text-sm text-gray-600 max-w-[276px]">
                        {$useNotification?.currentNotification?.value?.text}
                      </div>
                    ) : null}
                  </div>
                  {$useNotification?.currentNotification?.value?.buttons ? (
                    <div class="flex items-center justify-start gap-3">
                      {$useNotification?.currentNotification?.value?.buttons}
                    </div>
                  ) : null}
                </div>
              </div>
            </div>
            {slots.default?.()}
          </div>
        ) : null}
      </Transition>
    ))
    return {}
  },
})

export type UNotification = InstanceType<typeof UNotification>
