(function (wp) {
  if (!wp || !wp.blocks || !wp.element || !wp.i18n) {
    return;
  }

  const INITIAL_EDITOR_DATA = Object.assign({}, window.VAREONCALC_EDITOR || {});

  const { registerBlockType } = wp.blocks;
  const blockEditor = wp.blockEditor || wp.editor || {};
  const { InspectorControls, BlockControls, useBlockProps } = blockEditor;
  const {
    PanelBody,
    ToggleControl,
    Modal,
    Button,
    Dropdown,
    ToolbarGroup,
    ToolbarButton,
    BaseControl,
    TextControl,
    Spinner
  } = wp.components;
  const { createElement: el, Fragment, useEffect, useMemo, useRef, useState } = wp.element;
  const { __ } = wp.i18n;

  const BLOCK_NAME = 'vareoncalc/block';
  const TEXT_DOMAIN = 'vareon-calculator-suite-lite';
  const BASE_WIDTH_PRESETS = ['100%', '50%', '520px'];
  const MIN_RECOMMENDED_PREVIEW_WIDTH_PX = 410;
  const EDITOR_PREVIEW_LOADING_MIN_HEIGHT_PX = 220;
  const RECOMMENDED_WIDE_CARD_WIDTH_PX = 760;
  const DEFAULT_MIN_BLOCK_WIDTH = '300px';
  const DEFAULT_UNALIGNED_BLOCK_MAX_WIDTH = '645px';
  const DEFAULT_WIDE_BLOCK_MAX_WIDTH = '1340px';
  const DEFAULT_ALIGNED_BLOCK_WIDTH = '700px';

  function getMaxWidthForAlign(align) {
    if (align === 'wide' || align === 'full') {
      return parseFloat(DEFAULT_WIDE_BLOCK_MAX_WIDTH);
    }
    if (align === 'left' || align === 'center' || align === 'right') {
      return parseFloat(DEFAULT_ALIGNED_BLOCK_WIDTH);
    }
    return parseFloat(DEFAULT_UNALIGNED_BLOCK_MAX_WIDTH);
  }

  function getDefaultWidthForAlign(align) {
    if (align === 'wide' || align === 'full') {
      return DEFAULT_WIDE_BLOCK_MAX_WIDTH;
    }
    if (align === 'left' || align === 'center' || align === 'right') {
      return DEFAULT_ALIGNED_BLOCK_WIDTH;
    }
    return '100%';
  }

  function isDirectionalAlignValue(align) {
    return align === 'left' || align === 'center' || align === 'right';
  }

  function getWidthUpperGuidanceForAlign(align) {
    if (align === 'wide' || align === 'full') {
      return {
        warningThresholdPx: RECOMMENDED_WIDE_CARD_WIDTH_PX,
        helpMessage: __('Wide/full alignment allows larger widths. Very large widths can add extra side spacing.', TEXT_DOMAIN),
        warningMessage: __('Very large widths in wide/full alignment can add extra side spacing.', TEXT_DOMAIN)
      };
    }

    if (isDirectionalAlignValue(align)) {
      return {
        warningThresholdPx: parseFloat(DEFAULT_ALIGNED_BLOCK_WIDTH),
        helpMessage: __('For left/center/right alignment, widths above 700px are clamped to 700px.', TEXT_DOMAIN),
        warningMessage: __('For left/center/right alignment, widths above 700px are clamped to 700px.', TEXT_DOMAIN)
      };
    }

    return {
      warningThresholdPx: parseFloat(DEFAULT_UNALIGNED_BLOCK_MAX_WIDTH),
      helpMessage: __('For default alignment, widths above 645px are clamped to 645px.', TEXT_DOMAIN),
      warningMessage: __('For default alignment, widths above 645px are clamped to 645px.', TEXT_DOMAIN)
    };
  }

  function formatCssNumber(value) {
    const rounded = Math.round(value * 100) / 100;
    return Number.isInteger(rounded) ? String(Math.trunc(rounded)) : String(rounded);
  }

  function parsePixelWidth(widthValue) {
    const match = String(widthValue || '').trim().match(/^(\d+(?:\.\d+)?)px$/i);
    if (!match) {
      return null;
    }
    const parsed = parseFloat(match[1]);
    return Number.isFinite(parsed) ? parsed : null;
  }

  function getWidthPresetsForAlign(align) {
    if (align === 'wide' || align === 'full') {
      return ['100%', '50%', '700px', '900px', '1200px'];
    }
    if (isDirectionalAlignValue(align)) {
      return BASE_WIDTH_PRESETS.concat([DEFAULT_ALIGNED_BLOCK_WIDTH]);
    }
    return BASE_WIDTH_PRESETS.concat([DEFAULT_UNALIGNED_BLOCK_MAX_WIDTH]);
  }

  function getWidthExamplesForAlign(align) {
    if (align === 'wide' || align === 'full') {
      return ['100%', '50%', '900px'];
    }
    if (isDirectionalAlignValue(align)) {
      return ['100%', '50%', DEFAULT_ALIGNED_BLOCK_WIDTH];
    }
    return ['100%', '50%', DEFAULT_UNALIGNED_BLOCK_MAX_WIDTH];
  }

  function normalizeWidthForStorage(widthValue, align) {
    const maxWidthPx = getMaxWidthForAlign(align);
    const minWidthPx = parseFloat(DEFAULT_MIN_BLOCK_WIDTH);
    const fallbackWidth = getDefaultWidthForAlign(align);
    let raw = String(widthValue || '').trim();

    if (!raw) {
      raw = fallbackWidth;
    }

    if (isDirectionalAlignValue(align) && raw === '100%') {
      raw = DEFAULT_ALIGNED_BLOCK_WIDTH;
    }

    const percentMatch = raw.match(/^(\d+(?:\.\d+)?)%$/i);
    if (percentMatch) {
      const percent = Math.min(100, Math.max(0, parseFloat(percentMatch[1])));
      return `${formatCssNumber(percent)}%`;
    }

    const pxMatch = raw.match(/^(\d+(?:\.\d+)?)px$/i);
    if (pxMatch) {
      const parsedPx = parseFloat(pxMatch[1]);
      const clampedPx = Math.min(maxWidthPx, Math.max(minWidthPx, parsedPx));
      return `${formatCssNumber(clampedPx)}px`;
    }

    return fallbackWidth;
  }

  function getWidthInputValidation(widthValue, align) {
    const raw = String(widthValue || '').trim();
    const maxWidthPx = getMaxWidthForAlign(align);

    if (!raw) {
      return {
        isValid: true,
        message: __('Leave empty to use the default width for this alignment.', TEXT_DOMAIN)
      };
    }

    const percentMatch = raw.match(/^(\d+(?:\.\d+)?)%$/i);
    if (percentMatch) {
      const percent = parseFloat(percentMatch[1]);
      if (percent < 0 || percent > 100) {
        return {
          isValid: false,
          message: __('Percent width must be between 0% and 100%.', TEXT_DOMAIN)
        };
      }
      return {
        isValid: true,
        message: __('Valid width. The value may be clamped by the current alignment limits.', TEXT_DOMAIN)
      };
    }

    const pxMatch = raw.match(/^(\d+(?:\.\d+)?)px$/i);
    if (pxMatch) {
      const px = parseFloat(pxMatch[1]);
      if (px <= 0) {
        return {
          isValid: false,
          message: __('Pixel width must be greater than 0px.', TEXT_DOMAIN)
        };
      }
      if (px > maxWidthPx) {
        return {
          isValid: true,
          message: __('Above alignment max width. It will be clamped when applied.', TEXT_DOMAIN)
        };
      }
      if (px < parseFloat(DEFAULT_MIN_BLOCK_WIDTH)) {
        return {
          isValid: true,
          message: __('Below 300px minimum. It will be clamped to 300px when applied.', TEXT_DOMAIN)
        };
      }
      if (px < MIN_RECOMMENDED_PREVIEW_WIDTH_PX) {
        return {
          isValid: true,
          message: __('Below the recommended 410px width. It will stay this size, but some calculators may stack or compress.', TEXT_DOMAIN)
        };
      }
      return {
        isValid: true,
        message: __('Valid width value.', TEXT_DOMAIN)
      };
    }

    return {
      isValid: false,
      message: __('Use % or px units, for example: 100%, 50%, 700px.', TEXT_DOMAIN)
    };
  }

  function normalizeWidthToMax(widthValue, maxWidthPx) {
    const raw = String(widthValue || '').trim();
    if (!raw || !Number.isFinite(maxWidthPx) || maxWidthPx <= 0) {
      return widthValue;
    }
    const minWidthPx = parseFloat(DEFAULT_MIN_BLOCK_WIDTH);

    const percentMatch = raw.match(/^(\d+(?:\.\d+)?)%$/i);
    if (percentMatch) {
      const percent = Math.min(100, Math.max(0, parseFloat(percentMatch[1])));
      const scaled = (maxWidthPx * percent) / 100;
      const clamped = Math.min(maxWidthPx, Math.max(minWidthPx, scaled));
      const px = Math.round(clamped * 100) / 100;
      return `${px}px`;
    }

    const pxMatch = raw.match(/^(\d+(?:\.\d+)?)px$/i);
    if (pxMatch) {
      const px = parseFloat(pxMatch[1]);
      const clamped = Math.min(maxWidthPx, Math.max(minWidthPx, px));
      const normalizedPx = Math.round(clamped * 100) / 100;
      return `${normalizedPx}px`;
    }

    return widthValue;
  }

  function getEditorPreviewWidthStyle(rawWidth, effectiveWidth, effectiveMaxWidth) {
    const raw = String(rawWidth || '').trim();

    if (!raw) {
      return {
        width: '100%',
        maxWidth: effectiveMaxWidth
      };
    }

    const percentMatch = raw.match(/^(\d+(?:\.\d+)?)%$/i);
    if (percentMatch) {
      const percent = Math.min(100, Math.max(0, parseFloat(percentMatch[1])));
      return {
        width: `${formatCssNumber(percent)}%`,
        maxWidth: effectiveMaxWidth
      };
    }

    if (/^(\d+(?:\.\d+)?)px$/i.test(raw)) {
      return {
        width: '100%',
        maxWidth: effectiveWidth
      };
    }

    const keyword = raw.toLowerCase();
    if (keyword === 'auto' || keyword === 'inherit' || keyword === 'initial') {
      return {
        width: keyword,
        maxWidth: effectiveMaxWidth
      };
    }

    return {
      width: effectiveWidth,
      maxWidth: effectiveMaxWidth
    };
  }

  function getEditorData() {
    return Object.assign({}, INITIAL_EDITOR_DATA, window.VAREONCALC_EDITOR || {});
  }

  function buildCalculatorList(calculators) {
    const fallback = [
      {
        value: 'bmi',
        title: __('BMI Calculator', TEXT_DOMAIN),
        icon: '🧮',
        description: ''
      }
    ];

    if (!calculators || typeof calculators !== 'object') {
      return fallback;
    }

    const items = Object.keys(calculators).map(function (type) {
      const calc = calculators[type] || {};
      return {
        value: type,
        title: calc.title || type,
        icon: calc.icon || '🧮',
        description: calc.description || ''
      };
    });

    if (!items.length) {
      return fallback;
    }

    items.sort(function (a, b) {
      return a.title.localeCompare(b.title);
    });

    return items;
  }

  function normalizeThemeKey(themeKey) {
    if (typeof themeKey !== 'string' || !themeKey) {
      return { value: '', group: 'preset' };
    }

    if (themeKey.indexOf('preset:') === 0) {
      return {
        value: themeKey.slice(7),
        group: 'preset'
      };
    }

    if (themeKey.indexOf('custom:') === 0) {
      return {
        value: themeKey.slice(7),
        group: 'custom'
      };
    }

    return {
      value: themeKey,
      group: 'preset'
    };
  }

  function buildThemeOptions(themeMap, defaultTheme) {
    const seenValues = {};
    const rawOptions = [];

    if (themeMap && typeof themeMap === 'object') {
      Object.keys(themeMap).forEach(function (key) {
        const normalized = normalizeThemeKey(key);
        const value = normalized.value;
        if (!value || seenValues[value]) {
          return;
        }

        seenValues[value] = true;
        rawOptions.push({
          value: value,
          label: typeof themeMap[key] === 'string' && themeMap[key] ? themeMap[key] : value,
          group: normalized.group
        });
      });
    }

    rawOptions.sort(function (a, b) {
      if (a.group === b.group) {
        return a.label.localeCompare(b.label);
      }
      return a.group === 'preset' ? -1 : 1;
    });

    const defaultMatch = rawOptions.find(function (option) {
      return option.value === defaultTheme;
    });

    return {
      defaultLabel: defaultMatch ? defaultMatch.label : (defaultTheme || __('Default Theme', TEXT_DOMAIN)),
      options: rawOptions
    };
  }

  function getBlockListLabel(attributes, context) {
    const calculators = (INITIAL_EDITOR_DATA && INITIAL_EDITOR_DATA.calculators)
      || (window.VAREONCALC_EDITOR && window.VAREONCALC_EDITOR.calculators)
      || {};
    const calcType = attributes && typeof attributes.type === 'string' ? attributes.type : '';
    const calcMeta = calcType && calculators ? calculators[calcType] : null;
    const calcTitle = calcMeta && calcMeta.title
      ? calcMeta.title
      : __('Vareon Calculator', TEXT_DOMAIN);

    if (context === 'accessibility') {
      return calcTitle;
    }

    if (context === 'list-view') {
      return calcTitle;
    }

    return undefined;
  }

  function getEditorLogoUrl() {
    const editorData = getEditorData();
    if (typeof editorData.pluginUrl !== 'string' || !editorData.pluginUrl) {
      return '';
    }

    return `${editorData.pluginUrl}assets/vareon-logo.png`;
  }

  function getBlockEditorIconUrl() {
    const editorData = getEditorData();
    if (typeof editorData.pluginUrl !== 'string' || !editorData.pluginUrl) {
      return '';
    }

    return `${editorData.pluginUrl}assets/icon-256x256.png`;
  }

  function renderEditorLogo(className, key) {
    const logoUrl = getEditorLogoUrl();
    if (logoUrl) {
      return el('img', {
        key: key,
        className: className,
        src: logoUrl,
        alt: ''
      });
    }

    return el(
      'span',
      {
        key: key,
        className: className
      },
      '🧮'
    );
  }

  function getBlockEditorIcon() {
    const iconUrl = getBlockEditorIconUrl();
    if (!iconUrl) {
      return 'calculator';
    }

    return el('img', {
      src: iconUrl,
      alt: '',
      style: {
        width: 28,
        height: 28,
        objectFit: 'contain',
        display: 'block'
      }
    });
  }

  function isObject(value) {
    return !!value && typeof value === 'object' && !Array.isArray(value);
  }

  function getThemeConfigById(themeConfigs, rawThemeId) {
    if (!isObject(themeConfigs) || typeof rawThemeId !== 'string' || !rawThemeId) {
      return null;
    }

    if (isObject(themeConfigs[rawThemeId])) {
      return themeConfigs[rawThemeId];
    }

    const normalizedThemeId = rawThemeId
      .replace(/^preset:/, '')
      .replace(/^custom:/, '');

    if (isObject(themeConfigs[normalizedThemeId])) {
      return themeConfigs[normalizedThemeId];
    }

    return null;
  }

  function normalizePreviewEngineConfig(editorData) {
    const source = isObject(editorData.previewLoader)
      ? editorData.previewLoader
      : {};
    const fallbackLoaderUrl = (
      typeof editorData.pluginUrl === 'string'
      && editorData.pluginUrl
    )
      ? `${editorData.pluginUrl}js/vareoncalc-loader.js`
      : '';

    return {
      loaderUrl: (typeof source.url === 'string' && source.url) ? source.url : fallbackLoaderUrl,
      useMinifiedAssets: !!editorData.useMinifiedAssets
    };
  }

  function measureRenderedPreviewWidth(node) {
    if (!node || typeof node.querySelector !== 'function') {
      return null;
    }

    var target = node.querySelector('.vareoncalc-editor-preview-shell')
      || node.querySelector('.vareoncalc-editor-preview-host')
      || node;
    if (!target) {
      return null;
    }

    var measuredWidth = 0;
    if (typeof target.getBoundingClientRect === 'function') {
      measuredWidth = Math.round(target.getBoundingClientRect().width || 0);
    }
    if (!measuredWidth && typeof target.clientWidth === 'number') {
      measuredWidth = Math.round(target.clientWidth || 0);
    }

    return measuredWidth > 0 ? measuredWidth : null;
  }

  function ensurePreviewLoader(loaderUrl) {
    if (typeof window.vareoncalcMount === 'function') {
      return Promise.resolve(true);
    }

    if (!loaderUrl || typeof loaderUrl !== 'string') {
      return Promise.resolve(false);
    }

    if (!window.__VAREONCALC_PRO_EDITOR_LOADER_PROMISE) {
      try {
        window.__VAREONCALC_PRO_EDITOR_LOADER_PROMISE = import(loaderUrl).catch(function () {
          return null;
        });
      } catch {
        return Promise.resolve(false);
      }
    }

    return window.__VAREONCALC_PRO_EDITOR_LOADER_PROMISE.then(function () {
      return typeof window.vareoncalcMount === 'function';
    });
  }

  function buildPreviewConfig(type, selectedTheme, showBranding, editorData) {
    if (!type) {
      return null;
    }

    const previewConfig = { type: type };
    const themeConfigs = isObject(editorData.themeConfigs) ? editorData.themeConfigs : {};
    const activeTheme = isObject(editorData.activeTheme) ? editorData.activeTheme : null;
    const resolvedThemeConfig = selectedTheme
      ? getThemeConfigById(themeConfigs, selectedTheme)
      : activeTheme;
    const fallbackTheme = typeof editorData.defaultTheme === 'string' ? editorData.defaultTheme : '';

    if (resolvedThemeConfig && typeof resolvedThemeConfig.palette === 'string' && resolvedThemeConfig.palette) {
      previewConfig.theme = resolvedThemeConfig.palette;
    } else if (selectedTheme) {
      previewConfig.theme = selectedTheme
        .replace(/^preset:/, '')
        .replace(/^custom:/, '');
    } else if (fallbackTheme) {
      previewConfig.theme = fallbackTheme;
    }

    if (resolvedThemeConfig && isObject(resolvedThemeConfig.colors) && Object.keys(resolvedThemeConfig.colors).length) {
      previewConfig.colors = resolvedThemeConfig.colors;
    }

    if (resolvedThemeConfig && isObject(resolvedThemeConfig.design) && Object.keys(resolvedThemeConfig.design).length) {
      previewConfig.design = resolvedThemeConfig.design;
    }

    let effectiveBranding;
    if (typeof showBranding === 'boolean') {
      effectiveBranding = showBranding;
    } else if (typeof editorData.branding === 'boolean') {
      effectiveBranding = editorData.branding;
    } else if (isObject(window.VAREONCALC_CFG) && typeof window.VAREONCALC_CFG.branding === 'boolean') {
      effectiveBranding = window.VAREONCALC_CFG.branding;
    }

    if (typeof effectiveBranding === 'boolean') {
      previewConfig.branding = effectiveBranding;
    }

    return previewConfig;
  }

  function LivePreview(props) {
    const {
      config,
      engineConfig,
      isInteractive,
      previewLabel,
      onOpenModal
    } = props;

    const hostRef = useRef(null);
    const engineRef = useRef(null);
    const isMountedRef = useRef(true);
    const [status, setStatus] = useState('idle');
    const [errorMessage, setErrorMessage] = useState('');
    const [retryCount, setRetryCount] = useState(0);
    const lastRetriedAtRef = useRef(0);

    useEffect(
      function () {
        let cancelled = false;

        if (!config || !config.type || !hostRef.current) {
          setStatus('idle');
          setErrorMessage('');
          return undefined;
        }

        setStatus('loading');
        setErrorMessage('');

        var renderPreview = async function () {
          if (!window.VareoncalcShadowPreview || typeof window.VareoncalcShadowPreview.create !== 'function') {
            throw new Error(__('Preview engine is unavailable in editor.', TEXT_DOMAIN));
          }

          var loaderReady = await ensurePreviewLoader(engineConfig && engineConfig.loaderUrl);
          if (!loaderReady) {
            throw new Error(__('Preview loader is unavailable in editor.', TEXT_DOMAIN));
          }

          if (cancelled) {
            return;
          }

          if (!engineRef.current) {
            engineRef.current = window.VareoncalcShadowPreview.create({
              container: hostRef.current,
              hostClassName: 'vareoncalc-editor-preview-shadow-host',
              scaleToFit: false,
              naturalHeight: true,
              useMinifiedAssets: !!(engineConfig && engineConfig.useMinifiedAssets),
              minHeight: EDITOR_PREVIEW_LOADING_MIN_HEIGHT_PX,
              minWidth: 0,
              refreshOnResize: false,
              maxHeight: 2200,
              timeoutMs: 10000,
              ensureLoader: function () {
                return ensurePreviewLoader(engineConfig && engineConfig.loaderUrl);
              },
              onReady: function () {
                if (!isMountedRef.current) {
                  return;
                }
                setStatus('ready');
                setErrorMessage('');
              },
              onError: function (message) {
                if (!isMountedRef.current) {
                  return;
                }
                setStatus('error');
                setErrorMessage(message || __('Calculator preview unavailable in editor.', TEXT_DOMAIN));
              }
            });
            engineRef.current.mount();
          }

          if (
            retryCount > lastRetriedAtRef.current
            && engineRef.current
            && typeof engineRef.current.retry === 'function'
          ) {
            lastRetriedAtRef.current = retryCount;
            engineRef.current.retry();
          }

          if (engineRef.current && typeof engineRef.current.sendConfig === 'function') {
            engineRef.current.sendConfig(config, 80);
          } else {
            throw new Error(__('Calculator preview engine failed to initialize.', TEXT_DOMAIN));
          }
        };

        renderPreview().catch(function (error) {
          if (cancelled) {
            return;
          }
          setStatus('error');
          setErrorMessage(
            error && error.message
              ? error.message
              : __('Calculator preview unavailable in editor.', TEXT_DOMAIN)
          );
        });

        return function () {
          cancelled = true;
        };
      },
      [config, engineConfig, previewLabel, retryCount]
    );

    useEffect(
      function () {
        return function () {
          isMountedRef.current = false;
          if (engineRef.current && typeof engineRef.current.destroy === 'function') {
            engineRef.current.destroy();
          }
          engineRef.current = null;
        };
      },
      []
    );

    return el(
      'div',
      {
        className: [
          'vareoncalc-editor-preview-shell',
          isInteractive ? 'vareoncalc-editor-preview-shell-interactive' : 'vareoncalc-editor-preview-shell-safe'
        ].join(' '),
        'aria-label': previewLabel
      },
      [
        el('div', {
          key: 'host',
          className: 'vareoncalc-editor-preview-host',
          ref: hostRef
        }),
        status === 'loading' && el(
          'div',
          {
            key: 'loading',
            className: 'vareoncalc-editor-preview-feedback vareoncalc-editor-preview-feedback-loading'
          },
          [
            el(Spinner, { key: 'spinner' }),
            el('span', { key: 'label' }, __('Loading live preview…', TEXT_DOMAIN))
          ]
        ),
        status === 'error' && el(
          'div',
          {
            key: 'error',
            className: 'vareoncalc-editor-preview-feedback vareoncalc-editor-preview-feedback-error',
            role: 'alert'
          },
          [
            el(
              'p',
              {
                key: 'error-message',
                className: 'vareoncalc-editor-preview-error-message'
              },
              errorMessage || __('Calculator preview unavailable in editor.', TEXT_DOMAIN)
            ),
            el(
              'div',
              {
                key: 'error-actions',
                className: 'vareoncalc-editor-preview-error-actions'
              },
              [
                el(
                  Button,
                  {
                    key: 'retry',
                    variant: 'secondary',
                    onClick: function () {
                      setRetryCount(function (current) {
                        return current + 1;
                      });
                    },
                    'aria-label': __('Retry loading calculator preview', TEXT_DOMAIN)
                  },
                  __('Retry', TEXT_DOMAIN)
                ),
                el(
                  Button,
                  {
                    key: 'choose',
                    variant: 'tertiary',
                    onClick: onOpenModal,
                    'aria-label': __('Choose a different calculator', TEXT_DOMAIN)
                  },
                  __('Choose calculator', TEXT_DOMAIN)
                )
              ]
            )
          ]
        )
      ]
    );
  }

  registerBlockType(BLOCK_NAME, {
    title: __('Vareon Calculator', TEXT_DOMAIN),
    icon: getBlockEditorIcon(),
    category: 'vareoncalc',
    keywords: ['calculator', 'vareoncalc', 'finance', 'bmi'],
    __experimentalLabel: function (attributes, options) {
      const context = options && options.context ? options.context : 'visual';
      return getBlockListLabel(attributes, context);
    },
    attributes: {
      type: {
        type: 'string',
        default: ''
      },
      theme: {
        type: 'string',
        default: null
      },
      width: {
        type: 'string',
        default: '100%'
      },
      showBranding: {
        type: 'boolean'
      },
      showTitle: {
        type: 'boolean'
      },
      align: {
        type: 'string'
      }
    },
    supports: {
      align: ['left', 'center', 'right', 'wide', 'full'],
      spacing: {
        margin: true,
        padding: true
      },
      html: false
    },
    edit: function (props) {
      const { attributes, setAttributes, className } = props;
      const editorData = useMemo(getEditorData, []);
      const calculatorList = useMemo(
        function () {
          return buildCalculatorList(editorData.calculators);
        },
        [editorData.calculators]
      );
      const themeData = useMemo(
        function () {
          return buildThemeOptions(editorData.themes, editorData.defaultTheme);
        },
        [editorData.themes, editorData.defaultTheme]
      );

      const [isModalOpen, setIsModalOpen] = useState(false);
      const [selectedCalcType, setSelectedCalcType] = useState(attributes.type || '');
      const [selectedTheme, setSelectedTheme] = useState(attributes.theme || '');
      const selectedThemeRef = useRef(attributes.theme || '');
      
      const [isInteractivePreview, setIsInteractivePreview] = useState(false);
      const [draftWidth, setDraftWidth] = useState(attributes.width || '100%');
      const [measuredPreviewWidthPx, setMeasuredPreviewWidthPx] = useState(null);
      const blockWrapperRef = useRef(null);
      const commitWidthValue = function (nextWidth, alignOverride) {
        const resolvedAlign = typeof alignOverride === 'string' ? alignOverride : (attributes.align || '');
        const normalizedWidth = normalizeWidthForStorage(nextWidth, resolvedAlign);
        setAttributes({ width: normalizedWidth });
        setDraftWidth(normalizedWidth);
        return normalizedWidth;
      };

      useEffect(
        function () {
          setDraftWidth(attributes.width || '100%');
        },
        [attributes.width]
      );
      useEffect(
        function () {
          selectedThemeRef.current = selectedTheme || '';
        },
        [selectedTheme]
      );
      useEffect(
        function () {
          const currentAlign = attributes.align || '';
          const currentWidth = attributes.width || getDefaultWidthForAlign(currentAlign);
          const normalizedCurrentWidth = normalizeWidthForStorage(currentWidth, currentAlign);
          if (normalizedCurrentWidth !== currentWidth) {
            setAttributes({ width: normalizedCurrentWidth });
            setDraftWidth(normalizedCurrentWidth);
          }
        },
        [attributes.align, attributes.width]
      );

      const selectedCalculator = calculatorList.find(function (calc) {
        return calc.value === attributes.type;
      }) || null;

      const modalThemeOptions = [
        {
          value: '',
          label: `${__('Default (from settings)', TEXT_DOMAIN)}: ${themeData.defaultLabel}`
        }
      ].concat(
        themeData.options.map(function (option) {
          return {
            value: option.value,
            label: option.group === 'custom'
              ? `${option.label} (${__('Custom', TEXT_DOMAIN)})`
              : option.label
          };
        })
      );

      if (
        selectedTheme &&
        !modalThemeOptions.some(function (option) {
          return option.value === selectedTheme;
        })
      ) {
        modalThemeOptions.push({
          value: selectedTheme,
          label: selectedTheme
        });
      }

      const filteredCalculators = calculatorList;

      const previewLabel = selectedCalculator
        ? __('Live preview of', TEXT_DOMAIN) + ' ' + selectedCalculator.title
        : __('Live calculator preview', TEXT_DOMAIN);

      const previewEngineConfig = useMemo(
        function () {
          return normalizePreviewEngineConfig(editorData);
        },
        [editorData.previewLoader, editorData.pluginUrl]
      );

      const previewConfig = useMemo(
        function () {
          return buildPreviewConfig(
            attributes.type,
            attributes.theme || '',
            attributes.showBranding,
            editorData
          );
        },
        [attributes.type, attributes.theme, attributes.showBranding, editorData]
      );

      const openModal = function () {
        setSelectedCalcType(attributes.type || '');
        setSelectedTheme(attributes.theme || '');
        selectedThemeRef.current = attributes.theme || '';
        setIsModalOpen(true);
      };

      const applyModalSelection = function (nextCalcType) {
        const calculatorType = nextCalcType || selectedCalcType;
        if (!calculatorType) {
          return;
        }
        const appliedTheme = selectedThemeRef.current || null;
        setAttributes({
          type: calculatorType,
          theme: appliedTheme
        });
        setIsModalOpen(false);
      };

      const widthAlign = attributes.align || '';
      const defaultWidthForAlign = getDefaultWidthForAlign(widthAlign);
      const widthPresets = getWidthPresetsForAlign(widthAlign);
      const widthExamples = getWidthExamplesForAlign(widthAlign).join(', ');
      const widthValidation = getWidthInputValidation(draftWidth, widthAlign);
      const widthUpperGuidance = getWidthUpperGuidanceForAlign(widthAlign);
      const widthLimitNotice = __('Recommended minimum: 410px.', TEXT_DOMAIN);
      const widthHelp = [
        widthValidation.message,
        widthLimitNotice,
        widthUpperGuidance.helpMessage,
        `${__('Examples:', TEXT_DOMAIN)} ${widthExamples}`
      ].join(' • ');

      const blockControls = BlockControls && ToolbarGroup && ToolbarButton
        ? el(
          BlockControls,
          {},
          el(
            ToolbarGroup,
            {},
            el(ToolbarButton, {
              icon: 'edit',
              label: __('Change calculator', TEXT_DOMAIN),
              onClick: openModal
            }),
            el(Dropdown, {
              className: 'vareoncalc-editor-width-dropdown',
              renderToggle: function (toggleProps) {
                return el(ToolbarButton, {
                  icon: 'editor-expand',
                  label: __('Set width', TEXT_DOMAIN),
                  onClick: toggleProps.onToggle,
                  isPressed: toggleProps.isOpen,
                  'aria-expanded': toggleProps.isOpen
                });
              },
              renderContent: function (contentProps) {
                return el(
                  'div',
                  {
                    className: 'vareoncalc-editor-width-popover'
                  },
                  [
                    el(
                      'p',
                      {
                        key: 'quick-widths',
                        className: 'vareoncalc-editor-width-popover-label'
                      },
                      __('Quick widths', TEXT_DOMAIN)
                    ),
                    el(
                      'div',
                      {
                        key: 'width-list',
                        className: 'vareoncalc-editor-width-preset-list'
                      },
                      widthPresets.map(function (widthValue) {
                        const normalizedPresetWidth = normalizeWidthForStorage(widthValue, widthAlign);
                        return el(
                          Button,
                          {
                            key: widthValue,
                            variant: attributes.width === normalizedPresetWidth ? 'primary' : 'secondary',
                            onClick: function () {
                              commitWidthValue(widthValue, widthAlign);
                              if (contentProps && typeof contentProps.onClose === 'function') {
                                contentProps.onClose();
                              }
                            }
                          },
                          widthValue
                        );
                      })
                    ),
                    el(
                      BaseControl,
                      {
                        key: 'custom-width',
                        label: __('Custom width', TEXT_DOMAIN)
                      },
                      el(TextControl, {
                        value: draftWidth,
                        onChange: setDraftWidth,
                        help: widthHelp
                      })
                    ),
                    el(
                      Button,
                      {
                        key: 'reset-width',
                        variant: 'secondary',
                        onClick: function () {
                          commitWidthValue(defaultWidthForAlign, widthAlign);
                          if (contentProps && typeof contentProps.onClose === 'function') {
                            contentProps.onClose();
                          }
                        }
                      },
                      __('Reset width', TEXT_DOMAIN)
                    ),
                    el(
                      Button,
                      {
                        key: 'apply-width',
                        variant: 'primary',
                        disabled: !widthValidation.isValid,
                        onClick: function () {
                          const nextWidth = String(draftWidth || '').trim() || defaultWidthForAlign;
                          commitWidthValue(nextWidth, widthAlign);
                          if (contentProps && typeof contentProps.onClose === 'function') {
                            contentProps.onClose();
                          }
                        }
                      },
                      __('Apply width', TEXT_DOMAIN)
                    )
                  ]
                );
              }
            }),
            el(ToolbarButton, {
              icon: 'visibility',
              isPressed: isInteractivePreview,
              label: isInteractivePreview
                ? __('Switch to view mode', TEXT_DOMAIN)
                : __('Switch to interact mode', TEXT_DOMAIN),
              onClick: function () {
                setIsInteractivePreview(function (previous) {
                  return !previous;
                });
              }
            }),
          )
        )
        : null;

      const globalBrandingSetting = typeof editorData.branding === 'boolean'
        ? editorData.branding
        : (
          isObject(window.VAREONCALC_CFG) && typeof window.VAREONCALC_CFG.branding === 'boolean'
            ? window.VAREONCALC_CFG.branding
            : true
        );
      const effectiveBrandingSetting = typeof attributes.showBranding === 'boolean'
        ? attributes.showBranding
        : globalBrandingSetting;

      const inspectorControls = InspectorControls
        ? el(
          InspectorControls,
          {},
          el(
            PanelBody,
            {
              title: __('Display Settings', TEXT_DOMAIN),
              initialOpen: true
            },
            el(ToggleControl, {
              label: __('Show Branding', TEXT_DOMAIN),
              checked: effectiveBrandingSetting,
              onChange: function (value) {
                setAttributes({ showBranding: value });
              },
              help: attributes.showBranding === undefined
                ? (
                  globalBrandingSetting
                    ? __('Using global branding setting (currently enabled).', TEXT_DOMAIN)
                    : __('Using global branding setting (currently disabled).', TEXT_DOMAIN)
                )
                : (
                  attributes.showBranding
                    ? __('Branding is forced on for this block.', TEXT_DOMAIN)
                    : __('Branding is hidden for this block.', TEXT_DOMAIN)
                )
            }),
            attributes.showBranding !== undefined && el(Button, {
              variant: 'tertiary',
              onClick: function () {
                setAttributes({ showBranding: undefined });
              }
            }, __('Use global default', TEXT_DOMAIN))
          )
        )
        : null;

      const blockClasses = [
        'vareoncalc-block-editor',
        'vareoncalc-editor-live-preview',
        className,
        attributes.align ? `align${attributes.align}` : ''
      ].filter(Boolean).join(' ');
      const currentAlign = attributes.align || '';
      const isWideOrFullAlign = attributes.align === 'wide' || attributes.align === 'full';
      const rawEditorWidth = attributes.width || '100%';
      const maxWidthForAlign = getMaxWidthForAlign(currentAlign);
      const effectiveEditorMaxWidth = `${maxWidthForAlign}px`;
      const effectiveEditorWidth = normalizeWidthToMax(rawEditorWidth, maxWidthForAlign);
      const rawEditorWidthPx = parsePixelWidth(rawEditorWidth);
      const effectiveEditorWidthPx = parsePixelWidth(effectiveEditorWidth);
      const actualPreviewWidthPx = Number.isFinite(measuredPreviewWidthPx) ? measuredPreviewWidthPx : effectiveEditorWidthPx;
      const previewWidthStyle = getEditorPreviewWidthStyle(rawEditorWidth, effectiveEditorWidth, effectiveEditorMaxWidth);
      const showTinyWidthWarning = Number.isFinite(actualPreviewWidthPx) && actualPreviewWidthPx < MIN_RECOMMENDED_PREVIEW_WIDTH_PX;
      const showWideWidthWarning = Number.isFinite(rawEditorWidthPx) && rawEditorWidthPx > widthUpperGuidance.warningThresholdPx;
      let editorMarginLeft = 0;
      let editorMarginRight = 0;
      if (isWideOrFullAlign) {
        editorMarginLeft = 'auto';
        editorMarginRight = 'auto';
      } else if (attributes.align === 'left') {
        editorMarginLeft = 0;
        editorMarginRight = 'auto';
      } else if (attributes.align === 'center') {
        editorMarginLeft = 'auto';
        editorMarginRight = 'auto';
      } else if (attributes.align === 'right') {
        editorMarginLeft = 'auto';
        editorMarginRight = 0;
      }

      useEffect(
        function () {
          var wrapperNode = blockWrapperRef.current;
          if (!wrapperNode) {
            setMeasuredPreviewWidthPx(null);
            return undefined;
          }

          var lastMeasuredWidth = null;
          var measureWidth = function () {
            var nextWidth = measureRenderedPreviewWidth(wrapperNode);
            if (!Number.isFinite(nextWidth)) {
              if (lastMeasuredWidth !== null) {
                lastMeasuredWidth = null;
                setMeasuredPreviewWidthPx(null);
              }
              return;
            }

            if (lastMeasuredWidth !== null && Math.abs(nextWidth - lastMeasuredWidth) < 4) {
              return;
            }

            lastMeasuredWidth = nextWidth;
            setMeasuredPreviewWidthPx(nextWidth);
          };

          measureWidth();

          var detectEditorSurface = function () {
            var node = wrapperNode.parentElement;
            while (node) {
              var bg = window.getComputedStyle(node).backgroundColor;
              if (bg && !/^rgba?\(\s*0\s*,\s*0\s*,\s*0\s*,\s*0\s*\)$/.test(bg) && bg !== 'transparent') {
                var match = bg.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);
                if (match) {
                  var luma = (parseInt(match[1], 10) * 299 + parseInt(match[2], 10) * 587 + parseInt(match[3], 10) * 114) / 1000;
                  wrapperNode.dataset.editorSurface = luma > 155 ? 'light' : 'dark';
                  return;
                }
              }
              node = node.parentElement;
            }
            wrapperNode.dataset.editorSurface = 'light';
          };
          detectEditorSurface();

          if (typeof window === 'undefined' || typeof window.ResizeObserver !== 'function') {
            return undefined;
          }

          var observer = new window.ResizeObserver(function () {
            measureWidth();
            detectEditorSurface();
          });

          observer.observe(wrapperNode);
          return function () {
            observer.disconnect();
          };
        },
        [attributes.type, attributes.align, attributes.width, isInteractivePreview]
      );

      const blockProps = typeof useBlockProps === 'function'
        ? useBlockProps({
          ref: blockWrapperRef,
          className: blockClasses,
          style: {
            width: previewWidthStyle.width,
            maxWidth: previewWidthStyle.maxWidth,
            marginLeft: editorMarginLeft,
            marginRight: editorMarginRight,
            float: 'none',
            display: 'block',
            position: 'relative'
          }
        })
        : {
          ref: blockWrapperRef,
          className: blockClasses,
          style: {
            width: previewWidthStyle.width,
            maxWidth: previewWidthStyle.maxWidth,
            marginLeft: editorMarginLeft,
            marginRight: editorMarginRight,
            float: 'none',
            display: 'block',
            position: 'relative'
          }
        };

      const selectedModalCalculator = selectedCalcType
        ? calculatorList.find(function (calc) { return calc.value === selectedCalcType; }) || null
        : null;
      const selectedThemeOption = modalThemeOptions.find(function (option) {
        return option.value === selectedTheme;
      });

      const buildModalHeader = function () {
        return el(
          'div',
          { className: 'vcm-header' },
          el('div', { className: 'vcm-header__top', key: 'top' }, [
            el('div', { className: 'vcm-header__title-group', key: 'title-group' }, [
              el('h2', { className: 'vcm-header__title', key: 'title' }, [
                renderEditorLogo('vcm-header__title-icon', 'icon'),
                __('Select Calculator', TEXT_DOMAIN)
              ]),
              el('p', { className: 'vcm-header__subtitle', key: 'subtitle' }, calculatorList.length + ' ' + __('calculators available', TEXT_DOMAIN))
            ]),
            el('div', { className: 'vcm-header__actions', key: 'actions' },
              el('button', {
                className: 'vcm-close',
                key: 'close',
                type: 'button',
                onClick: function () {
                  setIsModalOpen(false);
                },
                'aria-label': __('Close', TEXT_DOMAIN)
              }, '×')
            )
          ])
        );
      };

      const buildCalculatorGrid = function () {
        const cards = filteredCalculators.map(function (calc) {
          const isSelected = selectedCalcType === calc.value;
          return el(
            'button',
            {
              key: calc.value,
              type: 'button',
              className: 'vcm-card' + (isSelected ? ' is-selected' : ''),
              onClick: function () {
                setSelectedCalcType(calc.value);
              },
              onDoubleClick: function () {
                applyModalSelection(calc.value);
              }
            },
            [
              isSelected && el('div', { className: 'vcm-card__check', key: 'check' }, '✓'),
              el('div', { className: 'vcm-card__icon', key: 'icon' }, calc.icon),
              el('div', { className: 'vcm-card__title', key: 'title' }, calc.title),
              calc.description && el('div', { className: 'vcm-card__desc', key: 'desc' }, calc.description)
            ]
          );
        });

        const hasNoResults = cards.length === 0;

        if (hasNoResults) {
          cards.push(
            el('div', { className: 'vcm-empty', key: 'empty-state' }, [
              el('span', { className: 'vcm-empty__icon', key: 'icon' }, '🔍'),
              el('strong', { className: 'vcm-empty__title', key: 'title' }, __('No calculators found', TEXT_DOMAIN)),
              el('span', { className: 'vcm-empty__hint', key: 'hint' }, __('Try a different search term', TEXT_DOMAIN))
            ])
          );
        }

        const gridAreaClassName = hasNoResults ? 'vcm-grid-area vcm-grid-area--empty' : 'vcm-grid-area';
        const gridClassName = hasNoResults ? 'vcm-grid vcm-grid--empty' : 'vcm-grid';

        return el(
          'div',
          { className: gridAreaClassName },
          el('div', { className: gridClassName }, cards)
        );
      };

      const buildModalFooter = function () {
        return el(
          'div',
          { className: 'vcm-footer' },
          [
            el(
              'div',
              { className: 'vcm-footer__selection', key: 'selection' },
              selectedModalCalculator
                ? [
                  el('span', { className: 'vcm-footer__sel-icon', key: 'icon' }, selectedModalCalculator.icon || '🧮'),
                  el('div', { className: 'vcm-footer__sel-info', key: 'info' }, [
                    el('div', { className: 'vcm-footer__sel-name', key: 'name' }, selectedModalCalculator.title || ''),
                    el('div', { className: 'vcm-footer__sel-hint', key: 'hint' }, __('Selected', TEXT_DOMAIN))
                  ])
                ]
                : [el('div', { className: 'vcm-footer__sel-hint', key: 'empty-hint' }, __('Click a calculator to select it', TEXT_DOMAIN))]
            ),
            el('div', { className: 'vcm-footer__theme', key: 'theme' }, [
              el('span', { className: 'vcm-footer__theme-label', key: 'theme-label' }, __('Theme:', TEXT_DOMAIN)),
              el(Dropdown, {
                popoverProps: {
                  placement: 'top-start',
                  offset: 4,
                  noArrow: true
                },
                renderToggle: function (toggleProps) {
                  return el(
                    'button',
                    {
                      type: 'button',
                      className: 'vcm-theme-btn',
                      onClick: toggleProps.onToggle,
                      'aria-expanded': toggleProps.isOpen
                    },
                    [
                      el(
                        'span',
                        { className: 'vcm-theme-btn__label', key: 'label' },
                        selectedThemeOption
                          ? selectedThemeOption.label
                          : __('Default (from settings)', TEXT_DOMAIN)
                      ),
                      el('span', { className: 'vcm-theme-btn__arrow', key: 'arrow' }, '▼')
                    ]
                  );
                },
                renderContent: function (contentProps) {
                  return el(
                    'div',
                    { className: 'vcm-theme-list' },
                    modalThemeOptions.map(function (option) {
                      const isSelected = option.value === selectedTheme;
                      return el(
                        'button',
                        {
                          key: option.value || 'default',
                          type: 'button',
                          className: 'vcm-theme-option' + (isSelected ? ' is-selected' : ''),
                          onClick: function () {
                            setSelectedTheme(option.value);
                            selectedThemeRef.current = option.value;
                            if (contentProps && typeof contentProps.onClose === 'function') {
                              contentProps.onClose();
                            }
                          }
                        },
                        [
                          el('span', { key: 'option-label' }, option.label),
                          isSelected && el('span', { className: 'vcm-theme-option__check', key: 'check' }, '✓')
                        ]
                      );
                    })
                  );
                }
              })
            ]),
            el('div', { className: 'vcm-footer__actions', key: 'actions' }, [
              el('button', {
                type: 'button',
                className: 'vcm-btn-cancel',
                key: 'cancel',
                onClick: function () {
                  setIsModalOpen(false);
                }
              }, __('Cancel', TEXT_DOMAIN)),
              el('button', {
                type: 'button',
                className: 'vcm-btn-insert',
                key: 'apply',
                disabled: !selectedCalcType,
                onClick: function () {
                  applyModalSelection();
                }
              }, [
                attributes.type ? __('Apply', TEXT_DOMAIN) : __('Insert Calculator', TEXT_DOMAIN),
                el('span', { className: 'vcm-btn-insert__arrow', key: 'arrow' }, '→')
              ])
            ])
          ]
        );
      };

      const selectionModal = isModalOpen && el(
        Modal,
        {
          className: 'vcm-modal',
          title: __('Select Calculator', TEXT_DOMAIN),
          onRequestClose: function () {
            setIsModalOpen(false);
          },
          __experimentalHideHeader: true,
          style: {
            width: 'min(85vw, 1000px)',
            maxWidth: '85vw',
            maxHeight: '90vh'
          }
        },
        el(
          'div',
          { className: 'vcm-body' },
          [
            buildModalHeader(),
            buildCalculatorGrid(),
            buildModalFooter()
          ]
        )
      );

      const content = attributes.type
        ? [
          el(
            'div',
            {
              key: 'header',
              className: 'vareoncalc-editor-header'
            },
            [
              el(
                'strong',
                {
                  key: 'title',
                  className: 'vareoncalc-editor-header__title'
                },
                [
                  renderEditorLogo('vareoncalc-editor-header__logo', 'logo'),
                  el(
                    'span',
                    {
                      key: 'label',
                      className: 'vareoncalc-editor-header__label'
                    },
                    selectedCalculator
                      ? selectedCalculator.title
                      : __('Vareon Calculator', TEXT_DOMAIN)
                  )
                ]
              ),
              el(
                'span',
                {
                  key: 'meta',
                  className: 'vareoncalc-editor-preview-meta'
                },
                isInteractivePreview
                  ? __('Live preview · Interact mode', TEXT_DOMAIN)
                  : __('Live preview', TEXT_DOMAIN)
              )
            ]
          ),
          showTinyWidthWarning && el(
            'div',
            {
              key: 'tiny-width-warning',
              className: 'vareoncalc-editor-width-warning',
              role: 'status'
            },
            __('Recommended minimum is 410px. Smaller widths may stack fields or tighten spacing.', TEXT_DOMAIN)
          ),
          showWideWidthWarning && el(
            'div',
            {
              key: 'wide-width-warning',
              className: 'vareoncalc-editor-width-warning',
              role: 'status'
            },
            widthUpperGuidance.warningMessage
          ),
          el(LivePreview, {
            key: 'preview',
            config: previewConfig,
            engineConfig: previewEngineConfig,
            isInteractive: isInteractivePreview,
            previewLabel: previewLabel,
            onOpenModal: openModal
          })
        ]
        : [
          el(
            'div',
            {
              key: 'empty-shell',
              className: 'vareoncalc-editor-preview-shell vareoncalc-editor-preview-shell-empty',
              'aria-label': __('No calculator selected', TEXT_DOMAIN)
            },
            el(
              'div',
              {
                className: 'vareoncalc-editor-empty-state'
              },
              [
                renderEditorLogo('vareoncalc-editor-empty-logo', 'icon'),
                el('h3', { key: 'title', className: 'vareoncalc-editor-empty-title' }, __('Choose a calculator', TEXT_DOMAIN)),
                el('p', { key: 'desc', className: 'vareoncalc-editor-empty-description' }, __('Select a calculator to show a live preview in the editor.', TEXT_DOMAIN)),
                el(
                  Button,
                  {
                    key: 'choose',
                    variant: 'primary',
                    onClick: openModal,
                    'aria-label': __('Open calculator picker', TEXT_DOMAIN)
                  },
                  __('Choose Calculator', TEXT_DOMAIN)
                )
              ]
            )
          )
        ];

      return el(
        Fragment,
        {},
        selectionModal,
        blockControls,
        inspectorControls,
        el(
          'div',
          blockProps,
          content
        )
      );
    },
    save: function () {
      return null;
    }
  });
})(window.wp);
