<?php

namespace App\Customizer;

/**
 * -------------------------------------------------------------------------
 * Live Preview (Customizer preview frame)
 * -------------------------------------------------------------------------
 *
 * Updates CSS variables instantly in the preview without refresh.
 * Uses a PHP-exported payload to avoid duplicating preset maps in JS.
 */

add_action('customize_preview_init', function (): void {
    wp_enqueue_script('customize-preview');

    $payload = live_preview_payload();

    $js_payload = wp_json_encode($payload);
    if (! $js_payload) {
        $js_payload = '{}';
    }

    $js = <<<JS
(function(api){
  if (!api) return;

  var payload = {$js_payload} || {};
  var radiusPresets  = payload.radius  || {};
  var spacingPresets = payload.spacing || {};
  var blockPaddingYPresets = payload.block_padding_y || {};
  var blockPaddingXPresets = payload.block_padding_x || {};
  var currentSpacingChoice = 'medium';
  var currentBlockPaddingYChoice = 'medium';
  var currentBlockPaddingXChoice = 'medium';
  var currentRadiusStyle = 'soft';
  var radiusBase = {
    soft: radiusPresets.soft || {},
    round: radiusPresets.round || {}
  };

  // Map setting IDs -> CSS var names
  var colorMap = {
    hayden_primary_color: '--color-primary',
    hayden_surface_color: '--color-surface',
    hayden_heading_color: '--color-headings',
    hayden_body_color: '--color-body',

    hayden_footer_color: '--color-footer',
    hayden_footer_text_color: '--color-footer-text',

    hayden_widget_bg_color: '--color-widget-bg',
    hayden_widget_title_color: '--color-widget-heading',
    hayden_widget_text_color: '--color-widget-text',
    hayden_widget_link_color: '--color-widget-link',

    hayden_footer_widget_title_color: '--color-footer-widget-heading',
    hayden_footer_widget_text_color: '--color-footer-widget-text',
    hayden_footer_widget_link_color: '--color-footer-widget-link',

    hayden_card_bg: '--card-bg',
    hayden_card_bg_alt: '--card-bg-alt',
    hayden_card_heading: '--card-heading',
    hayden_card_text: '--card-text',
    hayden_card_text_muted: '--card-text-muted',
    hayden_card_link: '--card-link',

    hayden_nav_link_color: '--color-nav-link',
    hayden_nav_link_hover_color: '--color-nav-link-hover',
    hayden_nav_sub_bg_color: '--color-nav-sub-bg',
    hayden_nav_sub_link_color: '--color-nav-sub-link',
    hayden_nav_sub_hover_bg_color: '--color-nav-sub-hover-bg'
  };

  // Footer widget colours update live when their specific settings change

  function setVar(name, value){
    if (!name || value === undefined || value === null) return;
    document.documentElement.style.setProperty(name, value);
  }

  function updateNavToggleFromSurface(hex){
    if (!hex) return;
    hex = ('' + hex).replace('#','');
    if (hex.length !== 6) return;

    var r = parseInt(hex.substring(0,2), 16);
    var g = parseInt(hex.substring(2,4), 16);
    var b = parseInt(hex.substring(4,6), 16);
    if (isNaN(r) || isNaN(g) || isNaN(b)) return;

    var brightness = (r * 299 + g * 587 + b * 114) / 1000;
    var toggleColor = brightness > 150 ? '#111111' : '#ffffff';
    setVar('--color-nav-toggle', toggleColor);
  }

  function applyRadius(style){
    currentRadiusStyle = style || currentRadiusStyle;
    var p = radiusPresets[style] || radiusPresets.soft;
    if (!p) return;

    setVar('--radius-sm',  p.sm);
    setVar('--radius-md',  p.md);
    setVar('--radius-lg',  p.lg);
    setVar('--radius-xl',  p.xl);
    setVar('--radius-2xl', p['2xl']);
    setVar('--radius-full', p.full);

    // legacy alias
    setVar('--radius-pill', p.full);
  }

  function formatRem(val){
    var num = parseFloat(val);
    if (isNaN(num)) return '0';
    return num.toFixed(3).replace(/\.000$/, '').replace(/(\.\d)00$/, '$1').replace(/(\.\d{2})0$/, '$1');
  }

  function updateRadiusPreset(style, raw){
    var base = radiusBase[style] || radiusPresets[style] || {};
    var base2xl = parseFloat(base['2xl']);
    var val = parseFloat(raw);
    if (isNaN(val) || !base2xl) return;

    var sizes = ['sm', 'md', 'lg', 'xl', '2xl'];
    if (!radiusPresets[style]) radiusPresets[style] = {};

    sizes.forEach(function(size){
      var baseVal = parseFloat(base[size]);
      var ratio = base2xl ? (baseVal / base2xl) : 0;
      radiusPresets[style][size] = formatRem(ratio * val) + 'rem';
    });

    if (base.full) {
      radiusPresets[style].full = base.full;
    }

    applyRadius(currentRadiusStyle);
  }

  function applySpacing(choice){
    currentSpacingChoice = choice || currentSpacingChoice;
    var p = spacingPresets[choice] || spacingPresets.medium;
    if (!p) return;

    setVar('--section-space-mobile',  p.mobile);
    setVar('--section-space-desktop', p.desktop);
  }

  function updateSpacingPreset(key, raw){
    var val = parseFloat(raw);
    if (isNaN(val)) return;
    var rem = val + 'rem';
    if (!spacingPresets[key]) spacingPresets[key] = {};
    spacingPresets[key].mobile = rem;
    spacingPresets[key].desktop = rem;
    applySpacing(currentSpacingChoice);
  }

  function applyBlockPaddingY(choice){
    currentBlockPaddingYChoice = choice || currentBlockPaddingYChoice;
    var p = blockPaddingYPresets[currentBlockPaddingYChoice] || blockPaddingYPresets.medium;
    if (!p) return;

    setVar('--block-padding-y', p.desktop);
  }

  function applyBlockPaddingX(choice){
    currentBlockPaddingXChoice = choice || currentBlockPaddingXChoice;
    var p = blockPaddingXPresets[currentBlockPaddingXChoice] || blockPaddingXPresets.medium;
    if (!p) return;

    setVar('--block-padding-x', p.desktop);
  }

  function updateBlockPaddingPreset(presets, key, raw, cssVarBase){
    var val = parseFloat(raw);
    if (isNaN(val)) return;
    var rem = val + 'rem';
    if (!presets[key]) presets[key] = {};
    presets[key].mobile = rem;
    presets[key].desktop = rem;

    if (cssVarBase) {
      setVar(cssVarBase + '-' + key, rem);
    }
  }

  // Bind all colour settings
  Object.keys(colorMap).forEach(function(settingId){
    var cssVar = colorMap[settingId];

    api(settingId, function(setting){
      var initial = setting.get();
      if (initial) {
        setVar(cssVar, initial);

        if (settingId === 'hayden_surface_color') {
          updateNavToggleFromSurface(initial);
        }

        if (settingId === 'hayden_widget_bg_color') {
          // keep surface-soft in sync with widget bg if your CSS uses it
          setVar('--color-surface-soft', initial);
        }
      }

      setting.bind(function(newVal){
        if (!newVal) return;
        setVar(cssVar, newVal);

        if (settingId === 'hayden_surface_color') {
          updateNavToggleFromSurface(newVal);
        }

        if (settingId === 'hayden_widget_bg_color') {
          setVar('--color-surface-soft', newVal);
        }
      });
    });
  });

  // Radius live preview
  api('hayden_radius_style', function(setting){
    applyRadius(setting.get());
    setting.bind(applyRadius);
  });

  api('hayden_radius_soft_scale', function(setting){
    updateRadiusPreset('soft', setting.get());
    setting.bind(function(newVal){ updateRadiusPreset('soft', newVal); });
  });

  api('hayden_radius_round_scale', function(setting){
    updateRadiusPreset('round', setting.get());
    setting.bind(function(newVal){ updateRadiusPreset('round', newVal); });
  });

  // Spacing live preview
  api('hayden_spacing_scale', function(setting){
    applySpacing(setting.get());
    setting.bind(applySpacing);
  });

  api('hayden_spacing_value_small', function(setting){
    updateSpacingPreset('small', setting.get());
    setting.bind(function(newVal){ updateSpacingPreset('small', newVal); });
  });

  api('hayden_spacing_value_medium', function(setting){
    updateSpacingPreset('medium', setting.get());
    setting.bind(function(newVal){ updateSpacingPreset('medium', newVal); });
  });

  api('hayden_spacing_value_large', function(setting){
    updateSpacingPreset('large', setting.get());
    setting.bind(function(newVal){ updateSpacingPreset('large', newVal); });
  });

  // Block padding Y live preview
  api('hayden_block_padding_y', function(setting){
    applyBlockPaddingY(setting.get());
    setting.bind(applyBlockPaddingY);
  });

  // Block padding X live preview
  api('hayden_block_padding_x', function(setting){
    applyBlockPaddingX(setting.get());
    setting.bind(applyBlockPaddingX);
  });

  api('hayden_block_padding_value_small', function(setting){
    updateBlockPaddingPreset(blockPaddingYPresets, 'small', setting.get(), '--block-padding-y');
    applyBlockPaddingY(currentBlockPaddingYChoice);
    setting.bind(function(newVal){
      updateBlockPaddingPreset(blockPaddingYPresets, 'small', newVal, '--block-padding-y');
      applyBlockPaddingY(currentBlockPaddingYChoice);
    });
  });

  api('hayden_block_padding_value_medium', function(setting){
    updateBlockPaddingPreset(blockPaddingYPresets, 'medium', setting.get(), '--block-padding-y');
    applyBlockPaddingY(currentBlockPaddingYChoice);
    setting.bind(function(newVal){
      updateBlockPaddingPreset(blockPaddingYPresets, 'medium', newVal, '--block-padding-y');
      applyBlockPaddingY(currentBlockPaddingYChoice);
    });
  });

  api('hayden_block_padding_value_large', function(setting){
    updateBlockPaddingPreset(blockPaddingYPresets, 'large', setting.get(), '--block-padding-y');
    applyBlockPaddingY(currentBlockPaddingYChoice);
    setting.bind(function(newVal){
      updateBlockPaddingPreset(blockPaddingYPresets, 'large', newVal, '--block-padding-y');
      applyBlockPaddingY(currentBlockPaddingYChoice);
    });
  });

  api('hayden_block_padding_x_value_small', function(setting){
    updateBlockPaddingPreset(blockPaddingXPresets, 'small', setting.get(), '--block-padding-x');
    applyBlockPaddingX(currentBlockPaddingXChoice);
    setting.bind(function(newVal){
      updateBlockPaddingPreset(blockPaddingXPresets, 'small', newVal, '--block-padding-x');
      applyBlockPaddingX(currentBlockPaddingXChoice);
    });
  });

  api('hayden_block_padding_x_value_medium', function(setting){
    updateBlockPaddingPreset(blockPaddingXPresets, 'medium', setting.get(), '--block-padding-x');
    applyBlockPaddingX(currentBlockPaddingXChoice);
    setting.bind(function(newVal){
      updateBlockPaddingPreset(blockPaddingXPresets, 'medium', newVal, '--block-padding-x');
      applyBlockPaddingX(currentBlockPaddingXChoice);
    });
  });

  api('hayden_block_padding_x_value_large', function(setting){
    updateBlockPaddingPreset(blockPaddingXPresets, 'large', setting.get(), '--block-padding-x');
    applyBlockPaddingX(currentBlockPaddingXChoice);
    setting.bind(function(newVal){
      updateBlockPaddingPreset(blockPaddingXPresets, 'large', newVal, '--block-padding-x');
      applyBlockPaddingX(currentBlockPaddingXChoice);
    });
  });

})(wp.customize);
JS;

    wp_add_inline_script('customize-preview', $js);
});
