import type { FeatureFilters, FeatureMeta } from '../types';
import type { VariantFilterConfig } from './variant-filter';

export const TENURE_FILTER_NAME = 'Tenure';
export const TENURE_FILTER_KEY_PREFIX = `${TENURE_FILTER_NAME}:`;

/**
 * The Census 2021 housing tenure categories (TS054). They sum to 100% per
 * neighbourhood and render as a single stacked "Tenure" composition in the area
 * pane (see STACKED_GROUPS["Neighbours"] in consts.ts). In the filter browser
 * they fold into one "Tenure" filter whose dropdown selects a category —
 * owner-occupied, social rent or private rent — rather than three separate
 * sliders.
 */
export const TENURE_FEATURE_NAMES = [
  '% Owner occupied',
  '% Social rent',
  '% Private rent',
] as const;

const TENURE_FEATURE_NAME_SET = new Set<string>(TENURE_FEATURE_NAMES);

export function isTenureFeatureName(name: string): boolean {
  return TENURE_FEATURE_NAME_SET.has(name);
}

export function isTenureFilterName(name: string): boolean {
  return isTenureFeatureName(name) || name.startsWith(TENURE_FILTER_KEY_PREFIX);
}

export function createTenureFilterKey(featureName: string, id: number | string): string {
  return `${TENURE_FILTER_KEY_PREFIX}${encodeURIComponent(featureName)}:${id}`;
}

export function getTenureFilterKeyId(name: string): string | null {
  if (!name.startsWith(TENURE_FILTER_KEY_PREFIX)) return null;
  const rest = name.substring(TENURE_FILTER_KEY_PREFIX.length);
  const lastColon = rest.lastIndexOf(':');
  return lastColon === -1 ? null : rest.substring(lastColon + 1);
}

export function parseTenureFilterKey(name: string): string | null {
  if (!name.startsWith(TENURE_FILTER_KEY_PREFIX)) return null;
  const rest = name.substring(TENURE_FILTER_KEY_PREFIX.length);
  const lastColon = rest.lastIndexOf(':');
  if (lastColon === -1) return null;

  const decoded = decodeURIComponent(rest.substring(0, lastColon));
  return isTenureFeatureName(decoded) ? decoded : null;
}

export function getTenureFeatureName(name: string): string | null {
  if (isTenureFeatureName(name)) return name;
  return parseTenureFilterKey(name);
}

export function replaceTenureFilterKeySelection(key: string, featureName: string): string {
  const id = getTenureFilterKeyId(key) ?? '0';
  return createTenureFilterKey(featureName, id);
}

export function getDefaultTenureFeatureName(features: FeatureMeta[]): string | null {
  return (
    TENURE_FEATURE_NAMES.find((name) => features.some((feature) => feature.name === name)) ?? null
  );
}

export function normalizeTenureFilters(filters: FeatureFilters): FeatureFilters {
  let changed = false;
  const next: FeatureFilters = {};

  for (const [name, value] of Object.entries(filters)) {
    if (isTenureFeatureName(name)) {
      next[createTenureFilterKey(name, Object.keys(next).length)] = value;
      changed = true;
      continue;
    }
    next[name] = value;
  }

  return changed ? next : filters;
}

export function getTenureFilterMeta(features: FeatureMeta[]): FeatureMeta {
  const sourceFeatureName = getDefaultTenureFeatureName(features);
  const sourceFeature = sourceFeatureName
    ? features.find((feature) => feature.name === sourceFeatureName)
    : undefined;

  return {
    name: TENURE_FILTER_NAME,
    type: 'numeric',
    group: 'Neighbours',
    min: sourceFeature?.min ?? 0,
    max: sourceFeature?.max ?? 100,
    step: 1,
    description:
      'Share of households that own their home, rent from a social landlord, or rent privately',
    detail:
      'Filter by one Census 2021 (TS054) housing tenure category at a time, e.g. the percentage of households that own their home.',
    source: 'census-2021',
    suffix: '%',
  };
}

export function clampTenureRange(value: [number, number], feature?: FeatureMeta): [number, number] {
  const min = feature?.histogram?.min ?? feature?.min ?? 0;
  const max = feature?.histogram?.max ?? feature?.max ?? Math.max(1, value[1]);
  return [Math.max(min, Math.min(value[0], max)), Math.max(min, Math.min(value[1], max))];
}

export const TENURE_VARIANT_CONFIG: VariantFilterConfig = {
  filterName: TENURE_FILTER_NAME,
  featureNames: TENURE_FEATURE_NAMES,
  dropdownLabelKey: 'filters.tenureType',
  getFilterMeta: getTenureFilterMeta,
  getDefaultFeatureName: getDefaultTenureFeatureName,
  getFeatureName: getTenureFeatureName,
  replaceFilterKeySelection: replaceTenureFilterKeySelection,
  clampRange: clampTenureRange,
};
