import { ValidationHelpers, HelpTooltip, InputAdornment, __, sprintf } from '@vareoncalc/calculator-base';
import { initCompactTwoStep } from '../utils/compact-two-step.js';

/**
 * Unit Converter
 * Convert between common units (length, weight, volume, speed, temperature)
 * Full-refresh two-step layout with richer input hierarchy and actionable results.
 */

export function mount(container) {
  const textDomain = 'vareon-calculator-suite-lite';
  const ALL_CONVERSIONS = {
    length: {
      label: __( 'Length', 'vareon-calculator-suite-lite' ),
      units: {
        m: { name: __( 'Meters', 'vareon-calculator-suite-lite' ), abbr: 'm', toBase: 1 },
        km: { name: __( 'Kilometers', 'vareon-calculator-suite-lite' ), abbr: 'km', toBase: 1000 },
        cm: { name: __( 'Centimeters', 'vareon-calculator-suite-lite' ), abbr: 'cm', toBase: 0.01 },
        mm: { name: __( 'Millimeters', 'vareon-calculator-suite-lite' ), abbr: 'mm', toBase: 0.001 },
        mi: { name: __( 'Miles', 'vareon-calculator-suite-lite' ), abbr: 'mi', toBase: 1609.34 },
        yd: { name: __( 'Yards', 'vareon-calculator-suite-lite' ), abbr: 'yd', toBase: 0.9144 },
        ft: { name: __( 'Feet', 'vareon-calculator-suite-lite' ), abbr: 'ft', toBase: 0.3048 },
        in: { name: __( 'Inches', 'vareon-calculator-suite-lite' ), abbr: 'in', toBase: 0.0254 }
      },
      quickRef: ['km', 'mi', 'ft', 'cm']
    },
    weight: {
      label: __( 'Weight', 'vareon-calculator-suite-lite' ),
      units: {
        kg: { name: __( 'Kilograms', 'vareon-calculator-suite-lite' ), abbr: 'kg', toBase: 1 },
        g: { name: __( 'Grams', 'vareon-calculator-suite-lite' ), abbr: 'g', toBase: 0.001 },
        mg: { name: __( 'Milligrams', 'vareon-calculator-suite-lite' ), abbr: 'mg', toBase: 0.000001 },
        lb: { name: __( 'Pounds', 'vareon-calculator-suite-lite' ), abbr: 'lb', toBase: 0.453592 },
        oz: { name: __( 'Ounces', 'vareon-calculator-suite-lite' ), abbr: 'oz', toBase: 0.0283495 },
        t: { name: __( 'Metric Tons', 'vareon-calculator-suite-lite' ), abbr: 't', toBase: 1000 }
      },
      quickRef: ['kg', 'lb', 'oz', 'g']
    },
    temperature: {
      label: __( 'Temperature', 'vareon-calculator-suite-lite' ),
      units: {
        c: { name: __( 'Celsius', 'vareon-calculator-suite-lite' ), abbr: '\u00B0C' },
        f: { name: __( 'Fahrenheit', 'vareon-calculator-suite-lite' ), abbr: '\u00B0F' },
        k: { name: __( 'Kelvin', 'vareon-calculator-suite-lite' ), abbr: 'K' }
      },
      quickRef: ['c', 'f']
    },
    volume: {
      label: __( 'Volume', 'vareon-calculator-suite-lite' ),
      units: {
        l: { name: __( 'Liters', 'vareon-calculator-suite-lite' ), abbr: 'L', toBase: 1 },
        ml: { name: __( 'Milliliters', 'vareon-calculator-suite-lite' ), abbr: 'mL', toBase: 0.001 },
        gal: { name: __( 'Gallons (US)', 'vareon-calculator-suite-lite' ), abbr: 'gal', toBase: 3.78541 },
        cup: { name: __( 'Cups (US)', 'vareon-calculator-suite-lite' ), abbr: 'cup', toBase: 0.236588 },
        tbsp: { name: __( 'Tablespoons', 'vareon-calculator-suite-lite' ), abbr: 'tbsp', toBase: 0.0147868 }
      },
      quickRef: ['l', 'ml', 'cup', 'gal']
    },
    speed: {
      label: __( 'Speed', 'vareon-calculator-suite-lite' ),
      units: {
        mps: { name: __( 'Meters / Sec', 'vareon-calculator-suite-lite' ), abbr: 'm/s', toBase: 1 },
        kph: { name: __( 'Kilometers / Hour', 'vareon-calculator-suite-lite' ), abbr: 'km/h', toBase: 0.277778 },
        mph: { name: __( 'Miles / Hour', 'vareon-calculator-suite-lite' ), abbr: 'mph', toBase: 0.44704 },
        kn: { name: __( 'Knots', 'vareon-calculator-suite-lite' ), abbr: 'kn', toBase: 0.514444 }
      },
      quickRef: ['mph', 'kph', 'mps']
    }
  };
  const CATEGORY_HINTS = {
    length: __( 'Distance and sizing conversions for travel, maps, and dimensions.', textDomain ),
    weight: __( 'Mass conversions for cooking, shipping, and fitness tracking.', textDomain ),
    volume: __( 'Liquid and kitchen volume conversions in common units.', textDomain ),
    speed: __( 'Velocity conversions for driving, running, and marine use.', textDomain ),
    temperature: __( 'Temperature conversions between Celsius, Fahrenheit, and Kelvin.', textDomain )
  };
  const CATEGORY_VALUE_HINTS = {
    length: __( 'Try values like 1.5, 42, or 1609.', textDomain ),
    weight: __( 'Try values like 0.5, 75, or 220.', textDomain ),
    volume: __( 'Try values like 0.25, 2, or 64.', textDomain ),
    speed: __( 'Try values like 5, 55, or 120.', textDomain ),
    temperature: __( 'Try values like -10, 25, or 212.', textDomain )
  };
  const CATEGORY_PLACEHOLDERS = {
    length: '1',
    weight: '10',
    volume: '1',
    speed: '60',
    temperature: '25'
  };

  const defaultTypes = ['length', 'weight', 'volume', 'speed', 'temperature'];
  const cfg = window.VAREONCALC_CFG || {};
  const calcOptions = cfg.calculatorOptions || {};
  const configured = calcOptions['unit-converter'] && Array.isArray(calcOptions['unit-converter'].enabled_types)
    ? calcOptions['unit-converter'].enabled_types.slice()
    : null;

  let enabledTypes = configured && configured.length ? configured : defaultTypes.slice();

  const seen = {};
  enabledTypes = enabledTypes.filter(function(type) {
    if (!Object.prototype.hasOwnProperty.call(ALL_CONVERSIONS, type)) {
      return false;
    }
    if (seen[type]) {
      return false;
    }
    seen[type] = true;
    return true;
  });

  if (!enabledTypes.length) {
    enabledTypes = defaultTypes.slice();
  }

  const conversions = {};
  enabledTypes.forEach(function(type) {
    conversions[type] = ALL_CONVERSIONS[type];
  });

  const typeOptions = enabledTypes.map(function(type) {
    return '<option value="' + type + '">' + conversions[type].label + '</option>';
  }).join('');
  const getEmptyResultHtml = () => `
    <div class="unit-converter-result__empty">
      <span class="unit-converter-result__empty-icon">&#8646;</span>
      <span class="unit-converter-result__empty-text">${__( 'Pick units and enter a value to see conversion results.', textDomain )}</span>
    </div>
  `;

  container.innerHTML = `
    <div class="vareoncalc-two-step" data-two-step data-two-step-mode="blind">
      <div class="vareoncalc-two-step__step vareoncalc-two-step__step--inputs" data-two-step-step="inputs">
        <div class="vareoncalc-two-step__inputs-body">
          <div class="unit-converter-panel unit-converter-panel--input">
            <div class="vareoncalc-section unit-converter-section unit-converter-section--category">
              <div class="vareoncalc-section__header">
                <div class="vareoncalc-section__title">${__( 'Category', textDomain )}</div>
              </div>
              <div class="unit-converter-category">
                <label for="unit-type" class="unit-converter-category__label">
                  <span class="vareoncalc-tooltip" id="unit-category-tooltip" data-tooltip="" data-tooltip-trigger="text" tabindex="0">${__( 'Category', textDomain )}</span>
                </label>
                <select id="unit-type" class="unit-converter-category__select">${typeOptions}</select>
              </div>
            </div>

            <div class="vareoncalc-section unit-converter-section unit-converter-section--value">
              <div class="vareoncalc-section__header">
                <div class="vareoncalc-section__title">${__( 'Value', textDomain )}</div>
              </div>
              <div class="unit-converter-value">
                <label for="unit-value" class="unit-converter-value__label">
                  <span class="vareoncalc-tooltip" id="unit-value-tooltip" data-tooltip="" data-tooltip-trigger="text" tabindex="0">${__( 'Value', textDomain )}</span>
                </label>
                <input type="number" id="unit-value" placeholder="1" step="0.1" class="unit-converter-value__input">
              </div>
            </div>

            <div class="vareoncalc-section unit-converter-section unit-converter-section--conversion">
              <div class="vareoncalc-section__header">
                <div class="vareoncalc-section__title">${__( 'Conversion', textDomain )}</div>
              </div>
              <div class="unit-converter-units">
                <div class="unit-converter-units__field">
                  <label for="unit-from">${__( 'From', textDomain )}</label>
                  <select id="unit-from"></select>
                </div>
                <button type="button" class="unit-converter-units__swap" id="swap-btn" title="${__( 'Swap units', textDomain )}" aria-label="${__( 'Swap units', textDomain )}">
                  <span class="unit-converter-units__swap-icon" aria-hidden="true">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true">
                      <path d="M4 8h13"></path>
                      <path d="m14 4 4 4-4 4"></path>
                      <path d="M20 16H7"></path>
                      <path d="m10 12-4 4 4 4"></path>
                    </svg>
                  </span>
                  <span class="unit-converter-units__swap-text">${__( 'Swap', textDomain )}</span>
                </button>
                <div class="unit-converter-units__field">
                  <label for="unit-to">${__( 'To', textDomain )}</label>
                  <select id="unit-to"></select>
                </div>
              </div>
            </div>

            <button type="button" class="vareoncalc-btn unit-converter-action" id="convert-btn" data-two-step-next>${__( 'Convert', textDomain )}</button>
          </div>
        </div>
      </div>
      
      <div class="vareoncalc-two-step__step vareoncalc-two-step__step--results" data-two-step-step="results" aria-hidden="true">
        <div class="vareoncalc-two-step__results">
          <div class="unit-converter-panel unit-converter-panel--result">
            <div class="vareoncalc-out unit-converter-result" id="unit-result">${getEmptyResultHtml()}</div>
          </div>
        </div>
      </div>
      
      <button type="button" class="vareoncalc-two-step__blind-handle" data-two-step-toggle>
        <span class="vareoncalc-two-step__blind-handle-grip" aria-hidden="true"></span>
        <span>${__( 'Edit inputs', textDomain )}</span>
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m18 15-6-6-6 6"/></svg>
      </button>
    </div>
  `;
  HelpTooltip.apply(container);

  const typeSelect = container.querySelector('#unit-type');
  const fromUnit = container.querySelector('#unit-from');
  const toUnit = container.querySelector('#unit-to');
  const fromValue = container.querySelector('#unit-value');
  const btn = container.querySelector('#convert-btn');
  const result = container.querySelector('#unit-result');
  const swapBtn = container.querySelector('#swap-btn');
  const categoryTooltip = container.querySelector('#unit-category-tooltip');
  const valueTooltip = container.querySelector('#unit-value-tooltip');
  let swapAnimationTimer = null;
  let twoStepInstance = null;
  let lastResultState = null;

  const forEachTwoStepInstance = (handler) => {
    if (!twoStepInstance) {
      return;
    }
    if (Array.isArray(twoStepInstance)) {
      twoStepInstance.forEach(instance => {
        if (instance) {
          handler(instance);
        }
      });
      return;
    }
    handler(twoStepInstance);
  };
  const getTwoStepState = () => {
    let state = null;
    forEachTwoStepInstance((instance) => {
      if (state || typeof instance.getState !== 'function') {
        return;
      }
      state = instance.getState();
    });
    return state;
  };
  const isResultsStepActive = () => getTwoStepState()?.step === 'results';
  const showResultsStep = () => {
    forEachTwoStepInstance((instance) => {
      if (typeof instance.setStep === 'function') {
        instance.setStep('results');
      }
      if (typeof instance.setDrawerOpen === 'function') {
        instance.setDrawerOpen(false);
      }
      if (typeof instance.refreshLayout === 'function') {
        instance.refreshLayout();
      }
    });
  };
  const refreshTwoStepLayout = () => {
    forEachTwoStepInstance((instance) => {
      if (typeof instance.refreshLayout === 'function') {
        instance.refreshLayout();
      }
    });
  };
  const triggerResultAnimation = () => {
    result.classList.remove('is-updated');
    window.requestAnimationFrame(() => {
      result.classList.add('is-updated');
    });
  };

  function setCategoryHints(type) {
    if (categoryTooltip) {
      categoryTooltip.setAttribute('data-tooltip', CATEGORY_HINTS[type] || '');
    }
    if (valueTooltip) {
      valueTooltip.setAttribute('data-tooltip', CATEGORY_VALUE_HINTS[type] || '');
    }
    fromValue.placeholder = CATEGORY_PLACEHOLDERS[type] || '1';
  }

  function formatUnitAbbr(unit) {
    if (!unit) {
      return '';
    }
    return unit.abbr || unit.name || '';
  }

  function syncValueSuffixRail(type) {
    const units = conversions[type]?.units || {};
    const suffix = formatUnitAbbr(units[fromUnit.value]);
    const hasAdornmentWrapper = fromValue.parentElement?.classList.contains('vareoncalc-input-adorned');

    if (hasAdornmentWrapper) {
      InputAdornment.setSuffix(fromValue, suffix);
      fromValue.closest('.vareoncalc-input-adorned')?.classList.toggle('vareoncalc-input-adorned--suffix-rail', Boolean(suffix));
      return;
    }

    if (suffix) {
      fromValue.dataset.suffix = suffix;
    } else {
      delete fromValue.dataset.suffix;
    }
  }

  
  function getFirstDifferentUnit(units, current) {
    const keys = Object.keys(units);
    return keys.find((key) => key !== current) || keys[0] || '';
  }

  function updateUnits(options = {}) {
    const preserveSelection = !!options.preserveSelection;
    let type = typeSelect.value;
    if (!conversions[type]) {
      type = enabledTypes[0];
      typeSelect.value = type;
    }
    const units = conversions[type].units;
    const previousFrom = preserveSelection ? fromUnit.value : '';
    const previousTo = preserveSelection ? toUnit.value : '';

    fromUnit.innerHTML = '';
    toUnit.innerHTML = '';

    Object.keys(units).forEach(function(key) {
      const option1 = document.createElement('option');
      option1.value = key;
      option1.textContent = units[key].name;
      fromUnit.appendChild(option1);

      const option2 = document.createElement('option');
      option2.value = key;
      option2.textContent = units[key].name;
      toUnit.appendChild(option2);
    });

    if (previousFrom && units[previousFrom]) {
      fromUnit.value = previousFrom;
    }
    if (previousTo && units[previousTo]) {
      toUnit.value = previousTo;
    }
    if (!fromUnit.value) {
      fromUnit.selectedIndex = 0;
    }
    if (!toUnit.value || toUnit.value === fromUnit.value) {
      toUnit.value = getFirstDifferentUnit(units, fromUnit.value);
    }

    setCategoryHints(type);
    syncValueSuffixRail(type);
  }

  function convertTemperature(value, from, to) {
    if (from === to) {
      return value;
    }
    let celsius;
    if (from === 'c') {
      celsius = value;
    } else if (from === 'f') {
      celsius = (value - 32) * 5 / 9;
    } else if (from === 'k') {
      celsius = value - 273.15;
    }

    if (to === 'c') {
      return celsius;
    }
    if (to === 'f') {
      return (celsius * 9 / 5) + 32;
    }
    return celsius + 273.15;
  }

  function convertUnits(value, fromU, toU, type) {
    if (type === 'temperature') {
      return convertTemperature(value, fromU, toU);
    }

    const units = conversions[type].units;
    const base = units[fromU] && units[fromU].toBase ? units[fromU].toBase : 1;
    const target = units[toU] && units[toU].toBase ? units[toU].toBase : 1;
    const baseValue = value * base;
    return baseValue / target;
  }

  function formatResult(num) {
    if (Math.abs(num) >= 1000000 || (Math.abs(num) < 0.0001 && num !== 0)) {
      return num.toExponential(4);
    }
    const rounded = Number(num.toFixed(6));
    return rounded.toLocaleString(undefined, { maximumFractionDigits: 6 });
  }

  function normalizeNumericValue(rawValue) {
    if (rawValue === null || rawValue === undefined) {
      return null;
    }
    if (String(rawValue).trim() === '') {
      return null;
    }
    const value = Number(rawValue);
    if (!Number.isFinite(value)) {
      return null;
    }
    return value;
  }

  function clearResultPanel() {
    result.classList.remove('has-result', 'is-updated');
    result.innerHTML = getEmptyResultHtml();
    lastResultState = null;
  }

  function getStateFromInputs() {
    const value = normalizeNumericValue(fromValue.value);
    const type = typeSelect.value;
    const from = fromUnit.value;
    const to = toUnit.value;
    if (value === null) {
      return null;
    }
    if (!conversions[type] || !conversions[type].units[from] || !conversions[type].units[to]) {
      return null;
    }
    return { value, type, from, to };
  }

  const canProceed = () => !!getStateFromInputs();

  function animateSwapButton() {
    if (swapAnimationTimer !== null) {
      window.clearTimeout(swapAnimationTimer);
      swapAnimationTimer = null;
    }

    swapBtn.classList.remove('is-animating');
    window.requestAnimationFrame(function() {
      swapBtn.classList.add('is-animating');
    });
    swapAnimationTimer = window.setTimeout(function() {
      swapBtn.classList.remove('is-animating');
      swapAnimationTimer = null;
    }, 280);
  }

  function renderResultCard(state) {
    const { value, type, from, to } = state;
    const converted = convertUnits(value, from, to, type);
    const fromUnitData = conversions[type].units[from];
    const toUnitData = conversions[type].units[to];
    const toUnitAbbr = toUnitData.abbr || toUnitData.name;
    const fromUnitAbbr = fromUnitData.abbr || fromUnitData.name;
    const resultValue = formatResult(converted);
    const inputValueLabel = formatResult(value);
    const formulaLabel = `${inputValueLabel} ${fromUnitAbbr} = ${resultValue} ${toUnitAbbr}`;
    const contextLabel = sprintf(
      __('%1$s \u00B7 %2$s to %3$s', textDomain),
      conversions[type].label,
      fromUnitData.name,
      toUnitData.name
    );

    result.innerHTML = `
      <div class="unit-converter-result__context">${contextLabel}</div>
      <div class="unit-converter-result__primary">
        <div class="unit-converter-result__main">${resultValue} <span class="unit-converter-result__unit">${toUnitAbbr}</span></div>
        <div class="unit-converter-result__formula">${formulaLabel}</div>
      </div>
    `;
    result.classList.add('has-result');
    triggerResultAnimation();
    lastResultState = {
      value,
      converted,
      type,
      from,
      to,
      fromUnitName: fromUnitData.name,
      toUnitName: toUnitData.name,
      fromUnitAbbr,
      toUnitAbbr,
      resultValue,
      inputValueLabel,
      formulaLabel,
    };
  }

  function handleInvalidValue(event) {
    const message = __( 'Please enter a valid number.', textDomain );
    ValidationHelpers.markInvalid(fromValue, {
      validator: () => normalizeNumericValue(fromValue.value) !== null,
    });
    ValidationHelpers.showResultError(result, message);
    clearResultPanel();
    if (event) {
      event.preventDefault();
      event.stopImmediatePropagation();
    }
    refreshTwoStepLayout();
  }

  function runConversion(event, options = {}) {
    ValidationHelpers.clearAllErrors(container);

    const state = getStateFromInputs();
    if (!state) {
      handleInvalidValue(event);
      return false;
    }
    renderResultCard(state);

    const showResults = options.showResults !== false;
    if (showResults) {
      showResultsStep();
    }
    refreshTwoStepLayout();
    return true;
  }

  function recalculateIfValid(options = {}) {
    if (!canProceed()) {
      return;
    }
    const showResults = options.showResults === true || (options.showResults !== false && isResultsStepActive());
    runConversion(null, { showResults });
  }

  function swapUnits(options = {}) {
    const currentFrom = fromUnit.value;
    fromUnit.value = toUnit.value;
    toUnit.value = currentFrom;
    syncValueSuffixRail(typeSelect.value);
    animateSwapButton();

    if (options.recalculate !== false) {
      recalculateIfValid({ showResults: options.showResults });
    }
  }



  typeSelect.addEventListener('change', function() {
    updateUnits({ preserveSelection: true });
    recalculateIfValid();
  });
  fromUnit.addEventListener('change', function() {
    syncValueSuffixRail(typeSelect.value);
    recalculateIfValid();
  });
  toUnit.addEventListener('change', function() {
    recalculateIfValid();
  });
  fromValue.addEventListener('input', function() {
    if (normalizeNumericValue(fromValue.value) !== null) {
      ValidationHelpers.clearInvalid(fromValue);
    }
  });
  swapBtn.addEventListener('click', function() {
    swapUnits({ recalculate: true, showResults: isResultsStepActive() });
  });
  btn.addEventListener('click', function(event) {
    runConversion(event, { showResults: true });
  });
  fromValue.addEventListener('keypress', function(e) {
    if (e.key === 'Enter') {
      e.preventDefault();
      runConversion(e, { showResults: true });
    }
  });

  updateUnits({ preserveSelection: false });
  InputAdornment.apply(container);
  syncValueSuffixRail(typeSelect.value);
  fromValue.closest('.vareoncalc-input-adorned')?.classList.add('vareoncalc-input-adorned--suffix-rail');
  clearResultPanel();
  twoStepInstance = initCompactTwoStep(container, { canProceed });
  refreshTwoStepLayout();
}


