import styles from './scale-bar.module.css';

interface ScaleBarProps {
  readonly zoom: number;
}

/** Fixed pixel width of the scale bar on screen. */
const BAR_WIDTH_PX = 100;

/**
 * Compute a "nice" real-world distance for the scale bar
 * and the corresponding pixel width to display.
 */
function computeScaleInfo(zoom: number): { label: string; barPx: number } {
  // zoom = pixels per meter
  // BAR_WIDTH_PX pixels = BAR_WIDTH_PX / zoom meters
  const rawMeters = BAR_WIDTH_PX / zoom;

  // Find the nearest "nice" value
  const niceValues = [
    0.01, 0.02, 0.05, 0.1, 0.2, 0.25, 0.5,
    1, 2, 5, 10, 20, 50, 100,
  ];

  let bestValue = niceValues[0];
  let bestDiff = Math.abs(rawMeters - bestValue);
  for (const v of niceValues) {
    const diff = Math.abs(rawMeters - v);
    if (diff < bestDiff) {
      bestDiff = diff;
      bestValue = v;
    }
  }

  const barPx = bestValue * zoom;

  let label: string;
  if (bestValue >= 1) {
    label = `${bestValue}m`;
  } else {
    label = `${Math.round(bestValue * 100)}cm`;
  }

  return { label, barPx };
}

export function ScaleBar({ zoom }: ScaleBarProps) {
  const { label, barPx } = computeScaleInfo(zoom);

  return (
    <div className={styles.container}>
      <div className={styles.bar} style={{ width: `${Math.round(barPx)}px` }}>
        <div className={styles.tickLeft} />
        <div className={styles.line} />
        <div className={styles.tickRight} />
      </div>
      <span className={styles.label}>{label}</span>
    </div>
  );
}
