/**
 * Unit Validation Utilities
 * Ensures all stored units comply with metric-only storage rule
 * 
 * Custom Knowledge Requirement:
 * "Unit Conversion Rules: Storage: Always metric in DB (km/h, m, cm, kg)"
 */

export const METRIC_UNITS = [
  'km/h',     // Speed
  'm',        // Distance (large)
  'cm',       // Distance (small)
  'kg',       // Weight
  'g',        // Weight (small)
  'G',        // G-force
  'celsius',  // Temperature
  'seconds',  // Time
  'minutes',  // Time
  'hours',    // Time
  'count',    // Dimensionless
  '%',        // Percentage
] as const;

export const IMPERIAL_UNITS = [
  'mph',      // Speed
  'ft',       // Distance
  'in',       // Distance
  'lbs',      // Weight
  'fahrenheit', // Temperature
] as const;

export type MetricUnit = typeof METRIC_UNITS[number];
export type ImperialUnit = typeof IMPERIAL_UNITS[number];

/**
 * Check if a unit is metric
 */
export function isMetricUnit(unit: string): unit is MetricUnit {
  return METRIC_UNITS.includes(unit as MetricUnit);
}

/**
 * Validate that a unit is metric (throws if not)
 */
export function validateMetricUnit(unit: string, fieldName: string = 'unit'): void {
  if (!isMetricUnit(unit)) {
    throw new Error(
      `${fieldName} must be metric. Received "${unit}", expected one of: ${METRIC_UNITS.join(', ')}`
    );
  }
}

/**
 * Ensure value is in metric units, converting if necessary
 * 
 * @example
 * ```typescript
 * const { value, unit } = ensureMetricUnit(60, 'mph');
 * // Returns: { value: 96.56, unit: 'km/h' }
 * ```
 */
export function ensureMetricUnit(
  value: number,
  unit: string
): { value: number; unit: MetricUnit } {
  if (isMetricUnit(unit)) {
    return { value, unit };
  }

  // Convert imperial to metric
  const { convertValueToMetric, getMetricUnit } = require('./units');
  const metricValue = convertValueToMetric(value, unit);
  const metricUnit = getMetricUnit(unit) as MetricUnit;

  return { value: metricValue, unit: metricUnit };
}

/**
 * Batch validate an array of measurements
 */
export function validateMetricUnits(
  measurements: Array<{ value: number; unit: string; name: string }>
): { valid: boolean; errors: string[] } {
  const errors: string[] = [];

  measurements.forEach(({ unit, name }) => {
    if (!isMetricUnit(unit)) {
      errors.push(`${name}: "${unit}" is not a valid metric unit`);
    }
  });

  return {
    valid: errors.length === 0,
    errors
  };
}
