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

import type { CatalogEntityVersionHistoryGroup } from '@redocly/theme/core/types';

import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
import { ChevronRightIcon } from '@redocly/theme/icons/ChevronRightIcon/ChevronRightIcon';
import { CheckmarkOutlineIcon } from '@redocly/theme/icons/CheckmarkOutlineIcon/CheckmarkOutlineIcon';
import { NavaidMilitaryIcon } from '@redocly/theme/icons/NavaidMilitaryIcon/NavaidMilitaryIcon';
import { Link } from '@redocly/theme/components/Link/Link';
import { Tag } from '@redocly/theme/components/Tag/Tag';
import { useThemeHooks } from '@redocly/theme/core/hooks';
import { ShowMoreButton } from '@redocly/theme/components/Catalog/CatalogEntity/ShowMoreButton';
import { CatalogEntityRevisionItem } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityRevisionItem';
import { buildRevisionUrl } from '@redocly/theme/core/utils';
import { VERSION_NOT_SPECIFIED } from '@redocly/theme/core/constants';

const MAX_INITIAL_REVISIONS = 5;
const MAX_REVISIONS = 20;

export type CatalogEntityVersionItemProps = {
  group: CatalogEntityVersionHistoryGroup;
  basePath: string;
  isExpanded: boolean;
  onToggle: (version: string) => void;
};

export function CatalogEntityVersionItem({
  group,
  basePath,
  isExpanded,
  onToggle,
}: CatalogEntityVersionItemProps): React.ReactElement {
  const { useTranslate } = useThemeHooks();
  const { translate } = useTranslate();
  const [showAllRevisions, setShowAllRevisions] = useState(false);

  const revisions = group.revisions || [];
  const hasRevisions = revisions.length > 0;
  const hasMoreThanMax = revisions.length > MAX_INITIAL_REVISIONS;
  const hasMoreThanLimit = revisions.length > MAX_REVISIONS;
  const displayedRevisions = showAllRevisions
    ? revisions.slice(0, MAX_REVISIONS)
    : revisions.slice(0, MAX_INITIAL_REVISIONS);

  useEffect(() => {
    if (!isExpanded) {
      setShowAllRevisions(false);
    }
  }, [isExpanded]);

  const isNotSpecifiedVersion = group.version === VERSION_NOT_SPECIFIED;

  const singleRevisionLink = buildRevisionUrl(basePath, group.singleRevisionDate, group.version);

  const versionTitle = isNotSpecifiedVersion
    ? `${translate('catalog.history.version.label', 'Version')}:\u00a0${translate('catalog.history.version.notSpecified', 'not specified')}`
    : `${translate('catalog.history.version.label', 'Version')}:\u00a0${group.version}`;

  const versionButton = (
    <VersionButton
      type="button"
      onClick={() => hasRevisions && onToggle(group.version)}
      $isCurrent={group.isCurrent}
    >
      <VersionIcon $isCurrent={group.isCurrent}>
        {group.isCurrent ? (
          <CheckmarkOutlineIcon
            size="16px"
            color="--catalog-history-sidebar-version-icon-color-current"
          />
        ) : (
          <NavaidMilitaryIcon size="16px" color="--catalog-history-sidebar-version-icon-color" />
        )}
      </VersionIcon>
      <VersionInfo>
        <VersionTitleRow>
          <VersionTitle>{versionTitle}</VersionTitle>
          {group.isDefaultVersion && (
            <Tag
              color="grey"
              borderless
              textTransform="lowercase"
              style={{
                fontSize: 'var(--font-size-xs)',
                borderRadius: 'var(--catalog-history-sidebar-version-tag-border-radius)',
                flexShrink: 0,
                marginLeft: 'var(--spacing-xxs)',
              }}
            >
              {translate('catalog.history.version.default', 'default')}
            </Tag>
          )}
        </VersionTitleRow>
        {!isNotSpecifiedVersion && <VersionDate>{group.date}</VersionDate>}
      </VersionInfo>
      {hasRevisions && (
        <ChevronIcon>
          {isExpanded ? (
            <ChevronDownIcon size="16px" color="--catalog-history-sidebar-chevron-icon-color" />
          ) : (
            <ChevronRightIcon size="16px" color="--catalog-history-sidebar-chevron-icon-color" />
          )}
        </ChevronIcon>
      )}
    </VersionButton>
  );

  return (
    <li>
      {singleRevisionLink ? <Link to={singleRevisionLink}>{versionButton}</Link> : versionButton}

      {hasRevisions && isExpanded && (
        <RevisionsList>
          {displayedRevisions.map((revisionItem) => (
            <CatalogEntityRevisionItem
              key={revisionItem.name}
              revisionItem={revisionItem}
              basePath={basePath}
              version={group.version}
            />
          ))}
          {hasMoreThanLimit && showAllRevisions && (
            <RevisionsLimitMessage>
              {translate(
                'catalog.history.revisions.limitMessage',
                'Older revisions are not stored.',
              )}
            </RevisionsLimitMessage>
          )}
          {hasMoreThanMax && (
            <ShowMoreButton
              onClick={() => setShowAllRevisions(!showAllRevisions)}
              isExpanded={showAllRevisions}
            >
              {showAllRevisions
                ? translate('catalog.history.revisions.showLess', 'Show less')
                : translate('catalog.history.revisions.showMore', {
                    defaultValue: 'Show more',
                    count: Math.min(
                      revisions.length - MAX_INITIAL_REVISIONS,
                      MAX_REVISIONS - MAX_INITIAL_REVISIONS,
                    ),
                  })}
            </ShowMoreButton>
          )}
        </RevisionsList>
      )}
    </li>
  );
}

const VersionButton = styled.button<{
  $isCurrent?: boolean;
}>`
  all: unset;
  display: flex;
  align-items: center;
  width: calc(100% - var(--catalog-history-sidebar-version-icon-margin-right));
  padding: var(--catalog-history-sidebar-version-header-padding);
  cursor: pointer;
  border-radius: var(--catalog-history-sidebar-version-header-border-radius);
  transition: 0.2s ease;
  text-decoration: none;
  color: inherit;
  background-color: 'transparent';

  &:hover {
    background-color: var(--catalog-history-sidebar-version-header-bg-color-hover);
  }

  ${({ $isCurrent }) =>
    !$isCurrent &&
    `
    &:hover ${VersionIcon} {
      background-color: var(--color-static-white);
    }
  `}
`;

const VersionIcon = styled.div<{ $isCurrent?: boolean }>`
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--catalog-history-sidebar-version-icon-size);
  height: var(--catalog-history-sidebar-version-icon-size);
  flex-shrink: 0;
  border-radius: 50%;
  background-color: ${({ $isCurrent }) =>
    $isCurrent ? 'var(--color-primary-base)' : 'var(--catalog-avatar-bg-color)'};
  transition: background-color 0.2s ease;
  margin-right: var(--catalog-history-sidebar-version-icon-margin-right);

  svg path {
    transition: fill 0.2s ease;
  }
`;

const VersionInfo = styled.div`
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--catalog-history-sidebar-version-info-gap);
`;

const VersionTitleRow = styled.div`
  display: flex;
  align-items: center;
  gap: var(--spacing-xs, 8px);
`;

const VersionTitle = styled.span`
  font-family: var(--catalog-history-sidebar-version-title-font-family);
  font-size: var(--catalog-history-sidebar-version-title-font-size);
  font-weight: var(--catalog-history-sidebar-version-title-font-weight);
  line-height: var(--catalog-history-sidebar-version-title-line-height);
  color: var(--catalog-history-sidebar-version-title-color);
  flex-shrink: 1;
  min-width: 0;
  overflow-wrap: break-word;
  word-break: break-word;
`;

const VersionDate = styled.span`
  font-family: var(--catalog-history-sidebar-version-date-font-family);
  font-size: var(--catalog-history-sidebar-version-date-font-size);
  font-weight: var(--catalog-history-sidebar-version-date-font-weight);
  line-height: var(--catalog-history-sidebar-version-date-line-height);
  color: var(--catalog-history-sidebar-version-date-color);
`;

const ChevronIcon = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-left: auto;
`;

const RevisionsList = styled.ul`
  list-style: none;
  margin: 0;
  padding: 0;
  padding-left: var(--catalog-history-sidebar-revisions-padding-left);
  padding-bottom: var(--catalog-history-sidebar-revisions-padding-bottom);
  position: relative;

  &::before {
    content: '';
    position: absolute;
    left: 22px;
    top: 0;
    bottom: var(--catalog-history-sidebar-revisions-padding-bottom);
    width: 1px;
    background-color: var(
      --catalog-history-sidebar-revision-line-color,
      var(--border-color-secondary)
    );
  }
`;

const RevisionsLimitMessage = styled.div`
  padding: var(--catalog-history-sidebar-revision-item-padding);
  margin-left: calc(-1 * var(--catalog-history-sidebar-revisions-padding-left));
  padding-left: var(--catalog-history-sidebar-revisions-padding-left);
  font-family: var(--catalog-history-sidebar-revision-name-font-family);
  font-size: var(--font-size-sm);
  font-weight: var(--catalog-history-sidebar-revision-name-font-weight);
  line-height: var(--catalog-history-sidebar-revision-name-line-height);
  color: var(--catalog-history-sidebar-revisions-limit-message-color);
  text-align: center;
`;
