import React, { useMemo } from 'react';

import { useComponentsContext } from '../../../contexts/componentsContext/ComponentsContext';
import type { TranslationContextValue } from '../../../contexts/translationContext/TranslationContext';
import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext';
import type { IconProps } from '../../../icons/utils/base';

/**
 * Identifies a navigation row. The literals are the built-in sections rendered by default;
 * consumers can also add their own rows with arbitrary section identifiers via `getNavigationItems`,
 * so any string is allowed.
 */
export type ChannelDetailsNavigationSectionType =
  | 'pinned-messages'
  | 'photos-and-videos'
  | 'files'
  | string;

/**
 * A single row in the channel details navigation section.
 */
export type ChannelDetailsNavigationItem = {
  /** Icon rendered at the start of the row and reused in the built-in modal header. */
  Icon: React.ComponentType<IconProps>;
  /** Already-translated label rendered for the row and its built-in modal header. */
  label: string;
  /** Identifies which built-in section this row represents. */
  section: ChannelDetailsNavigationSectionType;
  /**
   * Fired when the user taps the row. Leave unset to keep the built-in behavior (opening the
   * built-in modal for the section); set it to route the row somewhere else (e.g. your own screen).
   */
  onPress?: () => void;
};

/**
 * Maps each navigation section to the icon (by its key in the components-context icons map) and
 * (translatable) label rendered for its row and, when opened, its modal header. The declaration
 * order also drives the order of the rendered rows.
 */
const SECTION_CONFIG: Record<
  'pinned-messages' | 'photos-and-videos' | 'files',
  { icon: 'Pin' | 'Picture' | 'Folder'; label: string }
> = {
  'pinned-messages': { icon: 'Pin', label: 'Pinned Messages' },
  'photos-and-videos': { icon: 'Picture', label: 'Photos & Videos' },
  files: { icon: 'Folder', label: 'Files' },
};

const SECTIONS = Object.keys(SECTION_CONFIG) as Array<keyof typeof SECTION_CONFIG>;

export type ChannelDetailsNavigationItemsContext = {
  t: TranslationContextValue['t'];
};

/**
 * Customizes the navigation rows rendered by `ChannelDetailsNavigationSection`. Receives the
 * built-in `defaultItems` (and a `context`) and returns the items to render. Map over
 * `defaultItems` to set a row's `onPress` (e.g. to push your own screen), or add/remove rows. Any
 * row whose `onPress` you leave unset keeps its built-in behavior (opening the built-in modal) —
 * including sections added in future SDK versions.
 */
export type GetChannelDetailsNavigationItems = (params: {
  context: ChannelDetailsNavigationItemsContext;
  defaultItems: ChannelDetailsNavigationItem[];
}) => ChannelDetailsNavigationItem[];

export const getChannelDetailsNavigationItems: GetChannelDetailsNavigationItems = ({
  defaultItems,
}) => defaultItems;

/**
 * Builds the navigation rows rendered by `ChannelDetailsNavigationSection`. Returns the items as a
 * plain array — the section component owns the built-in modal and supplies the default open-modal
 * behavior for any row without a custom `onPress`. Customize the rows by passing `getNavigationItems`
 * to `ChannelDetails` (see {@link GetChannelDetailsNavigationItems}).
 */
export const useChannelDetailsNavigationItems = ({
  getNavigationItems = getChannelDetailsNavigationItems,
}: {
  getNavigationItems?: GetChannelDetailsNavigationItems;
} = {}): ChannelDetailsNavigationItem[] => {
  const { icons } = useComponentsContext();
  const { t } = useTranslationContext();

  const context = useMemo<ChannelDetailsNavigationItemsContext>(() => ({ t }), [t]);

  const defaultItems = useMemo<ChannelDetailsNavigationItem[]>(
    () =>
      SECTIONS.map((section) => {
        const { icon, label } = SECTION_CONFIG[section];
        return { Icon: icons[icon], label: t(label), section };
      }),
    [icons, t],
  );

  return useMemo(
    () => getNavigationItems({ context, defaultItems }),
    [context, defaultItems, getNavigationItems],
  );
};
