import { ValidationHelpers, InputAdornment, HelpTooltip, __, _n, sprintf } from '@vareoncalc/calculator-base';
import { getFormattingConfig, formatCurrency, formatCurrencyHtml, formatCompactCurrency, escapeHtml } from '../utils/formatting.js';
import { mapHoverClientXToScalar, findNearestPoint, positionChartTooltip } from '../utils/chart-helpers.js';
import { initWizardSkeleton } from '../utils/wizard-skeleton.js';
import { calculateMortgageAmortization, calculateMortgageEscrow } from '../utils/mortgage-engine.js';

/**
 * Mortgage Calculator - Wizard Layout
 * Step 1: Your Mortgage (required)
 * Step 2: Monthly Costs (optional)
 * Step 3: Pay It Off Faster (optional)
 * -> Results
 */

export function mount(container) {
  const cfg = window.VAREONCALC_CFG || {};
  const calcOptions = cfg.calculatorOptions || {};
  const mortgageOptions = calcOptions['mortgage'] || {};
  const hideAdvanced = Boolean(mortgageOptions.disable_advanced);
  const hostRoot = container.closest('.vareoncalc-root') || container;
  let wizardRoot = null;

  const textDomain = 'vareon-calculator-suite-lite';
  const formatting = getFormattingConfig();
  const currencySymbol = escapeHtml(formatting.currencySymbol || '$');

  const PAYMENT_COLORS = {
    principal: '#3b82f6',
    interest: '#f97316',
    taxIns: '#22c55e',
  };
  const MOBILE_RESULTS_MAX_WIDTH = 460;
  const LAYOUT_REFRESH_DELAYS = [80, 220, 420, 620];

  const monthNames = [
    __('January', textDomain),
    __('February', textDomain),
    __('March', textDomain),
    __('April', textDomain),
    __('May', textDomain),
    __('June', textDomain),
    __('July', textDomain),
    __('August', textDomain),
    __('September', textDomain),
    __('October', textDomain),
    __('November', textDomain),
    __('December', textDomain),
  ];

  const monthOptions = monthNames
    .map((label, index) => `<option value="${index + 1}">${label}</option>`)
    .join('');

  // Build optional Monthly Costs step (only when advanced is not disabled)
  const monthlyCostsStepHtml = hideAdvanced ? '' : `
    <!-- Step 2: Monthly Costs (Optional) -->
    <div class="vareoncalc-wizard__step"
         data-wizard-step="monthly-costs"
         data-step-title="${__('Monthly Costs', textDomain)}"
         data-step-subtitle="${__('Add escrow and recurring housing costs', textDomain)}"
         data-step-optional="true">
      <div class="mortgage-wizard__step-fields">
        <div class="mortgage-card vareoncalc-section" id="monthly-costs-card">
          <div class="mortgage-card__body">
            <div class="mortgage-escrow__estimate-grid">
              <div class="mortgage-escrow__estimate-card">
                <div class="mortgage-escrow__estimate-header">
                  <label for="property-tax" data-help="${__('Annual property tax. Find this on your local tax assessor\'s site or recent tax bill.', textDomain)}">${__('Property Tax', textDomain)}</label>
                  <div
                    class="vareoncalc-toggle mortgage-escrow__mode-toggle"
                    data-escrow-toggle="property-tax"
                    data-mode="amount"
                    role="group"
                    aria-label="${__('Property tax input mode', textDomain)}">
                    <input type="radio" name="property-tax-mode" id="property-tax-mode-amount" value="amount" class="vareoncalc-visually-hidden" checked>
                    <input type="radio" name="property-tax-mode" id="property-tax-mode-percent" value="percent" class="vareoncalc-visually-hidden">
                    <div class="vareoncalc-toggle__track">
                      <div class="vareoncalc-toggle__indicator" aria-hidden="true"></div>
                      <button type="button" class="vareoncalc-toggle__option mortgage-escrow__mode-option mortgage-escrow__mode-option--amount is-active" data-escrow-mode-option="amount" aria-label="${__('Dollar amount mode', textDomain)}">$</button>
                      <button type="button" class="vareoncalc-toggle__option mortgage-escrow__mode-option mortgage-escrow__mode-option--percent" data-escrow-mode-option="percent" aria-label="${__('Percent of home price mode', textDomain)}">%</button>
                    </div>
                  </div>
                </div>
                <div class="mortgage-escrow__estimate-input-wrap">
            <input type="number" id="property-tax" data-suffix="${currencySymbol}/yr" data-suffix-family="compound" placeholder="${__('e.g.', textDomain)} 3600" min="0" step="100">
                </div>
                <span class="vareoncalc-field-hint mortgage-escrow__estimate-helper" id="property-tax-helper"></span>
              </div>

              <div class="mortgage-escrow__estimate-card">
                <div class="mortgage-escrow__estimate-header">
                  <label for="home-insurance" data-help="${__('Annual homeowners insurance premium. Get quotes from insurance providers.', textDomain)}">${__('Home Insurance', textDomain)}</label>
                  <div
                    class="vareoncalc-toggle mortgage-escrow__mode-toggle"
                    data-escrow-toggle="home-insurance"
                    data-mode="amount"
                    role="group"
                    aria-label="${__('Home insurance input mode', textDomain)}">
                    <input type="radio" name="home-insurance-mode" id="home-insurance-mode-amount" value="amount" class="vareoncalc-visually-hidden" checked>
                    <input type="radio" name="home-insurance-mode" id="home-insurance-mode-percent" value="percent" class="vareoncalc-visually-hidden">
                    <div class="vareoncalc-toggle__track">
                      <div class="vareoncalc-toggle__indicator" aria-hidden="true"></div>
                      <button type="button" class="vareoncalc-toggle__option mortgage-escrow__mode-option mortgage-escrow__mode-option--amount is-active" data-escrow-mode-option="amount" aria-label="${__('Dollar amount mode', textDomain)}">$</button>
                      <button type="button" class="vareoncalc-toggle__option mortgage-escrow__mode-option mortgage-escrow__mode-option--percent" data-escrow-mode-option="percent" aria-label="${__('Percent of home price mode', textDomain)}">%</button>
                    </div>
                  </div>
                </div>
                <div class="mortgage-escrow__estimate-input-wrap">
            <input type="number" id="home-insurance" data-suffix="${currencySymbol}/yr" data-suffix-family="compound" placeholder="${__('e.g.', textDomain)} 1200" min="0" step="100">
                </div>
                <span class="vareoncalc-field-hint mortgage-escrow__estimate-helper" id="home-insurance-helper"></span>
              </div>
            </div>

            <div class="mortgage-escrow__dues-grid">
              <div class="vareoncalc-field">
                <label for="hoa-fees" data-help="${__('Monthly Homeowners Association fees, if applicable to your property.', textDomain)}">${__('HOA Fees', textDomain)}</label>
            <input type="number" id="hoa-fees" data-suffix="${currencySymbol}/mo" data-suffix-family="compound" placeholder="${__('e.g.', textDomain)} 150" min="0" step="100">
              </div>
              <div class="vareoncalc-field">
                <label for="pmi">${__('PMI', textDomain)}</label>
            <input type="number" id="pmi" data-suffix="${currencySymbol}/mo" data-suffix-family="compound" placeholder="0" min="0" step="100">
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  `;

  // Build the wizard layout
  container.innerHTML = `
    <div class="vareoncalc-shell vareoncalc-shell--wizard">
      <div class="vareoncalc-shell__body">
        <div class="vareoncalc-wizard" data-wizard>

          <!-- Wizard Header -->
          <div class="vareoncalc-wizard__header">
            <div class="vareoncalc-wizard__indicator" data-wizard-indicator></div>
            <div class="vareoncalc-wizard__title" data-wizard-title></div>
            <div class="vareoncalc-wizard__subtitle" data-wizard-subtitle></div>
            <div class="vareoncalc-wizard__progress">
              <div class="vareoncalc-wizard__progress-fill" data-wizard-progress></div>
            </div>
          </div>

          <!-- Wizard Body (Steps) -->
          <div class="vareoncalc-wizard__body">

            <!-- Step 1: Your Mortgage -->
            <div class="vareoncalc-wizard__step"
                 data-wizard-step="mortgage"
                 data-step-title="${__('Your Mortgage', textDomain)}"
                 data-step-subtitle="${__('Tell us about the home and loan', textDomain)}">
              <div class="mortgage-wizard__step-fields">

                <div class="vareoncalc-field mortgage-hero-field">
                  <label for="home-price">${__('Home Price', textDomain)}</label>
            <input type="number" id="home-price" data-suffix="${currencySymbol}" data-suffix-family="currency" placeholder="${__('e.g.', textDomain)} 350000" min="1" step="1000" class="mortgage-hero-field__input">
                </div>

                <div class="mortgage-card vareoncalc-section" id="loan-terms-card">
                  <div class="mortgage-card__body">
                    <div class="mortgage-card__row">
                      <label data-help="${__('The upfront amount you pay. Typically 10-20% of the home price.', textDomain)}">${__('Down Payment', textDomain)}</label>
                      <div class="mortgage-dp-row">
                        <div class="vareoncalc-field mortgage-dp-row__amount">
            <input type="number" id="down-payment" data-suffix="${currencySymbol}" data-suffix-family="currency" placeholder="${__('Amount', textDomain)}" min="0" step="100">
                        </div>
                        <div class="vareoncalc-field mortgage-dp-row__percent">
                          <input type="number" id="down-payment-percent" data-suffix="%" placeholder="0" min="0" max="100" step="0.1" aria-label="${__('Down payment percentage', textDomain)}" data-vareoncalc-mobile-label-shift="off">
                        </div>
                      </div>
                    </div>
                    <div class="mortgage-card__grid-2">
                      <div class="vareoncalc-field">
                        <label for="interest-rate" data-help="${__('The annual interest rate from your lender. Check current rates with your bank.', textDomain)}">${__('Interest Rate', textDomain)}</label>
                        <input type="number" id="interest-rate" data-suffix="%" placeholder="${__('e.g.', textDomain)} 6.5" min="0" max="25" step="0.1">
                      </div>
                      <div class="vareoncalc-field">
                        <label for="loan-term">${__('Loan Term', textDomain)}</label>
                        <input type="number" id="loan-term" data-suffix="${__('yrs', textDomain)}" placeholder="${__('e.g.', textDomain)} 30" min="1" max="50" step="1">
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>

            ${monthlyCostsStepHtml}

            <!-- Step 3: Pay It Off Faster -->
            <div class="vareoncalc-wizard__step"
                 data-wizard-step="extras"
                 data-step-title="${__('Pay It Off Faster', textDomain)}"
                 data-step-subtitle="${__('Optional extra payments to reduce your loan', textDomain)}"
                 data-step-optional="true">
              <div class="mortgage-wizard__step-fields">
                <div class="mortgage-card vareoncalc-section">
                  <div class="mortgage-card__body">
                    <div class="vareoncalc-field">
                      <label for="extra-monthly">${__('Extra Monthly Payment', textDomain)}</label>
            <input type="number" id="extra-monthly" data-suffix="${currencySymbol}/mo" data-suffix-family="compound" placeholder="0" min="0" step="100">
                    </div>
                    <div class="vareoncalc-field mortgage-card__start-date">
                      <label for="start-date">${__('Start Date', textDomain)}</label>
                      <input type="date" id="start-date">
                    </div>

                    <div class="mortgage-extra__advanced vareoncalc-section vareoncalc-disclosure vareoncalc-disclosure--optional">
                      <div class="mortgage-extra__advanced-header vareoncalc-section__header vareoncalc-disclosure__header">
                        <span class="mortgage-extra__advanced-title vareoncalc-section__title vareoncalc-disclosure__title">${__('Optional Details', textDomain)}</span>
                        <button
                          type="button"
                          class="mortgage-extra__advanced-toggle vareoncalc-disclosure__toggle vareoncalc-disclosure__toggle--compact"
                          id="mortgage-extra-advanced-toggle"
                          aria-expanded="false"
                          aria-controls="mortgage-extra-advanced-fields"
                          aria-label="${__('Toggle more options', textDomain)}">
                          <span class="mortgage-extra__advanced-text">${__('Show more options', textDomain)}</span>
                          <span class="mortgage-extra__advanced-icon vareoncalc-disclosure__icon" aria-hidden="true">></span>
                        </button>
                      </div>

                      <div class="mortgage-extra__advanced-fields vareoncalc-disclosure__content" id="mortgage-extra-advanced-fields" hidden>
                        <div class="mortgage-card__grid-2">
                          <div class="vareoncalc-field">
                            <label for="extra-yearly">${__('Extra Yearly Payment', textDomain)}</label>
            <input type="number" id="extra-yearly" data-suffix="${currencySymbol}/yr" data-suffix-family="compound" placeholder="0" min="0" step="100">
                          </div>
                          <div class="vareoncalc-field">
                            <label for="extra-yearly-month">${__('Yearly Payment Month', textDomain)}</label>
                            <select id="extra-yearly-month">
                              ${monthOptions}
                            </select>
                          </div>
                        </div>
                        <div class="mortgage-card__grid-2">
                          <div class="vareoncalc-field">
                            <label for="extra-one-time">${__('One-Time Extra Payment', textDomain)}</label>
            <input type="number" id="extra-one-time" data-suffix="${currencySymbol}" data-suffix-family="currency" placeholder="0" min="0" step="100">
                          </div>
                          <div class="vareoncalc-field">
                            <label for="extra-one-time-date">${__('One-Time Payment Date', textDomain)}</label>
                            <input type="date" id="extra-one-time-date">
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>

          </div>

          <!-- Wizard Navigation -->
          <div class="vareoncalc-wizard__nav">
            <button type="button" class="vareoncalc-btn vareoncalc-btn--outline" data-wizard-back>${__('Back', textDomain)}</button>
            <button type="button" class="vareoncalc-btn" data-wizard-next>${__('Next', textDomain)}</button>
            <button type="button" class="vareoncalc-btn" data-wizard-finish>${__('See Results', textDomain)}</button>
          </div>

          <!-- Results Panel -->
          <div class="vareoncalc-wizard__results" data-wizard-results
               data-results-title="${__('Payment Breakdown', textDomain)}"
               data-results-subtitle="${__('Your mortgage summary and charts', textDomain)}"
               aria-hidden="true">
            <div class="mortgage-studio__result" id="result">
              <div class="mortgage-studio__empty">
                <div class="mortgage-studio__empty-icon">&#128202;</div>
                <div class="mortgage-studio__empty-text">${__('Calculating your payment breakdown...', textDomain)}</div>
              </div>
            </div>
            <button type="button" class="vareoncalc-btn vareoncalc-btn--outline mortgage-wizard__restart" data-wizard-restart>${__('Start Over', textDomain)}</button>
          </div>

        </div>
      </div>
    </div>
  `;

  InputAdornment.apply(container);
  HelpTooltip.apply(container);

  // Collect input references
  const homePriceInput = container.querySelector('#home-price');
  const downPaymentInput = container.querySelector('#down-payment');
  const downPaymentPercentInput = container.querySelector('#down-payment-percent');
  const loanTermInput = container.querySelector('#loan-term');
  const interestRateInput = container.querySelector('#interest-rate');
  const extraMonthlyInput = container.querySelector('#extra-monthly');
  const extraYearlyInput = container.querySelector('#extra-yearly');
  const extraYearlyMonthSelect = container.querySelector('#extra-yearly-month');
  const extraOneTimeInput = container.querySelector('#extra-one-time');
  const extraOneTimeDateInput = container.querySelector('#extra-one-time-date');
  const extraAdvancedToggle = container.querySelector('#mortgage-extra-advanced-toggle');
  const extraAdvancedToggleText = container.querySelector('.mortgage-extra__advanced-text');
  const extraAdvancedFields = container.querySelector('#mortgage-extra-advanced-fields');
  const propertyTaxInput = container.querySelector('#property-tax');
  const homeInsuranceInput = container.querySelector('#home-insurance');
  const propertyTaxToggle = container.querySelector('[data-escrow-toggle="property-tax"]');
  const homeInsuranceToggle = container.querySelector('[data-escrow-toggle="home-insurance"]');
  const propertyTaxUnit = container.querySelector('#property-tax-unit');
  const homeInsuranceUnit = container.querySelector('#home-insurance-unit');
  const propertyTaxHelper = container.querySelector('#property-tax-helper');
  const homeInsuranceHelper = container.querySelector('#home-insurance-helper');
  const hoaFeesInput = container.querySelector('#hoa-fees');
  const pmiInput = container.querySelector('#pmi');
  const startDateInput = container.querySelector('#start-date');
  const resultContainer = container.querySelector('#result');
  const layoutRefreshState = {
    frameId: 0,
    timerIds: []
  };

  const clearScheduledLayoutRefresh = () => {
    if (typeof window === 'undefined') {
      return;
    }

    if (layoutRefreshState.frameId) {
      window.cancelAnimationFrame(layoutRefreshState.frameId);
      layoutRefreshState.frameId = 0;
    }

    while (layoutRefreshState.timerIds.length > 0) {
      window.clearTimeout(layoutRefreshState.timerIds.pop());
    }
  };

  const triggerLayoutRefresh = () => {
    const refreshTarget = wizardRoot || resultContainer || container;
    if (refreshTarget?.style) {
      refreshTarget.style.setProperty('--vareoncalc-layout-refresh', String(Date.now()));
    }
  };

  const scheduleLayoutRefresh = (includeSettledPasses = true) => {
    if (typeof window === 'undefined') {
      triggerLayoutRefresh();
      return;
    }

    clearScheduledLayoutRefresh();

    layoutRefreshState.frameId = window.requestAnimationFrame(() => {
      layoutRefreshState.frameId = 0;
      triggerLayoutRefresh();
    });

    if (!includeSettledPasses) {
      return;
    }

    layoutRefreshState.timerIds = LAYOUT_REFRESH_DELAYS.map((delay) => window.setTimeout(() => {
      triggerLayoutRefresh();
    }, delay));
  };

  hostRoot._vareoncalcRefreshLayout = () => {
    scheduleLayoutRefresh(true);
  };

  const setInputRailSuffix = (input, suffix) => {
    if (!input) {
      return;
    }
    InputAdornment.setSuffix(input, suffix);
    input.closest('.vareoncalc-input-adorned')?.classList.add('vareoncalc-input-adorned--suffix-rail');
  };

  [
    homePriceInput,
    downPaymentInput,
    downPaymentPercentInput,
    interestRateInput,
    loanTermInput,
    propertyTaxInput,
    homeInsuranceInput,
    hoaFeesInput,
    pmiInput,
    extraMonthlyInput,
    extraYearlyInput,
    extraOneTimeInput,
  ].forEach((input) => {
    input?.closest('.vareoncalc-input-adorned')?.classList.add('vareoncalc-input-adorned--suffix-rail');
  });

  // Number helpers
  const parseNumber = (value) => {
    if (value === null || value === undefined) {
      return NaN;
    }
    const normalized = String(value).replace(/,/g, '').trim();
    if (!normalized) {
      return NaN;
    }
    const parsed = Number(normalized);
    return Number.isFinite(parsed) ? parsed : NaN;
  };

  const parseOptionalNumber = (value) => {
    const parsed = parseNumber(value);
    return Number.isFinite(parsed) ? parsed : 0;
  };

  const round2 = (value) => Math.round((value + Number.EPSILON) * 100) / 100;

  const formatNumber = (value) => {
    if (!Number.isFinite(value)) {
      return '';
    }
    return round2(value).toLocaleString(undefined, {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2
    });
  };

  const parseDateValue = (value) => {
    if (!value) {
      return null;
    }
    const parts = value.split('-').map(Number);
    if (parts.length !== 3 || parts.some(Number.isNaN)) {
      return null;
    }
    const [year, month, day] = parts;
    if (!year || !month || !day) {
      return null;
    }
    return new Date(year, month - 1, day);
  };

  const formatDateValue = (date) => {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
  };

  const formatDuration = (months) => {
    const totalMonths = Math.max(0, Math.round(months));
    const years = Math.floor(totalMonths / 12);
    const remainingMonths = totalMonths % 12;
    const parts = [];

    if (years > 0) {
      parts.push(sprintf(_n('%d year', '%d years', years, textDomain), years));
    }
    if (remainingMonths > 0 || parts.length === 0) {
      parts.push(sprintf(_n('%d month', '%d months', remainingMonths, textDomain), remainingMonths));
    }

    return parts.join(' ');
  };

  const validateOptionalNumber = (input) => {
    if (!input || input.value === '') {
      return true;
    }
    const value = parseNumber(input.value);
    return Number.isFinite(value) && value >= 0;
  };

  // Escrow toggle helpers
  const getEscrowMode = (toggle) => (toggle?.dataset.mode === 'percent' ? 'percent' : 'amount');

  const state = {
    homePrice: parseNumber(homePriceInput?.value),
    downPayment: parseOptionalNumber(downPaymentInput?.value),
    downPaymentPercent: parseOptionalNumber(downPaymentPercentInput?.value),
    downPaymentMode: 'amount',
    loanTerm: parseNumber(loanTermInput?.value),
    interestRate: parseNumber(interestRateInput?.value),
    propertyTax: parseOptionalNumber(propertyTaxInput?.value),
    propertyTaxMode: getEscrowMode(propertyTaxToggle),
    homeInsurance: parseOptionalNumber(homeInsuranceInput?.value),
    homeInsuranceMode: getEscrowMode(homeInsuranceToggle),
    hoaFees: parseOptionalNumber(hoaFeesInput?.value),
    pmi: parseOptionalNumber(pmiInput?.value),
    extraMonthly: parseOptionalNumber(extraMonthlyInput?.value),
    extraYearly: parseOptionalNumber(extraYearlyInput?.value),
    extraYearlyMonth: extraYearlyMonthSelect ? parseInt(extraYearlyMonthSelect.value, 10) : 1,
    extraOneTime: parseOptionalNumber(extraOneTimeInput?.value),
    extraOneTimeDate: parseDateValue(extraOneTimeDateInput?.value),
    startDate: parseDateValue(startDateInput?.value),
  };

  const updateStateSnapshot = () => {
    state.homePrice = parseNumber(homePriceInput?.value);
    state.downPayment = parseOptionalNumber(downPaymentInput?.value);
    state.downPaymentPercent = parseOptionalNumber(downPaymentPercentInput?.value);
    state.loanTerm = parseNumber(loanTermInput?.value);
    state.interestRate = parseNumber(interestRateInput?.value);
    state.propertyTax = parseOptionalNumber(propertyTaxInput?.value);
    state.homeInsurance = parseOptionalNumber(homeInsuranceInput?.value);
    state.hoaFees = parseOptionalNumber(hoaFeesInput?.value);
    state.pmi = parseOptionalNumber(pmiInput?.value);
    state.extraMonthly = parseOptionalNumber(extraMonthlyInput?.value);
    state.extraYearly = parseOptionalNumber(extraYearlyInput?.value);
    state.extraYearlyMonth = extraYearlyMonthSelect ? parseInt(extraYearlyMonthSelect.value, 10) : 1;
    state.extraOneTime = parseOptionalNumber(extraOneTimeInput?.value);
    state.extraOneTimeDate = parseDateValue(extraOneTimeDateInput?.value);
    state.startDate = parseDateValue(startDateInput?.value);
    state.propertyTaxMode = getEscrowMode(propertyTaxToggle);
    state.homeInsuranceMode = getEscrowMode(homeInsuranceToggle);
  };

  const setEscrowMode = (toggle, mode, fieldName) => {
    if (!toggle) {
      return;
    }
    toggle.dataset.mode = mode;
    toggle.setAttribute(
      'aria-label',
      sprintf(
        /* translators: 1: field name, 2: active mode */
        __('%1$s input mode: %2$s', textDomain),
        fieldName,
        mode === 'percent' ? __('percent', textDomain) : __('amount', textDomain)
      )
    );

    const options = toggle.querySelectorAll('button[data-escrow-mode-option]');
    options.forEach((option) => {
      const isActive = option.dataset.escrowModeOption === mode;
      option.classList.toggle('is-active', isActive);
      option.setAttribute('aria-pressed', isActive ? 'true' : 'false');
      option.setAttribute('tabindex', isActive ? '0' : '-1');
    });

    const radios = toggle.querySelectorAll('input[type="radio"]');
    radios.forEach((radio) => {
      radio.checked = radio.value === mode;
    });
  };

  const getEscrowEstimateState = (estimateType) => {
    const isTax = estimateType === 'property-tax';
    const input = isTax ? propertyTaxInput : homeInsuranceInput;
    const mode = isTax ? state.propertyTaxMode : state.homeInsuranceMode;

    if (!input || input.value === '') {
      return { valid: true, annualAmount: 0, mode, reason: '' };
    }

    const rawValue = parseNumber(input.value);
    if (!Number.isFinite(rawValue) || rawValue < 0) {
      return { valid: false, annualAmount: 0, mode, reason: 'invalid' };
    }

    if (mode === 'percent') {
      if (rawValue > 100) {
        return { valid: false, annualAmount: 0, mode, reason: 'invalid-percent' };
      }
      if (!Number.isFinite(state.homePrice) || state.homePrice <= 0) {
        return { valid: false, annualAmount: 0, mode, reason: 'home-price-required' };
      }
      return { valid: true, annualAmount: round2((rawValue / 100) * state.homePrice), mode, reason: '' };
    }

    return { valid: true, annualAmount: round2(rawValue), mode, reason: '' };
  };

  const getEscrowValidationMessage = (estimateType, reason) => {
    if (estimateType === 'property-tax') {
      if (reason === 'invalid-percent') {
        return __('Please enter a valid property tax percentage (0-100).', textDomain);
      }
      if (reason === 'home-price-required') {
        return __('Please enter a valid home price to use property tax percentage.', textDomain);
      }
      return __('Please enter a valid property tax amount.', textDomain);
    }
    if (reason === 'invalid-percent') {
      return __('Please enter a valid home insurance percentage (0-100).', textDomain);
    }
    if (reason === 'home-price-required') {
      return __('Please enter a valid home price to use home insurance percentage.', textDomain);
    }
    return __('Please enter a valid home insurance amount.', textDomain);
  };

  const updateEscrowEstimateUi = ({ input, toggle, unit, helper, amountPlaceholder, percentPlaceholder }) => {
    if (!input || !toggle) {
      return;
    }

    const mode = getEscrowMode(toggle);
    if (mode === 'percent') {
      input.step = '0.1';
      input.placeholder = percentPlaceholder;
      setInputRailSuffix(input, '%');
      if (unit) {
        unit.textContent = '%';
      }
    } else {
      input.step = '100';
      input.placeholder = amountPlaceholder;
      setInputRailSuffix(input, `${currencySymbol}/yr`);
      if (unit) {
        unit.textContent = '/yr';
      }
    }

    if (!helper) {
      return;
    }

    const estimateType = toggle.dataset.escrowToggle;
    const estimate = getEscrowEstimateState(estimateType);
    if (mode === 'percent') {
      if (estimate.reason === 'home-price-required') {
        helper.textContent = __('Enter a home price to calculate costs.', textDomain);
        return;
      }
      if (!estimate.valid) {
        helper.textContent = __('Enter a valid percentage.', textDomain);
        return;
      }
      const monthlyAmount = round2(estimate.annualAmount / 12);
      helper.textContent = sprintf(
        /* translators: 1: annual amount, 2: monthly amount */
        __('Calculated: %1$s/yr (%2$s/mo)', textDomain),
        formatCurrency(estimate.annualAmount),
        formatCurrency(monthlyAmount)
      );
      return;
    }

    if (!estimate.valid) {
      helper.textContent = __('Enter a valid annual amount.', textDomain);
      return;
    }

    const monthlyAmount = round2(estimate.annualAmount / 12);
    helper.textContent = sprintf(
      /* translators: %s: monthly amount */
      __('(%s/mo)', textDomain),
      formatCurrency(monthlyAmount)
    );
  };

  const updateEscrowEstimateHelpers = () => {
    updateEscrowEstimateUi({
      input: propertyTaxInput,
      toggle: propertyTaxToggle,
      unit: propertyTaxUnit,
      helper: propertyTaxHelper,
      amountPlaceholder: `${__('e.g.', textDomain)} 3600`,
      percentPlaceholder: `${__('e.g.', textDomain)} 1.2`,
    });
    updateEscrowEstimateUi({
      input: homeInsuranceInput,
      toggle: homeInsuranceToggle,
      unit: homeInsuranceUnit,
      helper: homeInsuranceHelper,
      amountPlaceholder: `${__('e.g.', textDomain)} 1200`,
      percentPlaceholder: `${__('e.g.', textDomain)} 0.35`,
    });
  };

  const wireEscrowToggle = (toggle, input, fieldName) => {
    if (!toggle) {
      return;
    }

    const estimateType = toggle.dataset.escrowToggle;
    const setModeState = (mode) => {
      if (estimateType === 'property-tax') {
        state.propertyTaxMode = mode;
        return;
      }
      state.homeInsuranceMode = mode;
    };

    const convertValueForMode = (fromMode, toMode) => {
      if (!input || input.value === '' || fromMode === toMode) {
        return;
      }
      const rawValue = parseNumber(input.value);
      if (!Number.isFinite(rawValue) || rawValue < 0 || !Number.isFinite(state.homePrice) || state.homePrice <= 0) {
        return;
      }
      if (fromMode === 'amount' && toMode === 'percent') {
        input.value = String(round2((rawValue / state.homePrice) * 100));
        return;
      }
      if (fromMode === 'percent' && toMode === 'amount') {
        input.value = String(round2((rawValue / 100) * state.homePrice));
      }
    };

    const activateMode = (mode) => {
      const previousMode = getEscrowMode(toggle);
      convertValueForMode(previousMode, mode);
      setModeState(mode);
      setEscrowMode(toggle, mode, fieldName);
      updateStateSnapshot();
      updateEscrowEstimateHelpers();
      if (input) {
        input.focus();
      }
    };

    toggle.addEventListener('click', (event) => {
      const target = event.target.closest('button[data-escrow-mode-option]');
      if (!target) {
        return;
      }
      const nextMode = target.dataset.escrowModeOption;
      if (!nextMode || nextMode === getEscrowMode(toggle)) {
        return;
      }
      activateMode(nextMode);
    });

    toggle.addEventListener('keydown', (event) => {
      if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') {
        return;
      }
      event.preventDefault();
      const nextMode = getEscrowMode(toggle) === 'amount' ? 'percent' : 'amount';
      activateMode(nextMode);
    });
  };

  wireEscrowToggle(propertyTaxToggle, propertyTaxInput, __('Property tax', textDomain));
  wireEscrowToggle(homeInsuranceToggle, homeInsuranceInput, __('Home insurance', textDomain));
  setEscrowMode(propertyTaxToggle, getEscrowMode(propertyTaxToggle), __('Property tax', textDomain));
  setEscrowMode(homeInsuranceToggle, getEscrowMode(homeInsuranceToggle), __('Home insurance', textDomain));
  updateEscrowEstimateHelpers();

  if (propertyTaxInput) {
    propertyTaxInput.addEventListener('input', () => {
      state.propertyTax = parseOptionalNumber(propertyTaxInput.value);
      updateEscrowEstimateHelpers();
    });
  }
  if (homeInsuranceInput) {
    homeInsuranceInput.addEventListener('input', () => {
      state.homeInsurance = parseOptionalNumber(homeInsuranceInput.value);
      updateEscrowEstimateHelpers();
    });
  }

  // Extra payments advanced toggle
  const setExtraAdvancedOpen = (open) => {
    if (!extraAdvancedToggle || !extraAdvancedFields) {
      return;
    }
    extraAdvancedToggle.setAttribute('aria-expanded', open ? 'true' : 'false');
    if (extraAdvancedToggleText) {
      extraAdvancedToggleText.textContent = open
        ? __('Hide options', textDomain)
        : __('Show more options', textDomain);
    }
    extraAdvancedFields.hidden = !open;
  };

  if (extraAdvancedToggle && extraAdvancedFields) {
    setExtraAdvancedOpen(false);
    extraAdvancedToggle.addEventListener('click', () => {
      setExtraAdvancedOpen(extraAdvancedFields.hidden);
    });
  }

  // Default date values
  const today = new Date();
  if (startDateInput && !startDateInput.value) {
    startDateInput.value = formatDateValue(today);
  }

  if (extraYearlyMonthSelect) {
    const startDate = parseDateValue(startDateInput?.value) || today;
    extraYearlyMonthSelect.value = String(startDate.getMonth() + 1);
    extraYearlyMonthSelect.dataset.auto = '1';
  }

  if (startDateInput && extraYearlyMonthSelect) {
    startDateInput.addEventListener('change', () => {
      state.startDate = parseDateValue(startDateInput.value);
      if (extraYearlyMonthSelect.dataset.auto === '1') {
        const startDate = state.startDate || today;
        extraYearlyMonthSelect.value = String(startDate.getMonth() + 1);
        state.extraYearlyMonth = parseInt(extraYearlyMonthSelect.value, 10);
      }
    });
  }

  if (extraYearlyMonthSelect) {
    extraYearlyMonthSelect.addEventListener('change', () => {
      extraYearlyMonthSelect.dataset.auto = '0';
      state.extraYearlyMonth = parseInt(extraYearlyMonthSelect.value, 10);
    });
  }

  updateStateSnapshot();

  // Down payment sync (state-driven)
  const syncDownPaymentFromAmount = () => {
    state.downPaymentMode = 'amount';
    state.downPayment = parseOptionalNumber(downPaymentInput?.value);
    if (Number.isFinite(state.homePrice) && state.homePrice > 0) {
      state.downPaymentPercent = round2((state.downPayment / state.homePrice) * 100);
      if (downPaymentPercentInput) {
        downPaymentPercentInput.value = state.downPaymentPercent.toFixed(2);
      }
    } else {
      state.downPaymentPercent = 0;
    }
  };

  const syncDownPaymentFromPercent = () => {
    state.downPaymentMode = 'percent';
    state.downPaymentPercent = parseOptionalNumber(downPaymentPercentInput?.value);
    if (Number.isFinite(state.homePrice) && state.homePrice > 0) {
      state.downPayment = round2((state.downPaymentPercent / 100) * state.homePrice);
      if (downPaymentInput) {
        downPaymentInput.value = String(Math.round(state.downPayment));
      }
    } else {
      state.downPayment = 0;
    }
  };

  const syncDownPaymentForHomePrice = () => {
    state.homePrice = parseNumber(homePriceInput?.value);
    if (!Number.isFinite(state.homePrice) || state.homePrice <= 0) {
      return;
    }
    if (state.downPaymentMode === 'percent') {
      state.downPayment = round2((state.downPaymentPercent / 100) * state.homePrice);
      if (downPaymentInput && downPaymentPercentInput?.value !== '') {
        downPaymentInput.value = String(Math.round(state.downPayment));
      }
      return;
    }
    state.downPaymentPercent = round2((state.downPayment / state.homePrice) * 100);
    if (downPaymentPercentInput && downPaymentInput?.value !== '') {
      downPaymentPercentInput.value = state.downPaymentPercent.toFixed(2);
    }
  };

  downPaymentInput?.addEventListener('input', syncDownPaymentFromAmount);
  downPaymentPercentInput?.addEventListener('input', syncDownPaymentFromPercent);
  homePriceInput?.addEventListener('input', () => {
    syncDownPaymentForHomePrice();
    updateEscrowEstimateHelpers();
  });
  loanTermInput?.addEventListener('input', () => {
    state.loanTerm = parseNumber(loanTermInput.value);
  });
  interestRateInput?.addEventListener('input', () => {
    state.interestRate = parseNumber(interestRateInput.value);
  });
  hoaFeesInput?.addEventListener('input', () => {
    state.hoaFees = parseOptionalNumber(hoaFeesInput.value);
  });
  pmiInput?.addEventListener('input', () => {
    state.pmi = parseOptionalNumber(pmiInput.value);
  });
  extraMonthlyInput?.addEventListener('input', () => {
    state.extraMonthly = parseOptionalNumber(extraMonthlyInput.value);
  });
  extraYearlyInput?.addEventListener('input', () => {
    state.extraYearly = parseOptionalNumber(extraYearlyInput.value);
  });
  extraOneTimeInput?.addEventListener('input', () => {
    state.extraOneTime = parseOptionalNumber(extraOneTimeInput.value);
  });
  startDateInput?.addEventListener('change', () => {
    state.startDate = parseDateValue(startDateInput.value);
  });
  extraOneTimeDateInput?.addEventListener('change', () => {
    state.extraOneTimeDate = parseDateValue(extraOneTimeDateInput.value);
  });

  // SVG chart generators
  const generateDonutChart = (segments) => {
    const size = 180;
    const strokeWidth = 22;
    const radius = (size - strokeWidth) / 2;
    const circumference = 2 * Math.PI * radius;
    const centerX = size / 2;
    const centerY = size / 2;

    const activeSegments = segments.filter(s => s.value > 0);
    const total = activeSegments.reduce((sum, s) => sum + s.value, 0);

    if (total === 0) return '';

    let paths = '';
    let cumulativePercent = 0;

    activeSegments.forEach((segment) => {
      const percent = segment.value / total;
      const dashLength = circumference * percent;
      const dashOffset = circumference * (1 - cumulativePercent) + circumference / 4;

      paths += `
        <circle
          cx="${centerX}"
          cy="${centerY}"
          r="${radius}"
          fill="none"
          stroke="${segment.color}"
          stroke-width="${strokeWidth}"
          stroke-dasharray="${dashLength} ${circumference - dashLength}"
          stroke-dashoffset="${dashOffset}"
          class="mortgage-donut__segment"
          style="transition: stroke-dasharray 0.5s ease, stroke-dashoffset 0.5s ease;"
        />
      `;

      cumulativePercent += percent;
    });

    return `
      <svg viewBox="0 0 ${size} ${size}" class="mortgage-donut__svg" role="img" aria-label="${__('Monthly payment composition donut chart', textDomain)}">
        <circle
          cx="${centerX}"
          cy="${centerY}"
          r="${radius}"
          fill="none"
          stroke="var(--sc-card-border, #e5e7eb)"
          stroke-width="${strokeWidth}"
          opacity="0.3"
        />
        ${paths}
      </svg>
    `;
  };

  const generateAmortizationChart = (points, crossoverMonth) => {
    if (!points || points.length === 0) {
      return { html: '', hoverData: null };
    }

    let chartPoints = points;
    if (chartPoints.length > 2) {
      const last = chartPoints[chartPoints.length - 1];
      const prev = chartPoints[chartPoints.length - 2];
      if (last.principal < prev.principal * 0.7) {
        chartPoints = chartPoints.slice(0, -1);
      }
    }

    const width = 480;
    const height = 220;
    const padding = { top: 24, right: 16, bottom: 44, left: 54 };
    const chartWidth = width - padding.left - padding.right;
    const chartHeight = height - padding.top - padding.bottom;

    const maxValue = Math.max(...chartPoints.map(point => Math.max(point.principal, point.interest)));
    const maxMonth = chartPoints[chartPoints.length - 1].month;

    if (!Number.isFinite(maxValue) || maxValue <= 0 || maxMonth <= 0) {
      return { html: '', hoverData: null };
    }

    const maxYears = (maxMonth % 12) <= 2
      ? Math.floor(maxMonth / 12)
      : Math.ceil(maxMonth / 12);
    const maxDomainMonths = Math.max(12, maxYears * 12);

    const scaleX = (month) => padding.left + (month / maxDomainMonths) * chartWidth;
    const scaleY = (value) => padding.top + chartHeight - (value / maxValue) * chartHeight;

    const yGridlines = [];
    const yAxisLabels = [];
    for (let i = 1; i <= 3; i += 1) {
      const yValue = (maxValue / 4) * i;
      const y = scaleY(yValue);
      yGridlines.push(`<line x1="${padding.left}" y1="${y}" x2="${width - padding.right}" y2="${y}" class="mortgage-amortization__gridline" />`);
      yAxisLabels.push(`<text x="${padding.left - 8}" y="${y + 3}" text-anchor="end" class="mortgage-amortization__ylabel">${formatCompactCurrency(yValue)}</text>`);
    }

    const buildLine = (key) => {
      let path = `M ${scaleX(chartPoints[0].month)} ${scaleY(chartPoints[0][key])}`;
      chartPoints.slice(1).forEach(point => {
        path += ` L ${scaleX(point.month)} ${scaleY(point[key])}`;
      });
      return path;
    };

    const principalLine = buildLine('principal');
    const interestLine = buildLine('interest');

    const labelInterval = maxYears <= 5 ? 1 : maxYears <= 15 ? 2 : maxYears <= 30 ? 5 : 10;
    const yearLabels = [];

    for (let year = 0; year <= maxYears; year += labelInterval) {
      yearLabels.push(`<text x="${scaleX(year * 12)}" y="${height - 22}" text-anchor="middle" class="mortgage-amortization__label">${year}</text>`);
    }
    if (maxYears % labelInterval !== 0) {
      yearLabels.push(`<text x="${scaleX(maxYears * 12)}" y="${height - 22}" text-anchor="middle" class="mortgage-amortization__label">${maxYears}</text>`);
    }

    const crossoverIndex = crossoverMonth ? Math.min(crossoverMonth - 1, chartPoints.length - 1) : null;
    const crossoverX = crossoverIndex !== null ? scaleX(chartPoints[crossoverIndex].month) : null;
    const crossoverY = crossoverIndex !== null ? scaleY(chartPoints[crossoverIndex].principal) : null;

    let crossoverMarker = '';
    if (crossoverX !== null && crossoverMonth) {
      const yrs = Math.floor(crossoverMonth / 12);
      const mos = crossoverMonth % 12;
      const label = yrs > 0
        ? (mos > 0 ? `${yrs}y ${mos}m` : `${yrs}y`)
        : `${crossoverMonth}m`;
      crossoverMarker = `
        <circle cx="${crossoverX}" cy="${crossoverY}" r="5" fill="var(--sc-card-bg, #fff)" stroke="var(--sc-card-text, #111827)" stroke-width="2" class="mortgage-amortization__crossover-point" />
        <text x="${crossoverX}" y="${crossoverY - 12}" text-anchor="middle" class="mortgage-amortization__crossover-label">${label}</text>
      `;
    }

    const axisLabelX = padding.left + chartWidth / 2;
    const html = `
      <svg viewBox="0 0 ${width} ${height}" class="mortgage-amortization__svg" preserveAspectRatio="xMidYMid meet" role="img" aria-label="${__('Principal and interest payment trends over time', textDomain)}">
        ${yGridlines.join('\n        ')}
        ${yAxisLabels.join('\n        ')}
        ${crossoverX !== null ? `<line x1="${crossoverX}" y1="${padding.top}" x2="${crossoverX}" y2="${padding.top + chartHeight}" class="mortgage-amortization__crossover" />` : ''}
        <path d="${interestLine}" fill="none" stroke="var(--vareoncalc-chart-interest, #f97316)" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="mortgage-amortization__line mortgage-amortization__line--interest" />
        <path d="${principalLine}" fill="none" stroke="var(--vareoncalc-chart-principal, #3b82f6)" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="mortgage-amortization__line mortgage-amortization__line--principal" />
        ${crossoverMarker}
        ${yearLabels.join('\n        ')}
        <text x="${axisLabelX}" y="${height - 4}" text-anchor="middle" class="mortgage-amortization__axis-label">${__('Years', textDomain)}</text>
        <line class="mortgage-amortization__crosshair" x1="0" y1="${padding.top}" x2="0" y2="${padding.top + chartHeight}" style="display:none" />
        <circle class="mortgage-amortization__dot mortgage-amortization__dot--principal" r="4.5" cx="0" cy="0" style="display:none" />
        <circle class="mortgage-amortization__dot mortgage-amortization__dot--interest" r="4.5" cx="0" cy="0" style="display:none" />
        <rect class="mortgage-amortization__overlay" x="${padding.left}" y="0" width="${chartWidth}" height="${height}" fill="transparent" />
      </svg>
    `;

    return {
      html,
      hoverData: {
        points: chartPoints,
        maxValue,
        maxDomainMonths,
        padding,
        chartWidth,
        chartHeight,
      },
    };
  };

  const attachAmortizationChartHover = (chartEl, hoverData) => {
    if (!chartEl || !hoverData || !Array.isArray(hoverData.points) || hoverData.points.length < 2) {
      return null;
    }

    const svg = chartEl.querySelector('.mortgage-amortization__svg');
    const overlay = svg?.querySelector('.mortgage-amortization__overlay');
    const crosshair = svg?.querySelector('.mortgage-amortization__crosshair');
    const principalDot = svg?.querySelector('.mortgage-amortization__dot--principal');
    const interestDot = svg?.querySelector('.mortgage-amortization__dot--interest');
    if (!overlay || !svg) {
      return null;
    }

    const { points, maxValue, maxDomainMonths, padding, chartWidth, chartHeight } = hoverData;
    const scaleX = (month) => padding.left + (month / maxDomainMonths) * chartWidth;
    const scaleY = (value) => padding.top + chartHeight - (value / maxValue) * chartHeight;

    let tooltip = chartEl.querySelector('.mortgage-amortization__tooltip');
    if (!tooltip) {
      tooltip = document.createElement('div');
      tooltip.className = 'mortgage-amortization__tooltip';
      chartEl.appendChild(tooltip);
    }

    const hideHover = () => {
      if (crosshair) {
        crosshair.style.display = 'none';
      }
      if (principalDot) {
        principalDot.style.display = 'none';
      }
      if (interestDot) {
        interestDot.style.display = 'none';
      }
      tooltip.style.display = 'none';
    };

    const handleMove = (event) => {
      const overlayRect = overlay.getBoundingClientRect();
      const chartRect = chartEl.getBoundingClientRect();
      const monthApprox = mapHoverClientXToScalar(event.clientX, overlayRect, maxDomainMonths);
      const nearest = findNearestPoint(points, monthApprox, (point) => point.month);
      if (!nearest) {
        hideHover();
        return;
      }

      const x = scaleX(nearest.month);
      const principalY = scaleY(nearest.principal);
      const interestY = scaleY(nearest.interest);

      if (crosshair) {
        crosshair.setAttribute('x1', x);
        crosshair.setAttribute('x2', x);
        crosshair.style.display = '';
      }
      if (principalDot) {
        principalDot.setAttribute('cx', x);
        principalDot.setAttribute('cy', principalY);
        principalDot.style.display = '';
      }
      if (interestDot) {
        interestDot.setAttribute('cx', x);
        interestDot.setAttribute('cy', interestY);
        interestDot.style.display = '';
      }

      const yearValue = nearest.month / 12;
      const yearLabel = Math.abs(Math.round(yearValue) - yearValue) < 0.05
        ? String(Math.round(yearValue))
        : yearValue.toFixed(1);
      tooltip.innerHTML = `
        <div class="mortgage-amortization__tooltip-year">${sprintf(__('Year %s', textDomain), yearLabel)}</div>
        <div class="mortgage-amortization__tooltip-row">
          <span class="mortgage-amortization__tooltip-dot mortgage-amortization__tooltip-dot--principal"></span>
          <span class="mortgage-amortization__tooltip-label">${__('Principal', textDomain)}</span>
          <span class="mortgage-amortization__tooltip-value">${formatCurrencyHtml(nearest.principal)}</span>
        </div>
        <div class="mortgage-amortization__tooltip-row">
          <span class="mortgage-amortization__tooltip-dot mortgage-amortization__tooltip-dot--interest"></span>
          <span class="mortgage-amortization__tooltip-label">${__('Interest', textDomain)}</span>
          <span class="mortgage-amortization__tooltip-value">${formatCurrencyHtml(nearest.interest)}</span>
        </div>
      `;

      positionChartTooltip(tooltip, event.clientX, event.clientY, chartRect);
      tooltip.style.display = 'block';
    };

    overlay.addEventListener('mousemove', handleMove);
    overlay.addEventListener('mouseleave', hideHover);

    return () => {
      overlay.removeEventListener('mousemove', handleMove);
      overlay.removeEventListener('mouseleave', hideHover);
      if (tooltip && tooltip.parentNode === chartEl) {
        chartEl.removeChild(tooltip);
      }
    };
  };

  const isMobileResultsViewport = () => {
    if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
      return false;
    }
    return window.matchMedia(`(max-width: ${MOBILE_RESULTS_MAX_WIDTH}px)`).matches;
  };

  const wireMobileResultsTabs = (resultsRoot) => {
    if (!resultsRoot) {
      return;
    }

    const tabButtons = Array.from(resultsRoot.querySelectorAll('.mortgage-results-tab[role="tab"]'));
    const tabPanels = Array.from(resultsRoot.querySelectorAll('.mortgage-results-panel[role="tabpanel"]'));
    if (!tabButtons.length || !tabPanels.length) {
      return;
    }

    const activateTab = (tabId, focusTab = false) => {
      tabButtons.forEach((button) => {
        const isActive = button.dataset.tab === tabId;
        button.classList.toggle('mortgage-results-tab--active', isActive);
        button.setAttribute('aria-selected', isActive ? 'true' : 'false');
        button.setAttribute('tabindex', isActive ? '0' : '-1');
        if (isActive && focusTab) {
          button.focus();
        }
      });

      tabPanels.forEach((panel) => {
        const isActive = panel.dataset.tabPanel === tabId;
        panel.classList.toggle('mortgage-results-panel--active', isActive);
        panel.hidden = !isActive;
      });

      scheduleLayoutRefresh(true);
    };

    tabButtons.forEach((button) => {
      button.addEventListener('click', () => {
        const tabId = button.dataset.tab;
        if (tabId) {
          activateTab(tabId);
        }
      });
    });

    tabButtons.forEach((button) => {
      button.addEventListener('keydown', (event) => {
        if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) {
          return;
        }

        event.preventDefault();
        const currentIndex = tabButtons.findIndex((candidate) => candidate.getAttribute('aria-selected') === 'true');
        const safeIndex = currentIndex >= 0 ? currentIndex : 0;
        let nextIndex = safeIndex;

        if (event.key === 'ArrowRight') {
          nextIndex = (safeIndex + 1) % tabButtons.length;
        } else if (event.key === 'ArrowLeft') {
          nextIndex = (safeIndex - 1 + tabButtons.length) % tabButtons.length;
        } else if (event.key === 'Home') {
          nextIndex = 0;
        } else if (event.key === 'End') {
          nextIndex = tabButtons.length - 1;
        }

        const nextTabId = tabButtons[nextIndex]?.dataset.tab;
        if (nextTabId) {
          activateTab(nextTabId, true);
        }
      });
    });
  };

  // Main calculation function
  const calculate = () => {
    ValidationHelpers.clearAllErrors(container);
    updateStateSnapshot();

    const homePrice = state.homePrice;
    const loanTerm = state.loanTerm;
    const interestRate = state.interestRate;
    const downPayment = state.downPayment;

    if (!Number.isFinite(homePrice) || homePrice <= 0) {
      ValidationHelpers.markInvalid(homePriceInput, {
        validator: () => { const v = parseNumber(homePriceInput.value); return Number.isFinite(v) && v > 0; },
      });
      ValidationHelpers.showResultError(resultContainer, __('Please enter a valid home price.', textDomain));
      return;
    }

    if (!Number.isFinite(loanTerm) || loanTerm <= 0 || loanTerm > 50) {
      ValidationHelpers.markInvalid(loanTermInput, {
        validator: () => { const v = parseNumber(loanTermInput.value); return Number.isFinite(v) && v > 0 && v <= 50; },
      });
      ValidationHelpers.showResultError(resultContainer, __('Please enter a valid loan term (1-50 years).', textDomain));
      return;
    }

    if (!Number.isFinite(interestRate) || interestRate < 0 || interestRate > 25) {
      ValidationHelpers.markInvalid(interestRateInput, {
        validator: () => { const v = parseNumber(interestRateInput.value); return Number.isFinite(v) && v >= 0 && v <= 25; },
      });
      ValidationHelpers.showResultError(resultContainer, __('Please enter a valid interest rate (0-25%).', textDomain));
      return;
    }

    if (downPaymentInput.value && (!Number.isFinite(parseNumber(downPaymentInput.value)) || parseNumber(downPaymentInput.value) < 0)) {
      ValidationHelpers.markInvalid(downPaymentInput, {
        allowEmpty: true,
        validator: () => { const r = downPaymentInput.value; if (r === '') return true; const v = parseNumber(r); return Number.isFinite(v) && v >= 0; },
      });
      ValidationHelpers.showResultError(resultContainer, __('Please enter a valid down payment.', textDomain));
      return;
    }

    if (downPaymentPercentInput.value) {
      const pv = parseNumber(downPaymentPercentInput.value);
      if (!Number.isFinite(pv) || pv < 0 || pv > 100) {
        ValidationHelpers.markInvalid(downPaymentPercentInput, {
          allowEmpty: true,
          validator: () => { const r = downPaymentPercentInput.value; if (r === '') return true; const v = parseNumber(r); return Number.isFinite(v) && v >= 0 && v <= 100; },
        });
        ValidationHelpers.showResultError(resultContainer, __('Please enter a valid down payment percentage.', textDomain));
        return;
      }
    }

    if (downPayment >= homePrice) {
      const dpv = () => { const hp = parseNumber(homePriceInput.value); const dv = parseOptionalNumber(downPaymentInput.value); return Number.isFinite(hp) && hp > 0 && dv < hp; };
      ValidationHelpers.markInvalid(downPaymentInput, { allowEmpty: true, validator: dpv });
      if (downPaymentPercentInput?.value) {
        ValidationHelpers.markInvalid(downPaymentPercentInput, { allowEmpty: true, validator: dpv });
      }
      ValidationHelpers.showResultError(resultContainer, __('Down payment cannot be greater than or equal to home price.', textDomain));
      return;
    }

    const ensureOptional = (input, message) => {
      if (!input || input.value === '') return true;
      const value = parseNumber(input.value);
      if (!Number.isFinite(value) || value < 0) {
        ValidationHelpers.markInvalid(input, {
          allowEmpty: true,
          validator: () => { const r = input.value; if (r === '') return true; const nv = parseNumber(r); return Number.isFinite(nv) && nv >= 0; },
        });
        ValidationHelpers.showResultError(resultContainer, message);
        return false;
      }
      return true;
    };

    const propertyTaxEstimate = getEscrowEstimateState('property-tax');
    if (!propertyTaxEstimate.valid) {
      ValidationHelpers.markInvalid(propertyTaxInput, { allowEmpty: true, validator: () => getEscrowEstimateState('property-tax').valid });
      if (propertyTaxEstimate.reason === 'home-price-required') {
        ValidationHelpers.markInvalid(homePriceInput, { validator: () => { const v = parseNumber(homePriceInput.value); return Number.isFinite(v) && v > 0; } });
      }
      ValidationHelpers.showResultError(resultContainer, getEscrowValidationMessage('property-tax', propertyTaxEstimate.reason));
      return;
    }

    const homeInsuranceEstimate = getEscrowEstimateState('home-insurance');
    if (!homeInsuranceEstimate.valid) {
      ValidationHelpers.markInvalid(homeInsuranceInput, { allowEmpty: true, validator: () => getEscrowEstimateState('home-insurance').valid });
      if (homeInsuranceEstimate.reason === 'home-price-required') {
        ValidationHelpers.markInvalid(homePriceInput, { validator: () => { const v = parseNumber(homePriceInput.value); return Number.isFinite(v) && v > 0; } });
      }
      ValidationHelpers.showResultError(resultContainer, getEscrowValidationMessage('home-insurance', homeInsuranceEstimate.reason));
      return;
    }

    if (!ensureOptional(hoaFeesInput, __('Please enter a valid HOA fee.', textDomain))) return;
    if (!ensureOptional(pmiInput, __('Please enter a valid PMI amount.', textDomain))) return;
    if (!ensureOptional(extraMonthlyInput, __('Please enter a valid extra monthly payment.', textDomain))) return;
    if (!ensureOptional(extraYearlyInput, __('Please enter a valid extra yearly payment.', textDomain))) return;
    if (!ensureOptional(extraOneTimeInput, __('Please enter a valid one-time extra payment.', textDomain))) return;

    const extraOneTimeValue = state.extraOneTime;
    if (extraOneTimeValue > 0 && !extraOneTimeDateInput?.value) {
      ValidationHelpers.markInvalid(extraOneTimeDateInput, {
        validator: () => { const a = parseOptionalNumber(extraOneTimeInput?.value); if (!a || a <= 0) return true; return !!extraOneTimeDateInput?.value; },
      });
      ValidationHelpers.showResultError(resultContainer, __('Please select a one-time payment date.', textDomain));
      return;
    }

    const loanAmount = round2(homePrice - downPayment);
    const escrow = calculateMortgageEscrow({
      homePrice,
      propertyTaxValue: propertyTaxEstimate.annualAmount,
      propertyTaxMode: 'amount',
      homeInsuranceValue: homeInsuranceEstimate.annualAmount,
      homeInsuranceMode: 'amount',
      hoaFeesMonthly: state.hoaFees,
      pmiMonthly: state.pmi,
    });

    const monthlyEscrow = escrow.monthlyEscrow;
    const extraMonthly = state.extraMonthly;
    const extraYearly = state.extraYearly;
    const startDate = state.startDate || today;
    const extraYearlyMonth = Number.isFinite(state.extraYearlyMonth)
      ? state.extraYearlyMonth
      : (startDate.getMonth() + 1);
    const extraOneTimeDate = state.extraOneTimeDate;

    const baseSchedule = calculateMortgageAmortization({
      principal: loanAmount,
      annualRatePercent: interestRate,
      termYears: loanTerm,
      startDate,
      extraMonthly: 0,
      extraYearly: 0,
      extraYearlyMonth,
      extraOneTime: 0,
      extraOneTimeDate: null,
      monthlyEscrow,
    });

    const hasExtras = extraMonthly > 0 || extraYearly > 0 || extraOneTimeValue > 0;
    const extraSchedule = hasExtras
      ? calculateMortgageAmortization({
          principal: loanAmount,
          annualRatePercent: interestRate,
          termYears: loanTerm,
          startDate,
          extraMonthly,
          extraYearly,
          extraYearlyMonth,
          extraOneTime: extraOneTimeValue,
          extraOneTimeDate,
          monthlyEscrow,
        })
      : baseSchedule;

    if (!baseSchedule || !extraSchedule) {
      ValidationHelpers.showResultError(resultContainer, __('Unable to calculate mortgage details with the current inputs.', textDomain));
      return;
    }

    const monthlyBaseTotal = round2(baseSchedule.baseMonthlyPI + monthlyEscrow);
    const monthlyWithExtra = round2(monthlyBaseTotal + extraMonthly);
    const monthlyDisplay = extraMonthly > 0 ? monthlyWithExtra : monthlyBaseTotal;
    const downPaymentPercent = ((downPayment / homePrice) * 100).toFixed(1);

    const firstMonth = extraSchedule.firstMonth || { principal: 0, interest: 0 };
    const taxInsMonthly = monthlyEscrow;

    const chartSegments = [
      { label: __('Principal', textDomain), value: firstMonth.principal, color: PAYMENT_COLORS.principal },
      { label: __('Interest', textDomain), value: firstMonth.interest, color: PAYMENT_COLORS.interest },
      { label: __('Tax/Ins', textDomain), value: taxInsMonthly, color: PAYMENT_COLORS.taxIns },
    ];

    const baseTotalPaid = baseSchedule.totalPaidWithEscrow;
    const extraTotalPaid = extraSchedule.totalPaidWithEscrow;
    const interestSaved = Math.max(0, round2(baseSchedule.totalInterest - extraSchedule.totalInterest));
    const monthsSaved = Math.max(0, baseSchedule.months - extraSchedule.months);
    const amortizationChart = generateAmortizationChart(extraSchedule.points, extraSchedule.crossoverMonth);

    if (typeof resultContainer._mortgageChartCleanup === 'function') {
      resultContainer._mortgageChartCleanup();
      resultContainer._mortgageChartCleanup = null;
    }

    const monthlyDetailHtml = extraMonthly > 0 ? `
      <div class="mortgage-results__hero-detail">
        <span class="mortgage-results__hero-detail-item">${__('Base', textDomain)}: ${formatCurrencyHtml(monthlyBaseTotal)}</span>
        <span class="mortgage-results__hero-detail-sep">+</span>
        <span class="mortgage-results__hero-detail-item mortgage-results__hero-detail-item--extra">${__('Extra', textDomain)}: ${formatCurrencyHtml(extraMonthly)}</span>
      </div>
    ` : '';

    const chartTotal = chartSegments.reduce((sum, s) => sum + s.value, 0);
    const segmentsWithPct = chartSegments.filter(s => s.value > 0).map(s => ({
      ...s,
      pct: chartTotal > 0 ? Math.round((s.value / chartTotal) * 100) : 0,
    }));

    const makeDonutLabel = (seg) => `
      <div class="mortgage-donut__label">
        <span class="mortgage-donut__label-line"><span class="mortgage-donut__label-name" style="color:${seg.color}">${seg.label}:</span> ${formatCurrencyHtml(seg.value)}</span>
        <span class="mortgage-donut__label-pct">${seg.pct}%</span>
      </div>
    `;

    const principalSeg = segmentsWithPct.find(s => s.color === PAYMENT_COLORS.principal);
    const interestSeg = segmentsWithPct.find(s => s.color === PAYMENT_COLORS.interest);
    const taxInsSeg = segmentsWithPct.find(s => s.color === PAYMENT_COLORS.taxIns);

    const leftLabelsHtml = [taxInsSeg, interestSeg].filter(Boolean).map(makeDonutLabel).join('');
    const rightLabelsHtml = [principalSeg].filter(Boolean).map(makeDonutLabel).join('');

    const legendFallbackHtml = segmentsWithPct.map(s => `
      <div class="mortgage-results__legend-row">
        <span class="mortgage-results__legend-dot" style="background:${s.color}"></span>
        <span class="mortgage-results__legend-name">${s.label}</span>
        <span class="mortgage-results__legend-amount">${formatCurrencyHtml(s.value)}</span>
        <span class="mortgage-results__legend-pct">${s.pct}%</span>
      </div>
    `).join('');

    const heroSectionHtml = `
      <div class="mortgage-results__hero">
        <div class="mortgage-results__hero-eyebrow">${__('Your Estimated Monthly Payment', textDomain)}</div>
        <div class="mortgage-results__hero-amount">${formatCurrencyHtml(monthlyDisplay)}</div>
        <div class="mortgage-results__hero-period">/ ${__('month', textDomain)}</div>
        ${monthlyDetailHtml}
      </div>
    `;

    const breakdownSectionHtml = `
      <div class="mortgage-results__breakdown">
        <div class="mortgage-results__breakdown-title">${__('PITI breakdown', textDomain)}</div>
        <div class="mortgage-results__breakdown-chart">
          <div class="mortgage-donut__labels-col mortgage-donut__labels-col--left">
            ${leftLabelsHtml}
          </div>
          <div class="mortgage-results__donut">
            ${generateDonutChart(chartSegments)}
          </div>
          <div class="mortgage-donut__labels-col mortgage-donut__labels-col--right">
            ${rightLabelsHtml}
          </div>
        </div>
        <div class="mortgage-results__legend-fallback">
          ${legendFallbackHtml}
        </div>
      </div>
    `;

    const metricsSectionHtml = `
      <div class="mortgage-results__metrics-grid">
        <div class="mortgage-results__metric-card">
          <div class="mortgage-results__metric-icon" aria-hidden="true">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
          </div>
          <div class="mortgage-results__metric-body">
            <span class="mortgage-results__metric-label">${__('Loan Amount', textDomain)}</span>
            <span class="mortgage-results__metric-value">${formatCurrencyHtml(loanAmount)}</span>
          </div>
        </div>
        <div class="mortgage-results__metric-card">
          <div class="mortgage-results__metric-icon" aria-hidden="true">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="1" y="6" width="22" height="12" rx="2"/><circle cx="12" cy="12" r="3"/></svg>
          </div>
          <div class="mortgage-results__metric-body">
            <span class="mortgage-results__metric-label">${__('Down Payment', textDomain)}</span>
            <span class="mortgage-results__metric-value">${formatCurrencyHtml(downPayment)}</span>
            <span class="mortgage-results__metric-sub">${downPaymentPercent}%</span>
          </div>
        </div>
        <div class="mortgage-results__metric-card">
          <div class="mortgage-results__metric-icon" aria-hidden="true">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><line x1="19" y1="5" x2="5" y2="19"/><circle cx="6.5" cy="6.5" r="2.5"/><circle cx="17.5" cy="17.5" r="2.5"/></svg>
          </div>
          <div class="mortgage-results__metric-body">
            <span class="mortgage-results__metric-label">${__('Interest Rate', textDomain)}</span>
            <span class="mortgage-results__metric-value">${interestRate}<span class="mortgage-results__metric-unit">%</span></span>
          </div>
        </div>
        <div class="mortgage-results__metric-card">
          <div class="mortgage-results__metric-icon" aria-hidden="true">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
          </div>
          <div class="mortgage-results__metric-body">
            <span class="mortgage-results__metric-label">${__('Loan Term', textDomain)}</span>
            <span class="mortgage-results__metric-value">${loanTerm} <span class="mortgage-results__metric-unit">${__('years', textDomain)}</span></span>
          </div>
        </div>
      </div>
    `;

    const amortizationSectionHtml = `
      <div class="mortgage-results__amort">
        <div class="mortgage-results__amort-header">${__('Principal vs. Interest Over Time', textDomain)}</div>
        <div class="mortgage-results__amort-chart">
          ${amortizationChart.html}
        </div>
        <div class="mortgage-results__amort-legend">
          <span class="mortgage-results__amort-legend-item">
            <span class="mortgage-results__amort-dot mortgage-results__amort-dot--principal"></span>
            ${__('Principal', textDomain)}
          </span>
          <span class="mortgage-results__amort-legend-item">
            <span class="mortgage-results__amort-dot mortgage-results__amort-dot--interest"></span>
            ${__('Interest', textDomain)}
          </span>
        </div>
      </div>
    `;

    const costSectionHtml = `
      <div class="mortgage-results__cost">
        <div class="mortgage-results__cost-card${!hasExtras ? ' mortgage-results__cost-card--solo' : ''}">
          <div class="mortgage-results__cost-title">${hasExtras ? __('Standard Repayment', textDomain) : __('Total Cost Summary', textDomain)}</div>
          <div class="mortgage-results__cost-rows">
            <div class="mortgage-results__cost-row">
              <span class="mortgage-results__cost-label">${__('Total Paid', textDomain)}</span>
              <span class="mortgage-results__cost-value">${formatCurrencyHtml(baseTotalPaid)}</span>
            </div>
            <div class="mortgage-results__cost-row">
              <span class="mortgage-results__cost-label">${__('Total Interest', textDomain)}</span>
              <span class="mortgage-results__cost-value">${formatCurrencyHtml(baseSchedule.totalInterest)}</span>
            </div>
            <div class="mortgage-results__cost-row">
              <span class="mortgage-results__cost-label">${__('Payoff Time', textDomain)}</span>
              <span class="mortgage-results__cost-value">${formatDuration(baseSchedule.months)}</span>
            </div>
          </div>
        </div>
        ${hasExtras ? `
          <div class="mortgage-results__cost-card mortgage-results__cost-card--extra">
            <div class="mortgage-results__cost-title">${__('With Extra Payments', textDomain)}</div>
            <div class="mortgage-results__cost-rows">
              <div class="mortgage-results__cost-row">
                <span class="mortgage-results__cost-label">${__('Total Paid', textDomain)}</span>
                <span class="mortgage-results__cost-value">${formatCurrencyHtml(extraTotalPaid)}</span>
              </div>
              <div class="mortgage-results__cost-row">
                <span class="mortgage-results__cost-label">${__('Total Interest', textDomain)}</span>
                <span class="mortgage-results__cost-value">${formatCurrencyHtml(extraSchedule.totalInterest)}</span>
              </div>
              <div class="mortgage-results__cost-row">
                <span class="mortgage-results__cost-label">${__('Payoff Time', textDomain)}</span>
                <span class="mortgage-results__cost-value">${formatDuration(extraSchedule.months)}</span>
              </div>
            </div>
          </div>
        ` : ''}
      </div>
    `;

    const savingsSectionHtml = hasExtras && (interestSaved > 0 || monthsSaved > 0) ? `
      <div class="mortgage-results__savings">
        <div class="mortgage-results__savings-title">${__('Your Extra Payment Savings', textDomain)}</div>
        <div class="mortgage-results__savings-grid">
          <div class="mortgage-results__savings-item">
            <div class="mortgage-results__savings-icon" aria-hidden="true">
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 0 1 0 4H8"/><path d="M12 18V6"/></svg>
            </div>
            <span class="mortgage-results__savings-amount">${formatCurrencyHtml(interestSaved)}</span>
            <span class="mortgage-results__savings-label">${__('interest saved', textDomain)}</span>
          </div>
          <div class="mortgage-results__savings-item">
            <div class="mortgage-results__savings-icon" aria-hidden="true">
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
            </div>
            <span class="mortgage-results__savings-amount">${formatDuration(monthsSaved)}</span>
            <span class="mortgage-results__savings-label">${__('earlier payoff', textDomain)}</span>
          </div>
        </div>
      </div>
    ` : '';

    const defaultResultsHtml = `
      ${heroSectionHtml}
      ${breakdownSectionHtml}
      ${metricsSectionHtml}
      ${amortizationSectionHtml}
      ${costSectionHtml}
      ${savingsSectionHtml}
    `;

    if (isMobileResultsViewport()) {
      const mobileTabs = [
        {
          id: 'summary',
          label: __('Summary', textDomain),
          content: `${heroSectionHtml}${breakdownSectionHtml}${metricsSectionHtml}`,
        },
        {
          id: 'chart',
          label: __('Chart', textDomain),
          content: amortizationSectionHtml,
        },
        {
          id: 'payoff',
          label: __('Payoff', textDomain),
          content: `${costSectionHtml}${savingsSectionHtml}`,
        },
      ];

      const mobileTabButtonsHtml = mobileTabs.map((tab, index) => {
        const isActive = index === 0;
        return `
          <button
            type="button"
            class="mortgage-results-tab${isActive ? ' mortgage-results-tab--active' : ''}"
            role="tab"
            id="mortgage-results-tab-${tab.id}"
            aria-selected="${isActive ? 'true' : 'false'}"
            aria-controls="mortgage-results-panel-${tab.id}"
            tabindex="${isActive ? '0' : '-1'}"
            data-tab="${tab.id}">
            ${tab.label}
          </button>
        `;
      }).join('');

      const mobileTabPanelsHtml = mobileTabs.map((tab, index) => {
        const isActive = index === 0;
        return `
          <div
            class="mortgage-results-panel${isActive ? ' mortgage-results-panel--active' : ''}"
            role="tabpanel"
            id="mortgage-results-panel-${tab.id}"
            aria-labelledby="mortgage-results-tab-${tab.id}"
            data-tab-panel="${tab.id}"${isActive ? '' : ' hidden'}>
            ${tab.content}
          </div>
          `;
      }).join('');

      resultContainer.innerHTML = `
        <div class="mortgage-results-tabs">
          <div class="mortgage-results-tabs__header" role="tablist" aria-label="${__('Result sections', textDomain)}">
            ${mobileTabButtonsHtml}
          </div>
          <div class="mortgage-results-tabs__body">
            ${mobileTabPanelsHtml}
          </div>
        </div>
      `;
      wireMobileResultsTabs(resultContainer);
    } else {
      resultContainer.innerHTML = defaultResultsHtml;
    }

    const amortizationChartEl = resultContainer.querySelector('.mortgage-results__amort-chart');
    if (amortizationChartEl) {
      resultContainer._mortgageChartCleanup = attachAmortizationChartHover(amortizationChartEl, amortizationChart.hoverData);
    }
    resultContainer.classList.add('has-result');
    scheduleLayoutRefresh(true);
  };

  // Step-level validation for the wizard
  const wizardStepOrder = hideAdvanced
    ? ['mortgage', 'extras']
    : ['mortgage', 'monthly-costs', 'extras'];

  const validateStep = ({ stepId }) => {
    const resolvedStepId = /^\d+$/.test(stepId)
      ? (wizardStepOrder[parseInt(stepId, 10)] || stepId)
      : stepId;

    if (resolvedStepId === 'mortgage') {
      let message = '';
      const homePrice = parseNumber(homePriceInput.value);
      if (!Number.isFinite(homePrice) || homePrice <= 0) {
        ValidationHelpers.markInvalid(homePriceInput);
        message = message || __('Please enter a valid home price.', textDomain);
      }

      const loanTerm = parseNumber(loanTermInput.value);
      if (!Number.isFinite(loanTerm) || loanTerm <= 0 || loanTerm > 50) {
        ValidationHelpers.markInvalid(loanTermInput);
        message = message || __('Please enter a valid loan term (1-50 years).', textDomain);
      }

      const interestRate = parseNumber(interestRateInput.value);
      if (!Number.isFinite(interestRate) || interestRate < 0 || interestRate > 25) {
        ValidationHelpers.markInvalid(interestRateInput);
        message = message || __('Please enter a valid interest rate (0-25%).', textDomain);
      }

      if (downPaymentInput.value) {
        const dpVal = parseNumber(downPaymentInput.value);
        if (!Number.isFinite(dpVal) || dpVal < 0) {
          ValidationHelpers.markInvalid(downPaymentInput, { allowEmpty: true, validator: () => { const r = downPaymentInput.value; if (r === '') return true; const v = parseNumber(r); return Number.isFinite(v) && v >= 0; } });
          message = message || __('Please enter a valid down payment.', textDomain);
        }
        if (dpVal >= homePrice) {
          ValidationHelpers.markInvalid(downPaymentInput, { allowEmpty: true, validator: () => { const p = parseNumber(homePriceInput.value); const r = downPaymentInput.value; if (r === '') return true; const v = parseNumber(r); return Number.isFinite(v) && Number.isFinite(p) && v >= 0 && v < p; } });
          message = message || __('Down payment cannot be greater than or equal to home price.', textDomain);
        }
      }

      if (downPaymentPercentInput.value) {
        const pv = parseNumber(downPaymentPercentInput.value);
        if (!Number.isFinite(pv) || pv < 0 || pv > 100) {
          ValidationHelpers.markInvalid(downPaymentPercentInput, { allowEmpty: true, validator: () => { const r = downPaymentPercentInput.value; if (r === '') return true; const v = parseNumber(r); return Number.isFinite(v) && v >= 0 && v <= 100; } });
          message = message || __('Please enter a valid down payment percentage.', textDomain);
        }
      }

      return message ? message : true;
    }

    if (resolvedStepId === 'monthly-costs') {
      let message = '';
      const ptEstimate = getEscrowEstimateState('property-tax');
      if (!ptEstimate.valid) {
        ValidationHelpers.markInvalid(propertyTaxInput, { allowEmpty: true, validator: () => getEscrowEstimateState('property-tax').valid });
        message = message || getEscrowValidationMessage('property-tax', ptEstimate.reason);
      }
      const hiEstimate = getEscrowEstimateState('home-insurance');
      if (!hiEstimate.valid) {
        ValidationHelpers.markInvalid(homeInsuranceInput, { allowEmpty: true, validator: () => getEscrowEstimateState('home-insurance').valid });
        message = message || getEscrowValidationMessage('home-insurance', hiEstimate.reason);
      }
      if (!validateOptionalNumber(hoaFeesInput)) {
        ValidationHelpers.markInvalid(hoaFeesInput, { allowEmpty: true, validator: () => validateOptionalNumber(hoaFeesInput) });
        message = message || __('Please enter a valid HOA fee.', textDomain);
      }
      if (!validateOptionalNumber(pmiInput)) {
        ValidationHelpers.markInvalid(pmiInput, { allowEmpty: true, validator: () => validateOptionalNumber(pmiInput) });
        message = message || __('Please enter a valid PMI amount.', textDomain);
      }
      return message ? message : true;
    }

    if (resolvedStepId === 'extras') {
      let message = '';
      if (!validateOptionalNumber(extraMonthlyInput)) {
        ValidationHelpers.markInvalid(extraMonthlyInput, { allowEmpty: true, validator: () => validateOptionalNumber(extraMonthlyInput) });
        message = message || __('Please enter a valid extra monthly payment.', textDomain);
      }
      if (!validateOptionalNumber(extraYearlyInput)) {
        setExtraAdvancedOpen(true);
        ValidationHelpers.markInvalid(extraYearlyInput, { allowEmpty: true, validator: () => validateOptionalNumber(extraYearlyInput) });
        message = message || __('Please enter a valid extra yearly payment.', textDomain);
      }
      if (!validateOptionalNumber(extraOneTimeInput)) {
        setExtraAdvancedOpen(true);
        ValidationHelpers.markInvalid(extraOneTimeInput, { allowEmpty: true, validator: () => validateOptionalNumber(extraOneTimeInput) });
        message = message || __('Please enter a valid one-time extra payment.', textDomain);
      }
      const extraOneTimeValue = parseOptionalNumber(extraOneTimeInput?.value);
      if (extraOneTimeValue > 0 && !extraOneTimeDateInput?.value) {
        setExtraAdvancedOpen(true);
        ValidationHelpers.markInvalid(extraOneTimeDateInput, {
          validator: () => { const a = parseOptionalNumber(extraOneTimeInput?.value); if (a <= 0) return true; if (!extraOneTimeDateInput?.value) return false; const p = new Date(extraOneTimeDateInput.value); return !Number.isNaN(p.getTime()); },
        });
        message = message || __('Please select a one-time payment date.', textDomain);
      }
      return message ? message : true;
    }

    return true;
  };

  // Initialize wizard skeleton
  wizardRoot = container.querySelector('.vareoncalc-wizard');

  const wizard = initWizardSkeleton(wizardRoot, {
    initialStep: 0,
    validateStep,
  });

  // Hook: run calculate() whenever the wizard enters the results state.
  if (wizard && wizardRoot) {
    const observer = new MutationObserver((mutations) => {
      for (const mutation of mutations) {
        if (mutation.type === 'attributes' && mutation.attributeName === 'data-wizard-state') {
          if (wizardRoot.dataset.wizardState === 'results') {
            calculate();
          }
        }
      }
    });
    observer.observe(wizardRoot, { attributes: true, attributeFilter: ['data-wizard-state'] });

    const restartBtn = container.querySelector('[data-wizard-restart]');
    if (restartBtn) {
      restartBtn.addEventListener('click', () => {
        if (typeof resultContainer._mortgageChartCleanup === 'function') {
          resultContainer._mortgageChartCleanup();
          resultContainer._mortgageChartCleanup = null;
        }
        resultContainer.innerHTML = `
          <div class="mortgage-studio__empty">
            <div class="mortgage-studio__empty-icon">&#128202;</div>
            <div class="mortgage-studio__empty-text">${__('Calculating your payment breakdown...', textDomain)}</div>
          </div>
        `;
        resultContainer.classList.remove('has-result');
        scheduleLayoutRefresh(true);
      });
    }
  }
}
