import React from 'react';
import styled from 'styled-components';

import type { JSX } from 'react';
import type { BreadcrumbItem } from '@redocly/config';

import { useThemeHooks } from '@redocly/theme/core/hooks';
import { Breadcrumb } from '@redocly/theme/components/Breadcrumbs/Breadcrumb';
import { BreadcrumbDropdown } from '@redocly/theme/components/Breadcrumbs/BreadcrumbDropdown';
import { BreadcrumbIcon } from '@redocly/theme/components/Breadcrumbs/BreadcrumbIcon';
import { trimText } from '@redocly/theme/core/utils';
import { BREADCRUMB_MAX_LENGTH } from '@redocly/theme/core/constants';
import { GenericIcon } from '@redocly/theme/icons/GenericIcon/GenericIcon';

export function Breadcrumbs(props: {
  className?: string;
  additionalBreadcrumbs?: BreadcrumbItem[];
}): JSX.Element | null {
  const { useBreadcrumbs, useTelemetry, useTranslate } = useThemeHooks();
  const { breadcrumbs: fileBreadcrumbs, currentItemSiblings } = useBreadcrumbs();
  const telemetry = useTelemetry();
  const { translate } = useTranslate();

  const breadcrumbs = React.useMemo(() => {
    const extra = props.additionalBreadcrumbs ?? [];
    return [...(fileBreadcrumbs || []), ...extra];
  }, [fileBreadcrumbs, props.additionalBreadcrumbs]);

  const shouldCollapse = breadcrumbs.length > 4;

  const isInDropdown = (index: number, total: number, collapsed: boolean): boolean =>
    collapsed && index > 0 && index < total - 2;

  const items = React.useMemo(() => {
    const total = breadcrumbs.length;
    return breadcrumbs.map((b, i) => ({
      breadcrumb: b,
      idx: i,
      isLast: i === total - 1,
      inDropdown: isInDropdown(i, total, shouldCollapse),
    }));
  }, [breadcrumbs, shouldCollapse]);

  if (breadcrumbs.length === 0) {
    return null;
  }

  const renderBreadcrumb = (
    breadcrumb: BreadcrumbItem,
    idx: number,
    isActive: boolean,
  ): JSX.Element => {
    const isParentOfActive =
      idx === breadcrumbs.length - 2 && currentItemSiblings && currentItemSiblings.length > 0;

    if (isParentOfActive) {
      const currentActiveBreadcrumb = breadcrumbs[breadcrumbs.length - 1];
      const siblingsWithActive = [
        { ...currentActiveBreadcrumb, isActive: true },
        ...currentItemSiblings,
      ];

      const translatedLabel = translate(breadcrumb.labelTranslationKey, breadcrumb.label);
      return (
        <BreadcrumbDropdown
          label={translatedLabel}
          items={siblingsWithActive}
          onItemClick={(item, itemIdx) =>
            telemetry.sendBreadcrumbClickedMessage([
              {
                object: 'breadcrumb',
                link: item.link,
                position: itemIdx + 1,
                totalBreadcrumbs: siblingsWithActive.length,
              },
            ])
          }
        >
          <BreadcrumbIcon icon={breadcrumb.icon} />
          {trimText(translatedLabel, BREADCRUMB_MAX_LENGTH)}
          <GenericIcon icon="chevron-down" />
        </BreadcrumbDropdown>
      );
    }

    return (
      <Breadcrumb
        link={breadcrumb.link}
        label={translate(breadcrumb.labelTranslationKey, breadcrumb.label)}
        isActive={isActive}
        icon={breadcrumb.icon}
        onClick={() =>
          telemetry.sendBreadcrumbClickedMessage([
            {
              object: 'breadcrumb',
              link: breadcrumb.link,
              position: idx + 1,
              totalBreadcrumbs: breadcrumbs.length,
            },
          ])
        }
      />
    );
  };

  return (
    <BreadcrumbsWrapper data-component-name="Breadcrumbs/Breadcrumbs" className={props.className}>
      {items.map(({ breadcrumb, idx, isLast, inDropdown }) => {
        if (inDropdown) return null;

        if (shouldCollapse && idx === 0) {
          const collapsedBreadcrumbs = breadcrumbs.slice(1, -2);
          return (
            <React.Fragment key={idx}>
              {renderBreadcrumb(breadcrumb, idx, isLast)}
              <BreadcrumbSeparator>/</BreadcrumbSeparator>
              <BreadcrumbDropdown
                label="..."
                items={collapsedBreadcrumbs}
                onItemClick={(item, itemIdx) =>
                  telemetry.sendBreadcrumbClickedMessage([
                    {
                      object: 'breadcrumb',
                      link: item.link,
                      position: itemIdx + 1,
                      totalBreadcrumbs: breadcrumbs.length,
                    },
                  ])
                }
              >
                ...
              </BreadcrumbDropdown>
              <BreadcrumbSeparator>/</BreadcrumbSeparator>
            </React.Fragment>
          );
        }

        return (
          <React.Fragment key={idx}>
            {renderBreadcrumb(breadcrumb, idx, isLast)}
            {isLast ? null : <BreadcrumbSeparator>/</BreadcrumbSeparator>}
          </React.Fragment>
        );
      })}
    </BreadcrumbsWrapper>
  );
}

const BreadcrumbsWrapper = styled.div`
  display: flex;
  flex-direction: row;
  align-items: center;
  color: var(--breadcrumbs-text-color);
  font-size: var(--breadcrumbs-font-size);
  flex-wrap: wrap;
`;

const BreadcrumbSeparator = styled.span`
  padding: var(--breadcrumbs-padding);
`;
