import { useMemo } from "react";
import type { PredictionTheme } from "@/features/predictions/domain/prediction-theme";
import styles from "@/features/predictions/styles/predictions.module.css";

type WeightDoubleSliderProps = {
  valueKg: number | null;
  minKg: number;
  maxKg: number;
  disabled?: boolean;
  theme?: PredictionTheme;
  labelFontClassName?: string;
  valueFontClassName?: string;
  metaFontClassName?: string;
  onChange: (nextValueKg: number) => void;
};

function clamp(value: number, min: number, max: number) {
  return Math.min(Math.max(value, min), max);
}

function toKgAndGrams(valueKg: number) {
  const wholeKg = Math.floor(valueKg);
  const grams = Math.round((valueKg - wholeKg) * 1000);
  return { wholeKg, grams };
}

function fillPct(value: number, min: number, max: number): string {
  const pct = ((value - min) / (max - min)) * 100;
  return `${Math.round(pct)}%`;
}

export function WeightDoubleSlider({
  valueKg,
  minKg,
  maxKg,
  disabled,
  theme = "boy",
  labelFontClassName,
  valueFontClassName,
  metaFontClassName,
  onChange,
}: WeightDoubleSliderProps) {
  const safeValue = useMemo(() => {
    const fallback = clamp(minKg, minKg, maxKg);
    if (valueKg == null || Number.isNaN(valueKg)) {
      return fallback;
    }
    return clamp(valueKg, minKg, maxKg);
  }, [maxKg, minKg, valueKg]);

  const { wholeKg, grams } = toKgAndGrams(safeValue);

  const kgFill = fillPct(wholeKg, Math.floor(minKg), Math.floor(maxKg));
  const gramsFill = fillPct(Math.round(grams / 5) * 5, 0, 995);
  const valueLabelClassName = [styles.weightValueLabel, labelFontClassName].filter(Boolean).join(" ");
  const valueBadgeClassName = [
    styles.weightValueBadge,
    styles.predictionAnswerBadgeSurface,
    styles.predictionAnswerBadgeSurfaceVisible,
    theme === "girl" ? styles.predictionAnswerBadgeSurfaceGirl : styles.predictionAnswerBadgeSurfaceBoy,
    valueFontClassName,
  ]
    .filter(Boolean)
    .join(" ");
  const metaClassName = [styles.weightSliderMetaValue, metaFontClassName].filter(Boolean).join(" ");
  const sliderClassName = [
    styles.weightSlider,
    theme === "girl" ? styles.weightSliderGirl : "",
  ]
    .filter(Boolean)
    .join(" ");

  return (
    <div className={styles.weightSliderBlock}>
      {/* Weight value display */}
      <div className={styles.weightValueRow}>
        <span className={valueLabelClassName}>Mon pronostic :</span>
        <span className={valueBadgeClassName}>{safeValue.toFixed(3)} kg</span>
      </div>

      {/* Kg slider */}
      <div className={styles.weightSliderGroup}>
        <input
          id="weight-kg"
          type="range"
          min={Math.floor(minKg)}
          max={Math.floor(maxKg)}
          step={1}
          value={wholeKg}
          disabled={disabled}
          className={sliderClassName}
          style={{ "--fill-pct": kgFill } as React.CSSProperties}
          onChange={(event) => {
            const nextKg = Number(event.target.value);
            if (Number.isNaN(nextKg)) return;
            onChange(clamp(nextKg + grams / 1000, minKg, maxKg));
          }}
        />
        <div className={styles.weightSliderMeta}>
          <span className={metaClassName}>{Math.floor(minKg)}kg</span>
          <span className={metaClassName}>{Math.floor(maxKg)}kg</span>
        </div>
      </div>

      {/* Grams slider */}
      <div className={styles.weightSliderGroup}>
        <input
          id="weight-grams"
          type="range"
          min={0}
          max={995}
          step={5}
          value={Math.round(grams / 5) * 5}
          disabled={disabled}
          className={sliderClassName}
          style={{ "--fill-pct": gramsFill } as React.CSSProperties}
          onChange={(event) => {
            const nextGrams = Number(event.target.value);
            if (Number.isNaN(nextGrams)) return;
            onChange(clamp(wholeKg + nextGrams / 1000, minKg, maxKg));
          }}
        />
        <div className={styles.weightSliderMeta}>
          <span className={metaClassName}>0g</span>
          <span className={metaClassName}>995g</span>
        </div>
      </div>
    </div>
  );
}

