import type { FeatureMeta } from '../types';

/** i18n keys (typed for the strict `t()`) usable as a variant dropdown label. */
type VariantDropdownLabelKey =
  | 'filters.crimeType'
  | 'filters.qualificationLevel'
  | 'filters.tenureType';

/** i18n keys (typed for the strict `t()`) usable as a window-toggle label. */
type VariantWindowLabelKey =
  | 'filters.crimeWindow'
  | 'filters.crimeWindow7y'
  | 'filters.crimeWindow2y';

/** One option in a variant filter's secondary window/period toggle. */
export interface VariantWindowOption {
  /** Stable id encoded inside the feature name (e.g. "7y"). */
  id: string;
  /** i18n key for the toggle button label. */
  labelKey: VariantWindowLabelKey;
}

/**
 * Optional secondary axis for a variant filter: the same variant measured over
 * a different time window (e.g. crime rates over 7 vs 2 years). The dropdown
 * still picks the variant; this toggle picks the window. Both ultimately select
 * a single backend feature name, so switching either re-points the filter key.
 */
export interface VariantWindowConfig {
  /** Toggle options in display order. */
  options: VariantWindowOption[];
  /** Optional i18n key for a small label above the toggle. */
  labelKey?: VariantWindowLabelKey;
  /** Window id of a feature name (e.g. "7y"), or null if unrecognized. */
  getWindow: (featureName: string) => string | null;
  /** The same variant's feature name in a different window. */
  withWindow: (featureName: string, windowId: string) => string;
}

/**
 * Shared shape for the "pick one backend feature variant, filter its range"
 * family of client-side aggregate filters. Several Census/police breakdowns
 * (specific crimes, qualifications, …) are dozens of individual percentage
 * features that would clutter the filter browser as separate sliders. Instead
 * each is folded into a single named filter whose card carries a dropdown to
 * choose the variant, reusing one component ([`VariantFilterCard`]).
 *
 * Each filter library (e.g. `crime-filter`, `qualification-filter`) exports a
 * config so the card stays variant-agnostic.
 */
export interface VariantFilterConfig {
  /** Display name of the aggregate filter, e.g. "Specific crimes". */
  filterName: string;
  /**
   * Backend feature names enumerating the dropdown options, in display order.
   * With a [`window`] config these are the canonical (default-window) names;
   * the card re-points each to the currently selected window.
   */
  featureNames: readonly string[];
  /** i18n key for the dropdown label, e.g. "filters.crimeType". */
  dropdownLabelKey: VariantDropdownLabelKey;
  /** Synthetic [`FeatureMeta`] used for the aggregate filter's own label/info. */
  getFilterMeta: (features: FeatureMeta[]) => FeatureMeta;
  /** First selectable variant present in `features`, or null if none. */
  getDefaultFeatureName: (features: FeatureMeta[]) => string | null;
  /** Backend feature name for a filter key (or a bare feature name). */
  getFeatureName: (name: string) => string | null;
  /** Rewrite a filter key to point at a different variant, keeping its id. */
  replaceFilterKeySelection: (key: string, featureName: string) => string;
  /** Clamp a [min, max] range into the selected feature's bounds. */
  clampRange: (value: [number, number], feature?: FeatureMeta) => [number, number];
  /**
   * Server-translatable source value for a dropdown option's label; the card
   * renders `ts(...)` of it. Defaults to the feature name itself. Useful with a
   * [`window`] toggle so the label can be the bare variant (no window suffix).
   */
  getOptionLabelSource?: (featureName: string) => string;
  /** Optional secondary window/period toggle (e.g. 7- vs 2-year crime rates). */
  window?: VariantWindowConfig;
}
