"use client";

import cx from "classnames";
import React from "react";

import { useStatic } from "../../utils/hooks";
import { Tab } from "./Tab";
import type { TabPanelProps } from "./TabPanel";
import TabsStatic from "./Tabs.static";

interface TabsProps extends React.HTMLAttributes<HTMLUListElement> {
  /** Active Tab index */
  activeTabIndex?: number;
  /** Additional classes for tabs header. */
  classesTabNav?: string;
  /** All tabs have equal width inside a full-width container */
  hasEqualTabWidth?: boolean;
  /** Fullwidth container */
  isFullWidth?: boolean;
  /** Tabs behave as links rather than tabs */
  isLink?: boolean;
  /** Tab panels as children */
  children: React.ReactElement<TabPanelProps>[];
}

const Tabs: React.FC<TabsProps> = ({
  activeTabIndex = 0,
  className,
  classesTabNav,
  isFullWidth,
  isLink,
  hasEqualTabWidth,
  children,
  ...other
}) => {
  const CLASS_TABNAV = "tab-list";

  const tabNavClasses = cx(
    CLASS_TABNAV,
    { [`${CLASS_TABNAV}--equal`]: hasEqualTabWidth },
    { [`${CLASS_TABNAV}--fullwidth`]: isFullWidth },
    classesTabNav,
    className,
  );

  const [tabListRef] = useStatic(TabsStatic);

  const tabPanels = React.Children.toArray(children).filter(
    (tabPanel): tabPanel is React.ReactElement<TabPanelProps> =>
      React.isValidElement(tabPanel),
  );

  function getTabs() {
    return tabPanels.map((tabPanel, i) => {
      const isActive = i === activeTabIndex;
      const props = tabPanel.props || {};
      const {
        renderTab = undefined,
        id,
        isDisabled,
        tab,
        href,
      } = props as TabPanelProps;

      // Generate ID if not provided
      const tabId = id || `tab-${i}`;

      if (!renderTab) {
        return (
          <Tab
            key={tabId}
            controls={!href ? tabId : ""}
            href={href}
            isDisabled={isDisabled}
            isActive={isActive}
          >
            {tab}
          </Tab>
        );
      }

      const renderedTab = renderTab(props as TabPanelProps);
      return React.cloneElement(renderedTab, {
        key: tabId,
        isActive,
      } as React.HTMLAttributes<HTMLElement>);
    });
  }

  function getPanels() {
    return tabPanels.map((tabPanel, i) => {
      const isActive = i === activeTabIndex;
      const props = tabPanel.props || {};
      const { id } = props;
      const tabId = id || `tab-${i}`;
      return React.cloneElement(tabPanel, {
        key: tabId,
        isActive,
        tab: undefined,
      } as Partial<TabPanelProps>);
    });
  }

  return (
    <>
      <div className="tab-list__viewport">
        <ul
          className={tabNavClasses}
          role={isLink ? "navigation" : "tablist"}
          ref={tabListRef}
          data-tabs={isLink ? undefined : "true"}
          {...other}
        >
          {getTabs()}
          {isFullWidth && <li role="presentation" className="tab-list__hr" />}
        </ul>
      </div>
      {!isLink ? getPanels() : null}
    </>
  );
};

Tabs.displayName = "Tabs";

export { Tabs };
