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

import { VERSION_NOT_SPECIFIED } from '@redocly/theme/core/constants';

import { toLocalizedShortDate, toLocalizedShortDateTime } from './date';

export type TransformRevisionsToVersionHistoryParams = {
  revisions: BffCatalogEntityRevision[];
  currentRevisionDate?: string;
  currentVersion?: string | null;
  locale?: string;
};

export function transformRevisionsToVersionHistory({
  revisions,
  currentRevisionDate,
  currentVersion,
  locale = typeof navigator !== 'undefined' ? navigator.language : 'en-US',
}: TransformRevisionsToVersionHistoryParams): CatalogEntityVersionHistoryGroup[] {
  const normalizedCurrentVersion = currentVersion === null ? VERSION_NOT_SPECIFIED : currentVersion;

  const versionMap = new Map<string, BffCatalogEntityRevision[]>();
  revisions.forEach((revision) => {
    const version = revision.version || VERSION_NOT_SPECIFIED;
    const versionRevisions = versionMap.get(version) || [];
    versionRevisions.push(revision);
    if (!versionMap.has(version)) {
      versionMap.set(version, versionRevisions);
    }
  });

  const versionGroups = Array.from(versionMap.entries()).map(([version, versionRevisions]) => {
    const latestRevision = versionRevisions[0];

    const versionMatches =
      normalizedCurrentVersion === undefined || normalizedCurrentVersion === version;

    let isCurrent: boolean;
    if (currentRevisionDate !== undefined) {
      // Check if revision matches AND version matches
      const revisionMatches = versionRevisions.some((rev) => rev.revision === currentRevisionDate);
      isCurrent = revisionMatches && versionMatches;
    } else {
      // When no revision is specified, use isCurrent flag from the latest revision
      // but only if version also matches (or no version filter is applied)
      isCurrent = (latestRevision?.isCurrent ?? false) && versionMatches;
    }

    // Check if any revision in this version group is the default version
    const isDefaultVersion = versionRevisions.some((rev) => rev.isDefaultVersion === true);

    const revisions = versionRevisions.map((rev, index): CatalogEntityRevision => {
      const revisionMatches = currentRevisionDate ? rev.revision === currentRevisionDate : false;
      const isActiveRevision = revisionMatches && versionMatches;
      const isCurrentByDefault =
        !currentRevisionDate && normalizedCurrentVersion === undefined && index === 0 && isCurrent;
      return {
        name: `r.${versionRevisions.length - index}`,
        date: toLocalizedShortDateTime(rev.revision, locale),
        revisionDate: rev.revision,
        isActive: isActiveRevision || isCurrentByDefault,
        isCurrent: rev.isCurrent ?? false,
      };
    });

    return {
      version,
      date: toLocalizedShortDate(latestRevision?.revision || null, locale),
      isCurrent,
      isExpanded: isCurrent,
      hasCurrentRevisionFromBackend: latestRevision?.isCurrent ?? false,
      isDefaultVersion,
      revisions,
      singleRevisionDate: versionRevisions.length === 1 ? versionRevisions[0]?.revision : undefined,
    };
  });

  return versionGroups;
}
