/**
 * Measurement utilities for Lite version.
 * Handles imperial/metric conversions and user preference toggle.
 */

// Conversion constants
const MILE_TO_KM = 1.60934;
const FOOT_TO_METER = 0.3048;
const INCH_TO_CM = 2.54;
const GALLON_TO_LITER = 3.78541;
const LB_TO_KG = 0.45359237;

const STORAGE_KEY = 'vareoncalc_measurement_mode';

/**
 * Saves the user's measurement mode preference to localStorage.
 * @param {string} mode - 'metric' or 'imperial'
 */
function saveMeasurementPreference(mode) {
  if (typeof window === 'undefined' || typeof localStorage === 'undefined') return;
  try {
    localStorage.setItem(STORAGE_KEY, mode);
  } catch {
    // localStorage might be disabled or full
  }
}

/**
 * Retrieves the user's saved measurement mode preference from localStorage.
 * @returns {string|null} The saved mode or null if not set
 */
function getSavedMeasurementPreference() {
  if (typeof window === 'undefined' || typeof localStorage === 'undefined') return null;
  try {
    const saved = localStorage.getItem(STORAGE_KEY);
    if (saved === 'metric' || saved === 'imperial') {
      return saved;
    }
  } catch {
    // localStorage might be disabled
  }
  return null;
}

/**
 * Returns the configured measurement system from admin settings.
 * Possible values: 'imperial', 'metric', 'mixed'
 */
export function getMeasurementSystem() {
  if (typeof window === 'undefined') {
    return 'mixed';
  }

  const cfg = window.VAREONCALC_CFG && window.VAREONCALC_CFG.measurement;
  const system = (cfg && cfg.system) || 'mixed';

  return system;
}

/**
 * Returns true if the system is set to 'mixed', meaning the toggle should be shown.
 */
export function shouldShowMeasurementToggle() {
  return getMeasurementSystem() === 'mixed';
}

/**
 * Returns the preferred measurement mode (imperial/metric) based on the global setting.
 * When system is 'mixed', checks localStorage for user's saved preference first,
 * then falls back to the provided defaultMode.
 * @param {string} defaultMode - Default mode when no preference is set ('metric' or 'imperial')
 */
export function getPreferredMeasurementMode(defaultMode = 'metric') {
  const system = getMeasurementSystem();
  const savedPreference = getSavedMeasurementPreference();
  let result = defaultMode;

  if (system === 'metric') {
    result = 'metric';
  } else if (system === 'imperial') {
    result = 'imperial';
  } else if (savedPreference) {
    result = savedPreference;
  }

  return result;
}

/**
 * Returns the HTML string for a measurement toggle (for use in template literals).
 * @param {string} currentMode - Current mode ('metric' or 'imperial')
 * @param {string} toggleId - Unique ID for the toggle container
 * @returns {string} HTML string
 */
export function getMeasurementToggleHTML(currentMode, toggleId = 'measurement-toggle') {
  const metricActive = currentMode === 'metric' ? ' vareoncalc-measurement-toggle__btn--active' : '';
  const imperialActive = currentMode === 'imperial' ? ' vareoncalc-measurement-toggle__btn--active' : '';
  
  return `
    <div class="vareoncalc-measurement-toggle" id="${toggleId}" role="group" aria-label="Measurement system">
      <button type="button" class="vareoncalc-measurement-toggle__btn${metricActive}" data-mode="metric" aria-pressed="${currentMode === 'metric'}">Metric</button>
      <button type="button" class="vareoncalc-measurement-toggle__btn${imperialActive}" data-mode="imperial" aria-pressed="${currentMode === 'imperial'}">Imperial</button>
    </div>
  `;
}

/**
 * Attaches event listener to a measurement toggle rendered via getMeasurementToggleHTML.
 * @param {HTMLElement} container - The parent container where the toggle was rendered
 * @param {string} toggleId - The ID used when creating the toggle
 * @param {Function} onChange - Callback when mode changes, receives new mode as argument
 */
export function attachMeasurementToggleListener(container, toggleId, onChange) {
  const toggle = container.querySelector(`#${toggleId}`);
  if (!toggle) return;
  
  toggle.addEventListener('click', (e) => {
    const btn = e.target.closest('.vareoncalc-measurement-toggle__btn');
    if (!btn) return;
    
    const newMode = btn.dataset.mode;
    const buttons = toggle.querySelectorAll('.vareoncalc-measurement-toggle__btn');
    
    // Check if already active
    if (btn.classList.contains('vareoncalc-measurement-toggle__btn--active')) return;
    
    // Update active states
    buttons.forEach(b => {
      const isActive = b.dataset.mode === newMode;
      b.classList.toggle('vareoncalc-measurement-toggle__btn--active', isActive);
      b.setAttribute('aria-pressed', isActive ? 'true' : 'false');
    });

    // Save preference to localStorage (only effective when system is 'mixed')
    saveMeasurementPreference(newMode);
    
    if (typeof onChange === 'function') {
      onChange(newMode);
    }
  });
}

// ─────────────────────────────────────────────────────────────
// Conversion Helpers
// ─────────────────────────────────────────────────────────────

export function convertDistance(value, fromUnit, toUnit) {
  if (!isFinite(value)) return 0;
  if (fromUnit === toUnit) return value;

  if (fromUnit === 'miles' && toUnit === 'km') return value * MILE_TO_KM;
  if (fromUnit === 'km' && toUnit === 'miles') return value / MILE_TO_KM;
  return value;
}

export function convertWeight(value, fromUnit, toUnit) {
  if (!isFinite(value)) return 0;
  if (fromUnit === toUnit) return value;

  if (fromUnit === 'lbs' && toUnit === 'kg') return value * LB_TO_KG;
  if (fromUnit === 'kg' && toUnit === 'lbs') return value / LB_TO_KG;
  return value;
}

export function convertLength(value, fromUnit, toUnit) {
  if (!isFinite(value)) return 0;
  if (fromUnit === toUnit) return value;

  if (fromUnit === 'feet' && toUnit === 'meters') return value * FOOT_TO_METER;
  if (fromUnit === 'meters' && toUnit === 'feet') return value / FOOT_TO_METER;
  if (fromUnit === 'inches' && toUnit === 'cm') return value * INCH_TO_CM;
  if (fromUnit === 'cm' && toUnit === 'inches') return value / INCH_TO_CM;
  return value;
}

export function convertVolume(value, fromUnit, toUnit) {
  if (!isFinite(value)) return 0;
  if (fromUnit === toUnit) return value;

  if (fromUnit === 'gallons' && toUnit === 'liters') return value * GALLON_TO_LITER;
  if (fromUnit === 'liters' && toUnit === 'gallons') return value / GALLON_TO_LITER;
  return value;
}

export function convertFuelEfficiency(value, fromUnit, toUnit) {
  if (!isFinite(value) || value === 0) return 0;
  if (fromUnit === toUnit) return value;

  // mpg <-> L/100km conversions
  if (fromUnit === 'mpg' && toUnit === 'l_per_100km') {
    return 235.214583 / value;
  }
  if (fromUnit === 'l_per_100km' && toUnit === 'mpg') {
    return 235.214583 / value;
  }
  if (fromUnit === 'mpg' && toUnit === 'km_per_liter') {
    return value * MILE_TO_KM / GALLON_TO_LITER;
  }
  if (fromUnit === 'km_per_liter' && toUnit === 'mpg') {
    return value * GALLON_TO_LITER / MILE_TO_KM;
  }
  return value;
}

// ─────────────────────────────────────────────────────────────
// Feet + Inches Height Helpers
// ─────────────────────────────────────────────────────────────

/**
 * Converts centimeters to feet and inches.
 * @param {number} cm - Height in centimeters
 * @returns {{ feet: number, inches: number }} Object with feet (int) and inches (decimal)
 */
export function cmToFeetInches(cm) {
  if (!isFinite(cm) || cm <= 0) return { feet: 0, inches: 0 };
  const totalInches = cm / INCH_TO_CM;
  const feet = Math.floor(totalInches / 12);
  const inches = totalInches % 12;
  return { feet, inches: parseFloat(inches.toFixed(1)) };
}

/**
 * Converts feet and inches to centimeters.
 * @param {number} feet - Feet portion (integer)
 * @param {number} inches - Inches portion (can be decimal, should be < 12)
 * @returns {number} Height in centimeters
 */
export function feetInchesToCm(feet, inches) {
  const ft = parseFloat(feet) || 0;
  const inc = parseFloat(inches) || 0;
  const totalInches = (ft * 12) + inc;
  return totalInches * INCH_TO_CM;
}

/**
 * Converts feet and inches to total inches.
 * @param {number} feet - Feet portion
 * @param {number} inches - Inches portion
 * @returns {number} Total inches
 */
export function feetInchesToTotalInches(feet, inches) {
  const ft = parseFloat(feet) || 0;
  const inc = parseFloat(inches) || 0;
  return (ft * 12) + inc;
}

/**
 * Converts total inches to feet and inches.
 * @param {number} totalInches - Total inches
 * @returns {{ feet: number, inches: number }} Object with feet (int) and inches (decimal)
 */
export function totalInchesToFeetInches(totalInches) {
  if (!isFinite(totalInches) || totalInches <= 0) return { feet: 0, inches: 0 };
  const feet = Math.floor(totalInches / 12);
  const inches = totalInches % 12;
  return { feet, inches: parseFloat(inches.toFixed(1)) };
}

/**
 * Normalizes feet and inches so inches is always < 12.
 * Rolls over excess inches into feet (e.g., 5ft 14in → 6ft 2in).
 * @param {number} feet - Feet portion
 * @param {number} inches - Inches portion (can be >= 12)
 * @returns {{ feet: number, inches: number }} Normalized values with inches < 12
 */
export function normalizeFeetInches(feet, inches) {
  const ft = parseFloat(feet) || 0;
  const inc = parseFloat(inches) || 0;
  if (inc < 12 && inc >= 0) {
    return { feet: ft, inches: parseFloat(inc.toFixed(1)) };
  }
  const totalInches = (ft * 12) + inc;
  if (totalInches <= 0) return { feet: 0, inches: 0 };
  const newFeet = Math.floor(totalInches / 12);
  const newInches = totalInches % 12;
  return { feet: newFeet, inches: parseFloat(newInches.toFixed(1)) };
}







