import React, { useEffect, useRef } from 'react';
import styled, { css } from 'styled-components';

import type { JSX } from 'react';
import type { CodeBlockItems } from '@redocly/theme/components/CodeBlock/CodeBlock';

import { useCodeBlockTabsControls } from '@redocly/theme/core/hooks';
import { Button } from '@redocly/theme/components/Button/Button';
import { ChevronLeftIcon } from '@redocly/theme/icons/ChevronLeftIcon/ChevronLeftIcon';
import { ChevronRightIcon } from '@redocly/theme/icons/ChevronRightIcon/ChevronRightIcon';
import { getFileIconByExt, getFileIconByLanguage } from '@redocly/theme/core/utils';

export type CodeBlockTabsProps = {
  tabs: CodeBlockItems;
};

export function CodeBlockTabs({ tabs }: CodeBlockTabsProps): JSX.Element {
  const containerRef = useRef<HTMLDivElement>(null);
  const tabRefs = useRef<HTMLButtonElement[]>([]);
  const { showControls, handlePrevTab, handleNextTab } = useCodeBlockTabsControls({
    tabs,
    containerRef,
    tabRefs,
  });

  useEffect(() => {
    const activeTab = tabRefs.current.find((tab) => tab?.dataset.id === tabs.value);

    if (activeTab) {
      activeTab.scrollIntoView({ block: 'nearest', inline: 'center' });
    }
  }, [tabs.value]);

  return (
    <CodeBlockTabsWrapper ref={containerRef} data-component-name="CodeBlock/CodeBlockTabs">
      <ShadowWrapper>
        <Tabs>
          {tabs.items.map((item, i) => {
            const { name, lang, id } = item;
            const ext = name.match(/\.([^.]+)$/)?.[1];
            const fileIcon = lang
              ? getFileIconByLanguage(lang)
              : ext
                ? getFileIconByExt(ext)
                : null;
            return (
              <Tab
                ref={(el: HTMLButtonElement | null) => {
                  tabRefs.current[i] = el as HTMLButtonElement;
                }}
                data-name={name}
                active={id === tabs.value}
                key={id}
                onClick={() => tabs.onChange(id)}
              >
                {fileIcon}
                {name}
              </Tab>
            );
          })}
        </Tabs>
      </ShadowWrapper>

      {showControls && (
        <Controls>
          <ControlButton size="small" onClick={handlePrevTab} data-testid="prev-button">
            <ChevronLeftIcon />
          </ControlButton>
          <ControlButton size="small" onClick={handleNextTab} data-testid="next-button">
            <ChevronRightIcon />
          </ControlButton>
        </Controls>
      )}
    </CodeBlockTabsWrapper>
  );
}

const CodeBlockTabsWrapper = styled.div`
  display: flex;
  overflow: hidden;
`;

const Controls = styled.div`
  display: flex;
  gap: calc(var(--spacing-xxs) / 2);
`;

const ControlButton = styled(Button)`
  padding: 0 calc(var(--spacing-xxs) / 2);

  & + & {
    margin-left: 0;
  }
`;

const ShadowWrapper = styled.div`
  position: relative;
  overflow: hidden;

  :after {
    position: absolute;
    content: '';
    width: 16px;
    height: 100%;
    right: 0;
    top: 0;
    background: var(--bg-raised-gradient);
  }
`;

const Tabs = styled.div`
  display: flex;
  overflow-x: auto;
  padding-right: var(--spacing-base);

  &::-webkit-scrollbar {
    display: none;
  }
`;

const Tab = styled.button<{ active: boolean }>`
  --icon-size: 18px;
  display: inline-flex;
  align-items: center;

  padding: 0 var(--spacing-sm);
  background-color: transparent;
  height: 24px;
  border-radius: var(--border-radius);
  cursor: pointer;
  gap: var(--spacing-xs);
  color: var(--text-color-secondary);

  ${({ active }) =>
    active
      ? css`
          color: var(--text-color-primary);
          background-color: var(--tab-bg-color-filled);
        `
      : css`
          &:hover {
            color: var(--text-color-primary);
          }
        `}
`;
