import {
  ComputedQuery,
  DataResultRaw,
  Environment,
  ErrorMonitor,
  ExtractFilterValue,
  FiltersMap,
  SelectionStatus,
} from '@wix/bex-core';
import { Essentials } from '@wix/fe-essentials/core';
import { PickerContentComponent } from '../../components';

export type RawFiltersParams<F extends FiltersMap> = {
  [P in keyof F]: {
    initialValue?: ExtractFilterValue<F[P]>;
  };
};

export interface PickerModalEvents {
  readonly onError?: (params: {
    err: unknown;
    isOnline: boolean;
  }) => boolean | null | undefined | void;
}

export interface OnSelectOptions<T> {
  isSelectAll: boolean;
  uncheckedValues: T[];
  selectedCount: number;
  /**
   * @deprecated Read `values` prop instead
   */
  partiallySelectedIds: string[];

  values: {
    status: SelectionStatus;
    value: T;
  }[];
  defaultStatus: SelectionStatus;
  additionalStepData?: unknown;
}

export interface UsePickerModalParamsBase<T, F extends FiltersMap> {
  /** The user's environment
   * - `language` - preferable language for the user  */
  environment: Environment;
  /** A `ErrorMonitor` instance `@wix/fe-essentials/error-monitor` */
  errorMonitor: ErrorMonitor;
  /** A `BILoggerFactory` instance `@wix/fe-essentials/bi` */
  biLoggerFactory: Essentials['biLoggerFactory'];
  /**
   * Number of items to fetch on each page
   */
  limit?: number;
  /**
   * Defines the initial values and config for filters that the collection supports.
   * For example: { premium: {initialValue: 'true'} }
   */
  filters?: Partial<RawFiltersParams<F>>;
  /**
   * Optional function that loads more dependencies required for the content of the modal to show.
   * The modal will keep showing a loader when this promise is still pending.
   * For example custom i18n translations.
   */
  fetchInitialProps?: () => Promise<unknown>;
  minContentHeight?: string | number;
  /**
   * A function being called after clicking the primary button of the modal.  It accepts the following parameters:
   * - `items` - The items that were selected in the modal's internal selector list
   * - `options.isSelectAll` - Indicates the user toggled on the "Select All" checkbox (relevant only when `showSelectAllCheckbox` is passed to `<PickerContent />`)
   * - `options.selectedCount` - The number of items the user selected. Subtracts from total count the items that were unchecked after toggling on the "Select All" checkbox
   * - `options.uncheckedValues` - The items the user unchecked after toggling on the "Select All" checkbox (relevant only when `showSelectAllCheckbox` is passed to `<PickerContent />`)
   * - `options.partiallySelectedIds` - Selected items in indeterminate status
   */
  onSelect: (items: T[], options: OnSelectOptions<T>) => unknown;
  /**
   * A function that returns a promise of dynamically imported component that renders [`<PickerContent `/>](./?path=/story/base-components-collections-picker--pickercontent) internally
   */
  pickerContentComponent: () => Promise<{
    default: PickerContentComponent<T, F>;
  }>;

  shouldFilterNotAffectTotalCount?: (filterName: keyof F) => boolean;

  /**
   * Optional callbacks for various events of the picker modal lifecycle
   * `onError` - when there's an error fetching initial data, picker content chunk or initial props.
   */
  events?: PickerModalEvents;

  /**
   * Indicates what type of pagination the `fetchData` function supports.<br>
   * In case the server accepts the `query.offset` parameter - pass `'offset'`
   * In case the server returns a `cursor` from `fetchData` - pass `'cursor'`
   * @default offset
   */
  paginationMode?: 'offset' | 'cursor';

  /**
   * The query name used for cache purposes. This should be a unique value per API endpoint consumed inside the `fetchData` function.<br>
   * It's recommended to use the [Fqdn](https://bo.wix.com/wix-docs/rnd/p13n-guidelines---aips/guidance-aips/wix-api-basics/[1009]-fqdn) of the service used in `fetchData` as `queryName`
   */
  queryName: string;

  /**
   * A function that integrates with the API to fetch the collection data from.<br>
   * Accepts the following parameters:
   * - `query`: A [ComputedQuery](./?path=/story/common-types--computedquery)  instance. Holds all the relevant variables to query the server API with.
   *
   * The function must return a promise of [DataResultRaw](./?path=/story/common-models--dataresultraw)
   */
  fetchData?: (query: ComputedQuery<F>) => Promise<DataResultRaw<T>>;

  isOpenInitially?: boolean;

  /**
   * In the picker modal, the data is prefetched before the user opens the modal. This flag disables this behavior.
   */
  skipFirstPagePrefetch?: boolean;

  /**
   * A flag to disable default behavior when fetch data returns a single item.
   * Instead of calling onSelect a dialog will be opened.
   */
  disableAutoSelectOnSingleItem?: boolean;
}
