import { makeComponentProps } from '@/composables/component'
import { computed, ref, Transition } from 'vue'
import ColorName from '@/types/colors'

import { UIcon } from '@/components/UIcon/UIcon'
import { UButton } from '@/components/UButton/UButton'
import { UModalActions } from '@/components/UModal/UModalActions'
import '@/components/UModal/transition.scss'
import UntitledColorTypes from '@/types/untitledColorTypes'

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

export const makeUModalProps = propsFactory(
  {
    isActive: Boolean,
    prependIcon: String,
    iconColor: String,
    position: String,
    destructive: Boolean,
    dualAction: Boolean,
    checkboxControl: Boolean,
    smallActions: Boolean,
    unclosable: { type: Boolean, default: false },
    text: String,
    supportingText: String,
    primaryButtonText: String,
    secondaryButtonText: String,
    checkboxText: String,

    ...makeComponentProps(),
  },
  'UModal'
)

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

export const UModal = genericComponent<UModalSlots>()({
  name: 'UModal',

  props: makeUModalProps(),

  emits: {
    click: (e: MouseEvent) => true,
    close: () => true,
    check: (isChecked: boolean) => true,
    action: (isPrimary: boolean) => true,
    'update:isActive': (isActive: boolean) => true,
  },

  setup(props, { emit, slots }) {
    const modalContainer = ref<HTMLElement | null>(null)
    const modalContentContainer = ref<HTMLElement | null>(null)

    const onClick = (e: MouseEvent) => {
      emit('click', e)
    }

    const closeModal = () => {
      emit('update:isActive', false)
      emit('close')
    }

    const checkboxChange = (isChecked: boolean) => {
      emit('check', isChecked)
    }

    const actionsClick = (isPrimary: boolean) => {
      emit('action', isPrimary)
    }

    const backgroundClasses = computed<string>(
      () => `modal-container absolute top-0 left-0 w-full h-full 
      flex items-center justify-center backdrop-blur-[8px] px-4
      bg-[#344054] bg-opacity-70`
    )

    const contentClasses = computed<string>(
      () => `box-border flex flex-col 
      relative ${
        props.position == 'horizontal'
          ? `max-w-[544px] items-center :sm:items-start`
          : `max-w-[400px] items-${props.position}`
      } bg-white p-6 rounded-md w-full sm:min-w-[400px]`
    )

    const closeButtonClasses = computed<string>(
      () => `absolute top-[24px] right-[24px]`
    )

    const headerSlotClasses = computed<string>(
      () => `w-full ${props.text || props.supportingText ? 'mb-[20px]' : ``}`
    )

    const textContainerClasses = computed<string>(() => `flex flex-col gap-2`)

    const modalActionsContainerClasses = computed<string>(() => `w-full`)

    const defaultSlotClasses = computed<string>(
      () =>
        `${
          props.prependIcon || props.text || props.supportingText
            ? 'mt-[20px]'
            : ``
        }`
    )

    const iconTextClasses = computed<string>(
      () => `${
        props.position == 'horizontal'
          ? 'flex flex-col sm:flex-row gap-x-[28px] items-center sm:items-start'
          : `flex-col items-${props.position}`
      }
      flex items-${props.position}`
    )

    const getIconColor = computed(() => {
      return props.destructive
        ? ('error-600' as ColorName)
        : ((props.iconColor + '-600') as ColorName)
    })

    const iconClasses = computed<string>(
      () =>
        `w-[40px] h-[40px]
      flex shrink-0 items-center justify-center
      rounded-full
      ${props.destructive ? 'bg-error-100' : `bg-${props.iconColor}-100`}
      shadow-md-icon ${
        props.destructive ? 'shadow-error-50' : `shadow-${props.iconColor}-50`
      } mb-4`
    )

    const textClasses = computed<string>(
      () => `text-text-lg font-semibold text-gray-900
      ${
        props.position == 'horizontal'
          ? 'text-center sm:text-left'
          : `text-${props.position}`
      }`
    )

    const supportingTextClasses = computed<string>(
      () => `text-text-sm text-${props.position} font-regular text-gray-600 
      ${
        props.position == 'horizontal'
          ? 'text-center sm:text-left'
          : `text-${props.position}`
      }`
    )

    useRender(() => (
      <Transition name="display">
        {props.isActive ? (
          <div
            ref={modalContainer}
            class={backgroundClasses.value}
            onClick={() => props.unclosable === false && closeModal()}
          >
            <div
              ref={modalContentContainer}
              class={contentClasses.value}
              onClick={onClick}
            >
              <div class={iconTextClasses.value}>
                {props.prependIcon ? (
                  <div class={iconClasses.value}>
                    <UIcon
                      size="24"
                      color={getIconColor.value}
                      icon={`$${props.prependIcon}`}
                    ></UIcon>
                  </div>
                ) : null}

                {slots.header ? (
                  <div class={headerSlotClasses.value}>{slots.header?.()}</div>
                ) : null}

                {props.unclosable === false ? (
                  <div class={closeButtonClasses.value}>
                    <UButton type={UntitledColorTypes.linkGray}>
                      <div class="close" onClick={closeModal}>
                        <UIcon
                          size="24"
                          color="gray-500"
                          icon="$xClose"
                        ></UIcon>
                      </div>
                    </UButton>
                  </div>
                ) : null}
                {props.text || props.supportingText ? (
                  <div>
                    <div class={textContainerClasses.value}>
                      {props.text ? (
                        <div class={textClasses.value}>{props.text}</div>
                      ) : null}

                      {props.supportingText ? (
                        <div class={supportingTextClasses.value}>
                          {props.supportingText}
                        </div>
                      ) : null}
                    </div>
                  </div>
                ) : null}

                {slots.default ? (
                  <div class={defaultSlotClasses.value}>
                    {slots.default?.()}
                  </div>
                ) : null}
              </div>

              {props.primaryButtonText ? (
                <div class={modalActionsContainerClasses.value}>
                  <UModalActions
                    onAction={actionsClick}
                    onCheck={checkboxChange}
                    destructive={props.destructive}
                    dualAction={props.dualAction}
                    checkboxControl={props.checkboxControl}
                    smallActions={props.smallActions}
                    primaryButtonText={props.primaryButtonText}
                    secondaryButtonText={props.secondaryButtonText}
                    checkboxText={props.checkboxText}
                  ></UModalActions>
                </div>
              ) : null}
            </div>
          </div>
        ) : null}
      </Transition>
    ))
    return {
      closeModal,
    }
  },
})

export type UModal = InstanceType<typeof UModal>
