import { Children, ReactElement, useEffect } from 'react'

import { styled, useStyleConfig, vui } from '../core'
import { P } from '../p'
import { cs } from '../utils'
import Tab from './tab'
import { TabIndexProps, TabProps, TabsProps } from './tabs.types'
import TabsNavBar from './tabsNavBar'
import { useTabsState } from './useTabsState'

export const TabsBase = styled.divBox<TabsProps>`
  width: 100%;
`

/**
 * Implements Tabs navigation to switch between views. Implements Tabs navigation to switch between views. **Do not use as a top menu in a page!**
 */
export const Tabs = vui<'div', TabsProps>((props, ref) => {
  const { actions, activeTabId, showBorder = true, children, className, size, onTabClick, ...rest } = props
  const styles = useStyleConfig('Tabs', props)
  const { tabs, setTabs, activeTabIndex, setActiveTabIndex, animationDirection, setAnimationDirection } = useTabsState(
    'fadeIn',
    0,
  )

  useEffect(() => {
    const _tabs: TabIndexProps[] = []
    if (children) {
      ;(Children.toArray(children) as ReactElement[]).forEach((child: ReactElement<TabProps>, index: number) => {
        if (child?.props?.title)
          _tabs.push({
            id: child.props.id,
            index: index,
            title: child.props.title,
            icon: child.props.icon,
            className: child.props.className,
            children: child.props.children,
            disabled: child.props.disabled,
            onClick: child.props.onClick,
            onDelete: child.props.onDelete,
          })
      })
    }
    setTabs(_tabs)
    if (activeTabId !== undefined) {
      const tab = _tabs.find((t: TabIndexProps) => t?.id === activeTabId || t?.index === activeTabId)
      if (tab?.index !== undefined) setActiveTabIndex(tab.index)
    }
  }, [children, activeTabId])

  const onNavItemClick = (tabIndex: number, e: React.MouseEvent<HTMLLIElement, MouseEvent>) => {
    const tab = tabs.find(t => t.index === tabIndex)
    if (tab?.children !== undefined && tab?.index !== undefined) {
      setAnimationDirection(tab.index < activeTabIndex ? 'fadeLeft' : 'fadeRight')
      setActiveTabIndex(tab.index)
      onTabClick?.(tab.id || tab.index)
    }
    tab?.onClick?.(e)
  }

  const activeTab = tabs?.[activeTabIndex]

  return (
    <TabsBase className={cs('vui-tabs', className)} ref={ref} {...styles.container} {...rest}>
      {!!tabs?.length && (
        <TabsNavBar
          actions={actions}
          activeNavItem={activeTabIndex}
          animationDirection={animationDirection}
          onNavItemClick={(tabIndex, e) => onNavItemClick(tabIndex, e)}
          showBorder={showBorder}
          size={size}
          tabs={tabs}
        />
      )}
      {tabs?.length ? (
        <Tab onClick={activeTab?.onClick} title={activeTab?.title}>
          {!activeTab?.disabled && activeTab?.children}
        </Tab>
      ) : (
        <P p={2}>Please specify Tabs.</P>
      )}
    </TabsBase>
  )
})

Tabs.displayName = 'Tabs'

export default Tabs
