import { Fragment, useState } from 'react';

import type { ReactNode } from 'react';

import Box from '../Box';
import Clickable from '../Clickable';
import Text from '../Text';

export interface TabItem<TabId extends string = string> {
  id: TabId;
  testId?: string;
  text: string;
  content: ReactNode;
}

type TabsProps<TabId extends string = string> = {
  items: TabItem<TabId>[];
} & (
  | {
      // Controlled: parent owns selectedId, onChange required
      selectedId: TabId;
      onChange(id: TabId): Promise<void> | void;
      initialSelectedId?: never;
    }
  | {
      // Uncontrolled: Tabs owns selectedId internally
      initialSelectedId: TabId;
      onChange?(id: TabId): Promise<void> | void;
      selectedId?: never;
    }
);

const Tabs = <TabId extends string = string>({
  items,
  initialSelectedId,
  selectedId: selectedIdProp,
  onChange,
}: TabsProps<TabId>) => {
  const isControlled = selectedIdProp !== undefined;

  const [internalSelectedId, setInternalSelectedId] =
    useState(initialSelectedId);

  const selectedId = isControlled ? selectedIdProp : internalSelectedId;
  const selectedItem = items.find((item) => item.id === selectedId);

  const handleChange = async (id: TabId) => {
    if (!isControlled) setInternalSelectedId(id);
    await onChange?.(id);
  };

  return (
    <Box fullWidth>
      <Box
        flexRow
        fullHeight
        centerContent
        style={{ fontSize: '1.4rem', color: '#555' }}
      >
        {items.map((item, index) => (
          <Fragment key={item.id}>
            <Clickable
              testId={item.testId}
              margin="0 .6rem"
              padding=".3rem 0"
              isInline
              onClick={async () => {
                await handleChange(item.id);
              }}
            >
              <Text
                isBold
                letterSpacing={0}
                color={selectedId === item.id ? '#fff' : undefined}
              >
                {item.text}
              </Text>
            </Clickable>
            {index < items.length - 1 && (
              <div style={{ fontWeight: 'bold' }}>·</div>
            )}
          </Fragment>
        ))}
      </Box>
      <Box margin="1.2rem 0 0" testId={`${selectedItem?.testId}Content`}>
        {selectedItem?.content}
      </Box>
    </Box>
  );
};

export default Tabs;
