import type { ResolvedNavItem, Version } from '@redocly/config';
import type { Location } from 'react-router-dom';

import { type Locale, type TFunction } from '../types/l10n';
import { type ItemState } from '../types/sidebar';
import { MenuItemType } from '../constants/common';
import { getPathnameForLocale, withoutPathPrefix, withPathPrefix } from './urls';

const TRANSLATION_KEYS = {
  version: 'mobileMenu.version',
};

export const mapNavbarItems = (
  items: ResolvedNavItem[],
  defaultLocale: string,
  currentLocale: string,
  locales: Locale[],
  location: Location,
): ItemState[] => {
  return items.map(
    (navItem) =>
      ({
        ...navItem,
        ...(navItem.items && {
          items: mapNavbarItems(navItem.items, defaultLocale, currentLocale, locales, location),
        }),
        ...('link' in navItem && { link: navItem.link || '/' }),
        active:
          'link' in navItem &&
          isItemActive(navItem, defaultLocale, currentLocale, locales, location),
        hasActiveSubItem: !!navItem.items?.find((item) =>
          isItemActive(item, defaultLocale, currentLocale, locales, location),
        ),
      }) as ItemState,
  );
};

export const isItemActive = (
  item: ResolvedNavItem,
  defaultLocale: string,
  currentLocale: string,
  locales: Locale[],
  location: Location,
): boolean => {
  const pathHash = location.pathname + location.hash;
  const link = item.languageInsensitive
    ? item.link || ''
    : getPathnameForLocale(item.link || '/', defaultLocale, currentLocale, locales);

  return pathHash === withPathPrefix(link);
};

export const buildLanguagesGroup = (
  locales: Locale[],
  defaultLocale: string,
  currentLocale: string,
): ResolvedNavItem | undefined => {
  if (locales.length < 2) {
    return;
  }
  const locale = locales.find((l) => l.code === currentLocale);
  return {
    type: 'group',
    label: locale?.name || locale?.code,
    items: locales
      .filter((locale) => locale.code !== currentLocale)
      .map((locale) => {
        const newLangPathname = getPathnameForLocale(
          withoutPathPrefix(location.pathname),
          defaultLocale,
          locale.code,
          locales,
        );
        const newUrlWithLanguage = `${newLangPathname}${location.search}${location.hash}`;
        return {
          type: 'link',
          label: locale.name || locale.code || '',
          link: newUrlWithLanguage,
          active: false,
          hasActiveSubItem: false,
          languageInsensitive: true,
        };
      }),
  };
};

export const buildVersionSection = (
  translate: TFunction,
  versions: Version[],
  activeVersion?: Version,
): ResolvedNavItem[] => {
  return [
    {
      type: 'separator',
      label: translate(TRANSLATION_KEYS.version, 'Version'),
    },
    {
      type: 'group',
      label: activeVersion?.label,
      items: versions
        .filter((version) => !version.active)
        .map((version) => {
          return {
            type: 'link',
            label: version.label,
            link: version.link,
            active: false,
            hasActiveSubItem: false,
          };
        }),
    },
  ];
};

export function getMenuItemType(item: ItemState): MenuItemType {
  if (item.type === MenuItemType.Separator) {
    return MenuItemType.Separator;
  } else if (item.menuStyle === 'drilldown') {
    return MenuItemType.DrillDown;
  } else if (item.items?.length || (item.type === MenuItemType.Group && item.items?.length)) {
    return MenuItemType.Group;
  } else if (item.httpVerb) {
    return MenuItemType.Operation;
  } else return MenuItemType.Default;
}
