import './style.css';

/**
 * Handles feature-row collapse toggling and billing/mobile interactions.
 */
const initMulticolumnPricingTable = (widget) => {
  if (!(widget instanceof HTMLElement)) {
    return;
  }

  if (typeof widget.__calioPricingDestroy === 'function') {
    widget.__calioPricingDestroy();
  }

  const cleanups = [];
  const on = (element, eventName, handler, options) => {
    if (!element) {
      return;
    }
    element.addEventListener(eventName, handler, options);
    cleanups.push(() => element.removeEventListener(eventName, handler, options));
  };

  const toggle = widget.querySelector('.calio-mc-pricing-toggle');
  const rows = Array.from(
    widget.querySelectorAll(
      '.calio-mc-pricing-row[data-collapsible="yes"], .calio-mc-pricing-group-row[data-collapsible="yes"]',
    ),
  );
  const billingSwitcher = widget.querySelector('.calio-mc-pricing-billing-switcher');
  const monthlyPrices = Array.from(widget.querySelectorAll('[data-billing="monthly"]'));
  const yearlyPrices = Array.from(widget.querySelectorAll('[data-billing="yearly"]'));
  const cycleLabels = Array.from(widget.querySelectorAll('.calio-mc-pricing-cycle-label'));
  const mobileFocus = widget.querySelector('.calio-mc-pricing-mobile-focus');
  const mobileChips = Array.from(widget.querySelectorAll('.calio-mc-pricing-mobile-chip'));
  const mobilePlans = Array.from(widget.querySelectorAll('.calio-mc-pricing-plan[data-plan-index]'));
  const mobileValues = Array.from(widget.querySelectorAll('.calio-mc-pricing-row-value[data-plan-index]'));
  let switchAnimationTimeout = null;
  let knobAnimationFrame = null;

  if (billingSwitcher && monthlyPrices.length && yearlyPrices.length) {
    let currentCycle = widget.dataset.billingDefault === 'yearly' ? 'yearly' : 'monthly';
    const billingKnob = billingSwitcher.querySelector('.calio-mc-pricing-billing-knob');

    const syncKnobPosition = () => {
      if (!(billingKnob instanceof HTMLElement)) {
        return;
      }

      const activeLabel = billingSwitcher.querySelector(
        `.calio-mc-pricing-cycle-label[data-cycle="${currentCycle}"]`,
      );

      if (!(activeLabel instanceof HTMLElement)) {
        return;
      }

      const switcherRect = billingSwitcher.getBoundingClientRect();
      const labelRect = activeLabel.getBoundingClientRect();
      const knobX = Math.max(0, Math.round(labelRect.left - switcherRect.left));
      const knobWidth = Math.max(56, Math.round(labelRect.width));

      billingSwitcher.style.setProperty('--calio-mc-knob-x', `${knobX}px`);
      billingSwitcher.style.setProperty('--calio-mc-knob-width', `${knobWidth}px`);
    };

    const queueKnobPositionSync = () => {
      if (knobAnimationFrame) {
        window.cancelAnimationFrame(knobAnimationFrame);
      }
      knobAnimationFrame = window.requestAnimationFrame(() => {
        knobAnimationFrame = null;
        syncKnobPosition();
      });
    };

    const setPricesState = (prices, isActive) => {
      prices.forEach((price) => {
        if (!(price instanceof HTMLElement)) {
          return;
        }
        price.hidden = false;
        price.classList.toggle('is-active', isActive);
        price.setAttribute('aria-hidden', isActive ? 'false' : 'true');
      });
    };

    const syncBilling = () => {
      const isYearly = currentCycle === 'yearly';
      widget.dataset.billing = currentCycle;
      billingSwitcher.setAttribute('aria-pressed', isYearly ? 'true' : 'false');

      setPricesState(monthlyPrices, !isYearly);
      setPricesState(yearlyPrices, isYearly);

      cycleLabels.forEach((label) => {
        if (!(label instanceof HTMLElement)) {
          return;
        }
        label.classList.toggle('is-active', label.dataset.cycle === currentCycle);
      });

      queueKnobPositionSync();
    };

    syncBilling();
    on(window, 'resize', queueKnobPositionSync);

    on(billingSwitcher, 'click', () => {
      billingSwitcher.classList.remove('is-switching');
      // Reflow restarts the spring class so rapid taps still animate.
      // eslint-disable-next-line no-unused-expressions
      billingSwitcher.offsetWidth;
      billingSwitcher.classList.add('is-switching');
      if (switchAnimationTimeout) {
        window.clearTimeout(switchAnimationTimeout);
      }
      switchAnimationTimeout = window.setTimeout(() => {
        billingSwitcher.classList.remove('is-switching');
      }, 360);

      currentCycle = currentCycle === 'monthly' ? 'yearly' : 'monthly';
      syncBilling();
    });
  }

  if (mobileFocus instanceof HTMLElement && mobileChips.length) {
    let activePlan = mobileFocus.dataset.mobileDefault || mobileChips[0].dataset.planIndex || '0';

    const syncMobileFocus = () => {
      widget.dataset.mobilePlan = activePlan;

      mobileChips.forEach((chip) => {
        if (!(chip instanceof HTMLElement)) {
          return;
        }
        const isActive = chip.dataset.planIndex === activePlan;
        chip.classList.toggle('is-active', isActive);
        chip.setAttribute('aria-pressed', isActive ? 'true' : 'false');
      });

      mobilePlans.forEach((plan) => {
        if (!(plan instanceof HTMLElement)) {
          return;
        }
        plan.dataset.mobileActive = plan.dataset.planIndex === activePlan ? 'true' : 'false';
      });

      mobileValues.forEach((value) => {
        if (!(value instanceof HTMLElement)) {
          return;
        }
        value.dataset.mobileActive = value.dataset.planIndex === activePlan ? 'true' : 'false';
      });
    };

    syncMobileFocus();

    mobileChips.forEach((chip) => {
      on(chip, 'click', () => {
        activePlan = chip.dataset.planIndex || activePlan;
        syncMobileFocus();
      });
    });
  }

  if (toggle instanceof HTMLElement && rows.length > 0) {
    let expanded = false;

    on(toggle, 'click', () => {
      expanded = !expanded;

      rows.forEach((row) => {
        if (row instanceof HTMLElement) {
          row.hidden = !expanded;
        }
      });

      toggle.textContent = expanded
        ? toggle.dataset.lessText || ''
        : toggle.dataset.moreText || '';
    });
  }

  widget.__calioPricingDestroy = () => {
    if (switchAnimationTimeout) {
      window.clearTimeout(switchAnimationTimeout);
      switchAnimationTimeout = null;
    }
    if (knobAnimationFrame) {
      window.cancelAnimationFrame(knobAnimationFrame);
      knobAnimationFrame = null;
    }
    cleanups.forEach((cleanup) => cleanup());
    widget.__calioPricingDestroy = null;
  };
};

const boot = (scope = document) => {
  if (!(scope instanceof HTMLElement || scope instanceof Document)) {
    return;
  }

  scope.querySelectorAll('.calio-mc-pricing-table').forEach((widget) => {
    initMulticolumnPricingTable(widget);
  });
};

document.addEventListener('DOMContentLoaded', () => {
  boot(document);
});

let calioPricingTableHookBound = false;
const bindElementorPricingTable = () => {
  if (calioPricingTableHookBound) {
    return true;
  }

  if (!window.elementorFrontend?.hooks) {
    return false;
  }

  window.elementorFrontend.hooks.addAction(
    'frontend/element_ready/calio-multicolumn-pricing-table.default',
    ($scope) => {
      const root = $scope?.[0] || document;
      boot(root);
    },
  );

  calioPricingTableHookBound = true;
  return true;
};

window.addEventListener('elementor/frontend/init', bindElementorPricingTable);
if (!bindElementorPricingTable()) {
  let attempts = 0;
  const timer = window.setInterval(() => {
    attempts += 1;
    if (bindElementorPricingTable() || attempts >= 40) {
      window.clearInterval(timer);
    }
  }, 250);
}
