/**
 * Copyright (c) 2022 - present TinyVue Authors.
 * Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
 *
 * Use of this source code is governed by an MIT-style license.
 *
 * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
 * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
 * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
 *
 */

import type {
  IDropdownItemState,
  IDropdownItemApi,
  IDropdownItemProps,
  IDropdownItemRenderlessParamUtils,
  ISharedRenderlessParamHooks,
  IDropdownMenuVm
} from '@/types'
import {
  tagClick,
  confirm,
  clickOutside,
  getOptionStyle,
  reset,
  getTitle,
  bindScroll,
  toggle,
  onScroll,
  open,
  opened,
  close,
  closed,
  clickItem,
  clickWrapper,
  getItemStyle,
  handleClick,
  computedGetIcon,
  computedTip
} from './index'

export const api = [
  'state',
  'confirm',
  'clickOutside',
  'getOptionStyle',
  'reset',
  'tagClick',
  'clickItem',
  'clickWrapper',
  'toggle',
  'open',
  'opened',
  'close',
  'closed',
  'handleClick',
  'computedTip'
]

const initState = ({ reactive, computed, api, props, parent, dropdownMenuVm, dropdownVm }) => {
  const state: IDropdownItemState = reactive({
    checkedStatus: dropdownMenuVm?.checkedStatus,
    sort: props.modelValue,
    transition: true,
    getTitle: false,
    showWrapper: false,
    showPopup: false,
    duration: parent.duration,
    overlay: computed(() => parent.overlay),
    offset: computed(() => parent.state.offset),
    direction: computed(() => parent.direction),
    displayTitle: computed(() => api.getTitle()),
    itemStyle: computed(() => api.getItemStyle()),
    activeColor: computed(() => parent.activeColor),
    closeOnClickOverlay: computed(() => parent.closeOnClickOverlay),
    dropdownMenuVm,
    currentIndex: props.currentIndex,
    textField: dropdownMenuVm?.textField || props.textField,
    popperClass: dropdownMenuVm?.popperClass || '',
    sizeClass: dropdownVm?.size ? `tiny-dropdown-item--${dropdownVm?.size}` : '',
    getIcon: computed(() => api.computedGetIcon()),
    children: [],
    computedTip: computed(() => api.computedTip())
  })

  return state
}

const initApi = ({ api, state, emit, props, parent, dispatch, vm, constants, designConfig }) => {
  Object.assign(api, {
    state,
    open: open(emit),
    opened: opened(emit),
    close: close(emit),
    getTitle: getTitle(props),
    onScroll: onScroll(parent),
    reset: reset({ emit, props }),
    closed: closed({ emit, state }),
    clickWrapper: clickWrapper(parent),
    clickOutside: clickOutside(parent),
    tagClick: tagClick({ emit, props }),
    getOptionStyle: getOptionStyle(state),
    toggle: toggle({ parent, props, state }),
    clickItem: clickItem({ emit, props, state }),
    getItemStyle: getItemStyle({ parent, state }),
    bindScroll: bindScroll({ api, parent }),
    confirm: confirm({ emit, props, state }),
    handleClick: handleClick({ state, props, dispatch, vm, emit }),
    computedGetIcon: computedGetIcon({ constants, designConfig }),
    computedTip: computedTip({ props, vm })
  })
}

export const renderless = (
  props: IDropdownItemProps,
  { computed, onMounted, reactive, watch, inject }: ISharedRenderlessParamHooks,
  { parent, emit, vm, dispatch, constants, designConfig }: IDropdownItemRenderlessParamUtils
): IDropdownItemApi => {
  const api = {} as IDropdownItemApi
  const dropdownMenuVm = inject('dropdownMenuVm', null) as IDropdownMenuVm
  const dropdownVm = inject('dropdownVm', null)
  const state: IDropdownItemState = initState({ reactive, computed, api, props, parent, dropdownMenuVm, dropdownVm })

  initApi({ api, state, emit, props, parent, dispatch, vm, constants, designConfig })

  watch(() => state.showPopup, api.bindScroll)

  onMounted(() => {
    const realParent = parent.$parent.$parent || {}
    if (realParent.state && realParent.state.children) {
      realParent.state.children.push(vm)
    } else {
      if (dropdownMenuVm) {
        dropdownMenuVm.state.children = [...dropdownMenuVm.state.children, vm]
      }
    }

    if (props.disabled) {
      state.checkedStatus = false
    }
  })

  return api
}