'use client'

import React, { type ReactElement, useState, useEffect } from 'react'
import * as TabsPrimitive from '@radix-ui/react-tabs'
import { twMerge } from 'tailwind-merge'
import { type ITabProps } from './Types'
import { makeClassName } from '@/utils'

export const defaultTabs = [
  {
    id: 'id_required_string',
    label: 'Label required. String or react component',
    content: 'String or react component'
  }
]
export default function Tabs({
  tabs = defaultTabs,
  defaultTab,
  selectedTab,
  className,
  defaultContentClassName = 'mt-4',
  navClassName,
  tabNavClassName,
  defaultTabNavClassName = twMerge(
    'group',
    'text-sm',
    'first:rounded-tl-lg last:rounded-tr-lg',
    'border-b',
    'border-gray-300 dark:border-gray-600',
    'radix-state-active:border-b-gray-700 focus-visible:radix-state-active:border-b-transparent radix-state-inactive:bg-gray-50 dark:radix-state-active:border-b-gray-100 dark:radix-state-active:bg-gray-900 focus-visible:dark:radix-state-active:border-b-transparent dark:radix-state-inactive:bg-gray-800',
    'flex-1 px-5 py-3',
    'focus:radix-state-active:border-b-red',
    'focus:z-10 focus:outline-none focus-visible:ring focus-visible:ring-purple-500 focus-visible:ring-opacity-75'
  ),
  activeTabNavClassName,
  defaultActiveTabNavClassName = 'font-bold',
  onChange,
  beforeTabNavElements,
  afterTabNavElements
}: ITabProps): ReactElement {
  selectedTab = selectedTab === undefined ? tabs[0].id : selectedTab
  const [activeTab, setActiveTab] = useState<string>(selectedTab)
  const onTabChange = (tab: string): void => {
    setActiveTab(tab)
    selectedTab = tab
    if (typeof onChange === 'function') {
      onChange(tab)
    }
  }

  useEffect(() => {
    if (selectedTab !== activeTab) {
      const newSelected = selectedTab !== undefined ? selectedTab : tabs[0].id
      setActiveTab(newSelected)
      onTabChange(newSelected)
    }
  }, [selectedTab])

  return (
    <TabsPrimitive.Root onValueChange={onTabChange} value={activeTab} className={className}>
      {
        <>
          <TabsPrimitive.List className={navClassName}>
            {beforeTabNavElements !== undefined && beforeTabNavElements}
            {tabs.map(tab => {

              const triggerClassName = makeClassName({
                className: activeTab === tab.id
                  ? makeClassName({
                    className: tab.activeNavClassName,
                    defaultClassName: activeTabNavClassName
                  })
                  : makeClassName({
                    className: tab.navClassName,
                    defaultClassName: tabNavClassName
                  }),
                defaultClassName: [
                  defaultTabNavClassName,
                  activeTab === tab.id
                    ? defaultActiveTabNavClassName
                    : undefined
                ].filter(d => typeof d === 'string').join(' ')
              })

              return (
                <React.Fragment key={tab.id}>{
                  tab.disabled
                    ? <span className={`${triggerClassName} opacity-50 cursor-not-allowed`}>{tab.label}</span>
                    : <TabsPrimitive.Trigger value={tab.id} className={triggerClassName}
                    >
                      {tab.label}
                    </TabsPrimitive.Trigger>
                }</React.Fragment>
              )

            })}
            {afterTabNavElements !== undefined && afterTabNavElements}
          </TabsPrimitive.List>
          {tabs.map(tab => (
            <TabsPrimitive.Content value={tab.id} key={tab.id} className={makeClassName({
              className: tab.className,
              defaultClassName: tab.defaultClassName ?? defaultContentClassName
            })}>
              {tab.content !== undefined ? tab.content : tab.children}
            </TabsPrimitive.Content>

          ))}
        </>

      }
    </TabsPrimitive.Root>

  )
}
