// Pricing defaults and JSON loading live in quote-pricing.js.
// This file intentionally consumes the pricing globals exposed there
// so Phase 1 can stay low-risk and preserve the current runtime API.

// Rendering helpers and nudge state live in quote-render.js.
// Persistence, export/print, theme, and mobile sync live in dedicated
// modules so this file can stay focused on quote calculation orchestration.

// --- CALC ---
// ── calcQuote() ─────────────────────────────────────────────────
// Compatibility wrapper around the pure Phase 2 quote engine.
// Reads live form state from the DOM, then delegates pricing math to
// calculateQuote(state, pricing) without changing the rest of the app.
function calcQuote() {
  return calculateQuote(readFormState(), getPricingConfig());
}

// --- MAIN UPDATE ---
// ── update() ─────────────────────────────────────────────────────
// Master DOM update function. Called on every input change.
// Sequence: calcQuote → update all displays → renderNudge →
//   updateSavings → updateVsComparison → updateSectionSummaries
// Also wrapped by the mobile IIFE below to sync _m elements.
// Do not call renderNudge() directly from other functions;
//    always go through update() to keep _m panel in sync.
function update() {
  const q = calcQuote();
  const pricing = getPricingConfig();
  const bestM365Rate = Math.max(pricing.RATE_M365_M2M || 0, pricing.RATE_M365 || 0);
  const m365BundleSavings = Math.max(0, bestM365Rate - pricing.RATE_BYOL);
  const render = window.SVSQuoteRender;

  // ── Onboarding fee logic ──
  // m2m: auto = 50% MRR, manual override allowed, waive toggle available
  // 12-month: auto = 50% off onboarding (25% of MRR), manual override allowed
  // 24-month: complimentary (fully waived), input disabled
  const waivedEl = document.getElementById('onboardingWaived');
  const feeEl    = document.getElementById('oneTimeFee');
  const fullOnboarding = Math.round(q.MRR / 2);

  if (waivedEl && q.contractTerm === '24mo') {
    // 24-month: fully complimentary
    waivedEl.checked = true;
    waivedEl.disabled = true;
    waivedEl.dataset.autoWaived = '1';
    // Preserve any manual override so it survives the round-trip back to m2m/12mo
    if (feeEl && feeEl.dataset.manual) {
      feeEl.dataset.manualValue = feeEl.value;
      delete feeEl.dataset.manual;
    }
  } else if (waivedEl && q.contractTerm === '12mo') {
    // 12-month: 50% off onboarding, not waived — clear any auto-waive state
    waivedEl.disabled = false;
    if (waivedEl.dataset.autoWaived) {
      waivedEl.checked = false;
      delete waivedEl.dataset.autoWaived;
    }
    // Restore manual override if user had one before switching to 24mo
    if (feeEl && !feeEl.dataset.manual && feeEl.dataset.manualValue) {
      feeEl.dataset.manual = '1';
      feeEl.value = feeEl.dataset.manualValue;
      delete feeEl.dataset.manualValue;
    }
  } else if (waivedEl) {
    // m2m: full manual control
    waivedEl.disabled = false;
    if (waivedEl.dataset.autoWaived) {
      waivedEl.checked = false;
      delete waivedEl.dataset.autoWaived;
    }
    // Restore manual override if user had one before switching to 24mo
    if (feeEl && !feeEl.dataset.manual && feeEl.dataset.manualValue) {
      feeEl.dataset.manual = '1';
      feeEl.value = feeEl.dataset.manualValue;
      delete feeEl.dataset.manualValue;
    }
  }

  const waived = waivedEl?.checked || false;
  let oneTimeFee;
  if (waived) {
    oneTimeFee = 0;
    if (feeEl) { feeEl.value = ''; feeEl.disabled = true; feeEl.placeholder = 'Complimentary'; }
  } else if (q.contractTerm === '12mo') {
    // 12-month: 50% off the standard onboarding fee
    if (feeEl) { feeEl.disabled = false; feeEl.placeholder = '50% off'; }
    if (feeEl && !feeEl.dataset.manual) {
      oneTimeFee = Math.round(fullOnboarding / 2);
      feeEl.value = oneTimeFee > 0 ? oneTimeFee : '';
    } else {
      oneTimeFee = parseFloat(feeEl?.value) || 0;
    }
  } else {
    // m2m: standard auto-calc
    if (feeEl) { feeEl.disabled = false; feeEl.placeholder = 'auto'; }
    if (feeEl && !feeEl.dataset.manual) {
      oneTimeFee = fullOnboarding;
      feeEl.value = oneTimeFee > 0 ? oneTimeFee : '';
    } else {
      oneTimeFee = parseFloat(feeEl?.value) || 0;
    }
  }
  q.oneTimeFee = oneTimeFee;
  const renderOptions = {
    m365BundleSavings,
    oneTimeFee,
    onboardingWaived: waived,
    onboardingWouldBe: fullOnboarding,
    onboardingHalfOff: q.contractTerm === '12mo' && !waived
  };

  render.renderQuoteUi(q, renderOptions);
  render.renderSidebar(q, renderOptions);
  render.setNudges(render.buildNudges(q, renderOptions));

  renderNudge();
  updateSavings(q);
  updateVsComparison(q);
  updateSectionSummaries(q);

  // Active section accent
  ['sec-02', 'sec-03', 'sec-01', 'sec-04', 'sec-05', 'sec-06'].forEach(function(secId) {
    var el = document.getElementById(secId);
    if (!el) return;
    var input = el.querySelector('.num-input');
    var isActive = input ? parseInt(input.value) > 0 : false;
    if (secId === 'sec-01') isActive = q.mrr > 0;
    el.classList.toggle('sec-active', isActive);
  });

  debouncedSave();
}

// ── onWaiveToggle() ──────────────────────────────────────────────
// Called from onchange on #onboardingWaived checkbox.
// Clears the manual override flag on the fee input so auto-calc resumes,
// then runs update(). Extracted from inline HTML attribute for clarity.
function onWaiveToggle() {
  const feeInput = document.getElementById('oneTimeFee');
  if (feeInput) feeInput.removeAttribute('data-manual');
  update();
}

// ── toggleSection(id) ────────────────────────────────────────────
// Collapses/expands a numbered section card.
// Adds/removes .sec-open on the section element.
// .sec-open → chevron rotates 180deg (CSS), body shown (JS display).
// Calls updateSectionSummaries() to show/hide summary badges.
// Map: section ID → collapsible IDs that should auto-expand when section opens
const _sectionCollapsibles = {};

function finishSectionAnimation(body, isOpen) {
  body.style.transition = '';
  body.style.overflow = '';
  body.style.height = '';
  body.style.opacity = '';
  body.style.display = isOpen ? '' : 'none';
}

function animateSectionBody(body, open) {
  if (!body) return;

  if (body._sectionAnimationCleanup) {
    body._sectionAnimationCleanup();
    body._sectionAnimationCleanup = null;
  }

  body.style.overflow = 'hidden';
  body.style.transition = 'height 0.34s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.22s ease';

  if (open) {
    body.style.display = '';
    body.style.height = '0px';
    body.style.opacity = '0';
    body.getBoundingClientRect();

    const targetHeight = body.scrollHeight;
    requestAnimationFrame(() => {
      body.style.height = targetHeight + 'px';
      body.style.opacity = '1';
    });
  } else {
    const startHeight = body.scrollHeight || body.offsetHeight;
    body.style.display = '';
    body.style.height = startHeight + 'px';
    body.style.opacity = '1';
    body.getBoundingClientRect();

    requestAnimationFrame(() => {
      body.style.height = '0px';
      body.style.opacity = '0';
    });
  }

  const onEnd = (event) => {
    if (event.target !== body || event.propertyName !== 'height') return;
    body.removeEventListener('transitionend', onEnd);
    body._sectionAnimationCleanup = null;
    finishSectionAnimation(body, open);
  };

  body._sectionAnimationCleanup = () => {
    body.removeEventListener('transitionend', onEnd);
    finishSectionAnimation(body, open);
  };

  body.addEventListener('transitionend', onEnd);
}

function toggleSection(id) {
  const section = document.getElementById(id);
  const body    = document.getElementById(id + '-body');
  if (!section || !body) return;
  const isOpen = section.classList.toggle('sec-open');
  // Sync aria-expanded on the section-toggle header
  const header = section.querySelector('.section-toggle');
  if (header) header.setAttribute('aria-expanded', String(isOpen));
  animateSectionBody(body, isOpen);
  // Auto-expand inner collapsibles when section opens
  if (isOpen && _sectionCollapsibles[id]) {
    _sectionCollapsibles[id].forEach(cid => {
      const cBody = document.getElementById(cid);
      const cIcon = document.getElementById(cid + '-icon');
      const cPreview = document.getElementById(cid + '-preview');
      if (cBody && !cBody.classList.contains('open')) {
        cBody.classList.add('open');
        if (cIcon) cIcon.classList.add('open');
        if (cPreview) cPreview.style.display = 'none';
      }
    });
  }
  updateSectionSummaries(calcQuote());
  updateToggleAllBtn();
}

// ── toggleAllSections() / updateToggleAllBtn() ────────────────────
// Collapse all if any are open; expand all if all are closed.
// Button label reflects current state.
const _allSecIds = ['sec-02','sec-03','sec-01','sec-04','sec-05','sec-06'];
function toggleAllSections() {
  const anyOpen = _allSecIds.some(id => document.getElementById(id)?.classList.contains('sec-open'));
  _allSecIds.forEach(id => {
    const section = document.getElementById(id);
    const body    = document.getElementById(id + '-body');
    if (!section || !body) return;
    if (anyOpen) {
      section.classList.remove('sec-open');
      animateSectionBody(body, false);
    }
    else {
      section.classList.add('sec-open');
      animateSectionBody(body, true);
      // Auto-expand inner collapsibles
      if (_sectionCollapsibles[id]) {
        _sectionCollapsibles[id].forEach(cid => {
          const cBody = document.getElementById(cid);
          const cIcon = document.getElementById(cid + '-icon');
          const cPreview = document.getElementById(cid + '-preview');
          if (cBody && !cBody.classList.contains('open')) {
            cBody.classList.add('open');
            if (cIcon) cIcon.classList.add('open');
            if (cPreview) cPreview.style.display = 'none';
          }
        });
      }
    }
  });
  updateSectionSummaries(calcQuote());
  updateToggleAllBtn();
}
function updateToggleAllBtn() {
  const anyOpen = _allSecIds.some(id => document.getElementById(id)?.classList.contains('sec-open'));
  const btn = document.getElementById('toggleAllBtn');
  if (!btn) return;
  const collapseSpan = btn.querySelector('.toggle-all-collapse-icon');
  const expandSpan   = btn.querySelector('.toggle-all-expand-icon');
  const textSpan     = btn.querySelector('.toggle-all-label');
  if (collapseSpan) collapseSpan.style.display = anyOpen ? '' : 'none';
  if (expandSpan)   expandSpan.style.display   = anyOpen ? 'none' : '';
  if (textSpan)     textSpan.textContent        = anyOpen ? 'Collapse All' : 'Expand All';
}

// ── toggleCollapsible(id) ─────────────────────────────────────────
// Collapses/expands inner content panels (What's Included, Add-Ons).
// Separate from section-level toggle. Toggles .open on .collapsible-body.
// Also toggles preview pills (shown when collapsed, hidden when open).
function toggleCollapsible(id) {
  const body = document.getElementById(id);
  const icon = document.getElementById(id + '-icon');
  const preview = document.getElementById(id + '-preview');
  if (!body) return;
  const open = body.classList.toggle('open');
  if (icon) icon.classList.toggle('open', open);
  if (preview) preview.style.display = open ? 'none' : 'flex';
  // Sync aria-expanded on the collapsible header that controls this body
  const header = body.previousElementSibling;
  if (header && header.classList.contains('collapsible-header')) {
    header.setAttribute('aria-expanded', String(open));
  }
}

// ── toggleAddon(checkId, rowId) ─────────────────────────────────
// Flips the hidden checkbox + toggles .selected on the visible row.
// Called via onclick on the <label class="addon-row"> element.
// The label's onclick fires BEFORE the native checkbox change,
//    so we manually invert cb.checked here instead of reading it.
function toggleAddon(checkId, rowId) {
  const cb  = document.getElementById(checkId);
  const row = document.getElementById(rowId);
  cb.checked = !cb.checked;
  if (row) row.classList.toggle('selected', cb.checked);
}

// ── activateTier(tier) ───────────────────────────────────────────
// Sets the active VoIP tier pill (basic/standard/premium).
// Adds .active class to matching .tier-seg, removes from others.
// Called from onclick on tier labels (alongside update()).
function activateTier(tier) {
  const el = document.getElementById('voip' + tier.charAt(0).toUpperCase() + tier.slice(1));
  if (el) { el.checked = true; update(); }
}

// Rendering helpers for summaries, savings, nudges, and the VS comparison
// now live in quote-render.js. They stay available globally so the existing
// HTML shell and inline handlers do not change.

// ── HELPERS ──────────────────────────────────────────────────────
// stepInput — increment/decrement a num-input by delta, respects min
function stepInput(id, delta) {
  const el = document.getElementById(id);
  if (!el) return;
  const min = parseInt(el.min) ?? 0;
  el.value = Math.max(min, (parseInt(el.value) || 0) + delta);
  // Pulse feedback
  el.classList.remove('pulse');
  void el.offsetWidth;
  el.classList.add('pulse');
  update();
}

// Persistence and reset behavior now live in quote-persistence.js and stay
// global so update(), initQuote(), and inline HTML handlers continue to work.

// Export/print and theme management live in their own Phase 4 modules and
// remain available globally for the existing buttons and init flow.

// ── initQuote() ──────────────────────────────────────────────────
// Entry point. Sets quote ref (SVS-YYYYMMDD-XXXX) and date,
// restores saved state, then calls update() for initial render.
// Called once at bottom of script.
function syncAddonPriceLabels() {
  document.querySelectorAll('.addon-price[data-price-key]').forEach(function(el) {
    var key = el.dataset.priceKey;
    var unit = el.dataset.priceUnit || 'unit';
    var val = window[key];
    if (typeof val === 'number') {
      el.textContent = '+$' + val + '/' + unit + '/mo';
    }
  });
}

async function initQuote() {
  await loadPricing();
  syncAddonPriceLabels();
  const now = new Date();
  const months = ['JANUARY','FEBRUARY','MARCH','APRIL','MAY','JUNE','JULY','AUGUST','SEPTEMBER','OCTOBER','NOVEMBER','DECEMBER'];
  const year  = now.getFullYear();
  const month = months[now.getMonth()];
  const quoteRef = getOrCreateQuoteRef(now);
  const quoteRefEl = document.getElementById('quoteRef');
  if (quoteRefEl) quoteRefEl.textContent = quoteRef;
  const headerDateEl = document.getElementById('headerDate');
  if (headerDateEl) headerDateEl.textContent = `${month} ${year}`;
  restoreState();
  update();
  updateToggleAllBtn();
}

// ── Keyboard Shortcuts ───────────────────────────────────────────
// Ctrl+P  → Print invoice (overrides browser print)
// Ctrl+E  → Export JSON
// Ctrl+R  → Reset quote (opens confirm modal)
// Escape  → Close sidebar focus / mobile panel (handled in mobile-sync.js)
document.addEventListener('keydown', function(e) {
  // Skip when user is typing in an input/textarea
  var tag = (document.activeElement || {}).tagName;
  if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;

  if (e.ctrlKey && !e.shiftKey && !e.altKey) {
    if (e.key === 'p' || e.key === 'P') {
      e.preventDefault();
      if (typeof printInvoice === 'function') printInvoice();
    } else if (e.key === 'e' || e.key === 'E') {
      e.preventDefault();
      if (typeof exportQuoteJSON === 'function') exportQuoteJSON();
    } else if (e.key === 'r' || e.key === 'R') {
      e.preventDefault();
      if (typeof openResetConfirm === 'function') openResetConfirm();
    }
  }
});

initTheme();
initQuote();

// Mobile sidebar cloning and sync now live in mobile-sync.js, which loads
// after this file so it can wrap the finalized global update() function.
