import { useTranslation } from 'react-i18next';
import type { FeatureFilters, FeatureMeta } from '../../../types';
import { formatNumber, type PercentileScale } from '../../../lib/format';
import { getFeatureIcon } from '../../../lib/feature-icons';
import { getGroupIcon } from '../../../lib/group-icons';
import { Slider } from '../../ui/Slider';
import { FeatureActions } from '../../ui/FeatureIcons';
import { FeatureLabel } from '../../ui/FeatureLabel';
import { SliderLabels } from './SliderLabels';

interface NumericFeatureFilterCardProps {
  feature: FeatureMeta;
  filters: FeatureFilters;
  activeFeature: string | null;
  dragValue: [number, number] | null;
  pinnedFeature: string | null;
  filterImpact?: number;
  percentileScale?: PercentileScale;
  onFilterChange: (name: string, value: [number, number] | string[]) => void;
  onDragStart: (name: string, initialValue?: [number, number]) => void;
  onDragChange: (value: [number, number]) => void;
  onDragEnd: () => void;
  onTogglePin: (name: string) => void;
  onShowInfo: (feature: FeatureMeta) => void;
  onRemoveFilter: (name: string) => void;
}

export function NumericFeatureFilterCard({
  feature,
  filters,
  activeFeature,
  dragValue,
  pinnedFeature,
  filterImpact,
  percentileScale,
  onFilterChange,
  onDragStart,
  onDragChange,
  onDragEnd,
  onTogglePin,
  onShowInfo,
  onRemoveFilter,
}: NumericFeatureFilterCardProps) {
  const { t } = useTranslation();
  const isActive = activeFeature === feature.name;
  const isPinned = pinnedFeature === feature.name;
  const hist = feature.histogram;
  const displayValue =
    isActive && dragValue
      ? dragValue
      : (filters[feature.name] as [number, number]) || [
          hist?.min ?? feature.min!,
          hist?.max ?? feature.max!,
        ];
  const scale = percentileScale;
  const dataMin = hist?.min ?? feature.min!;
  const dataMax = hist?.max ?? feature.max!;
  const clampMin = displayValue[0] <= dataMin;
  const clampMax = displayValue[1] >= dataMax;
  const isAtMin = displayValue[0] === dataMin;
  const isAtMax = displayValue[1] === dataMax;
  const sliderValue: [number, number] = scale
    ? [
        clampMin ? 0 : Math.round(scale.toPercentile(displayValue[0])),
        clampMax ? 100 : Math.round(scale.toPercentile(displayValue[1])),
      ]
    : [clampMin ? feature.min! : displayValue[0], clampMax ? feature.max! : displayValue[1]];

  const mobileIconClass = 'w-4 h-4 text-teal-600 dark:text-teal-400 shrink-0';
  const mobileIcon =
    getFeatureIcon(feature.name, mobileIconClass) ||
    (() => {
      const G = feature.group ? getGroupIcon(feature.group) : null;
      return G ? <G className={mobileIconClass} /> : null;
    })();

  return (
    <div
      data-filter-name={feature.name}
      className={`space-y-0.5 px-2 py-1.5 rounded ${isActive ? 'ring-2 ring-teal-400 bg-teal-50 dark:bg-teal-900/30' : isPinned ? 'ring-2 ring-teal-400 bg-teal-50/50 dark:bg-teal-900/20' : ''}`}
    >
      <div className="relative z-10 flex items-center justify-between gap-1">
        <FeatureLabel
          feature={feature}
          size="sm"
          className="min-w-0 shrink"
          hideIconOnMobile
          wrap
        />
        <FeatureActions
          feature={feature}
          isPinned={isPinned}
          isPreviewing={isActive}
          onTogglePin={onTogglePin}
          onShowInfo={onShowInfo}
          onRemove={onRemoveFilter}
        />
      </div>
      <div className="flex md:block items-start gap-1.5">
        {mobileIcon && <div className="md:hidden shrink-0 pt-0.5">{mobileIcon}</div>}
        <div className="min-w-0 flex-1">
          <Slider
            min={scale ? 0 : feature.min!}
            max={scale ? 100 : feature.max!}
            step={scale ? 1 : (feature.step ?? (feature.max! - feature.min!) / 100)}
            value={sliderValue}
            onValueChange={
              scale
                ? ([pMin, pMax]) => {
                    const step = feature.step ?? 1;
                    const snap = (v: number) => Math.round(v / step) * step;
                    onDragChange([
                      pMin <= 0 ? (hist?.min ?? feature.min!) : snap(scale.toValue(pMin)),
                      pMax >= 100 ? (hist?.max ?? feature.max!) : snap(scale.toValue(pMax)),
                    ]);
                  }
                : ([min, max]) =>
                    onDragChange([
                      min <= feature.min! ? (hist?.min ?? feature.min!) : min,
                      max >= feature.max! ? (hist?.max ?? feature.max!) : max,
                    ])
            }
            onPointerDown={() => onDragStart(feature.name, displayValue)}
            onPointerUp={() => onDragEnd()}
          />
          <SliderLabels
            min={scale ? 0 : feature.min!}
            max={scale ? 100 : feature.max!}
            value={sliderValue}
            displayValues={displayValue}
            isAtMin={isAtMin}
            isAtMax={isAtMax}
            raw={feature.raw}
            feature={feature}
            onValueChange={(v) => onFilterChange(feature.name, v)}
          />
          {filterImpact != null && filterImpact > 0 && (
            <p className="text-[10px] text-warm-400 dark:text-warm-500 -mt-1 ml-2.5">
              {t('filters.filtersOut', { value: formatNumber(filterImpact) })}
            </p>
          )}
        </div>
      </div>
    </div>
  );
}
