/* global wp */
(function () {
  if (!window.wp || !wp.blocks || !wp.element) return;

  const { __ } = wp.i18n;
  const { registerBlockType } = wp.blocks;
  const { PanelBody, TextControl, ToggleControl, RangeControl, SelectControl, Button } = wp.components;
  const { useEffect } = wp.element;

  if (!wp.blockEditor) return;
  const { InspectorControls, useBlockProps, PanelColorSettings } = wp.blockEditor;

  // SSR resolver
  const ServerSideRender =
    (wp.serverSideRender && (wp.serverSideRender.default || wp.serverSideRender)) || null;

  // Presets (values copied into chips on change)
  const PRESET_COLORS = {
    'stocktitan-dark': {
      colorBackground:   '#0d0c2d',
      colorTitle:        '#97c9fc',
      colorSummary:      '#dddddd',
      colorDate:         '#dddddd',
      colorSymbol:       '#3586d3',
      colorExchange:     '#dddddd',
      colorTag:          '#ffffff',
      colorTagBackground:'#006e62',
      colorDivider:      '#26294c'
    },
    'nyse': {
      colorBackground:   '#ffffff',
      colorTitle:        '#000000',
      colorSummary:      '#000000',
      colorDate:         '#000000',
      colorSymbol:       '#4299e1',
      colorExchange:     '#000000',
      colorTag:          '#000000',
      colorTagBackground:'#d4e2e8',
      colorDivider:      '#e2e8f0'
    },
    'nasdaq': {
      colorBackground:    '#ffffff',
      colorTitle:         '#08062a',
      colorSummary:       '#313141',
      colorDate:          '#313141',
      colorSymbol:        '#00eb80',
      colorExchange:      '#313141',
      colorTag:           '#313141',
      colorTagBackground: '#f5f5fa',
      colorDivider:       '#e6e6e6'
    },
    'bloomberg': {
      colorBackground:    '#000000',
      colorTitle:         '#f5a623',
      colorSummary:       '#cccccc',
      colorDate:          '#999999',
      colorSymbol:        '#f5a623',
      colorExchange:      '#999999',
      colorTag:           '#f5a623',
      colorTagBackground: '#1a1a1a',
      colorDivider:       '#222222'
    },
    'ft': {
      colorBackground:    '#fff1e5',
      colorTitle:         '#990f3d',
      colorSummary:       '#33302e',
      colorDate:          '#66605a',
      colorSymbol:        '#0d7680',
      colorExchange:      '#66605a',
      colorTag:           '#33302e',
      colorTagBackground: '#f2dfce',
      colorDivider:       '#ccc1b7'
    },
    'theme': {
      // empty = inherit from theme/preset
      colorBackground:'', colorTitle:'', colorSummary:'', colorDate:'',
      colorSymbol:'', colorExchange:'', colorTag:'', colorTagBackground:'', colorDivider:''
    }
  };

  const COLOR_KEYS = [
    'colorBackground','colorTitle','colorSummary','colorDate',
    'colorSymbol','colorExchange','colorTag','colorTagBackground','colorDivider'
  ];

  function setColors(setAttributes, map) {
    const next = {};
    COLOR_KEYS.forEach(k => { next[k] = map[k] ?? ''; });
    setAttributes(next);
  }
  function clearColors(setAttributes) {
    const next = {};
    COLOR_KEYS.forEach(k => { next[k] = ''; });
    setAttributes(next);
  }

function getPresetMap(name) {
  return PRESET_COLORS[name] || PRESET_COLORS.theme;
}

// What the user actually saw: chip value if present, otherwise current preset’s value
function resolveEffectiveColors(attrs) {
  const base = getPresetMap(attrs.preset);
  const out = {};
  COLOR_KEYS.forEach(k => {
    const v = attrs[k];
    out[k] = (v && String(v).trim() !== '')
      ? v
      : (attrs.preset === 'theme' ? '' : (base[k] ?? ''));
  });
  return out;
}

// Full snapshot = preset + effective colors
function makeSnapshot(attrs) {
  return { preset: attrs.preset, colors: resolveEffectiveColors(attrs) };
}
function hasSnapshot(s) {
  return !!(s && typeof s === 'object' && ('preset' in s) && s.colors);
}


registerBlockType('stocktitan-news-feed/news-feed', {
    title: __('StockTitan News Feed', 'stocktitan-news-feed-block'),
    icon: 'rss',
    category: 'widgets',
    supports: { html: false },
    attributes: {
      containerID: { type: 'string', default: 'stockTitanNewsFeed' },

      colorBackground: { type: 'string', default: '' },
      colorDate:       { type: 'string', default: '' },
      colorSymbol:     { type: 'string', default: '' },
      colorExchange:   { type: 'string', default: '' },
      colorTitle:      { type: 'string', default: '' },
      colorTag:        { type: 'string', default: '' },
      colorTagBackground: { type: 'string', default: '' },
      colorSummary:    { type: 'string', default: '' },
      colorDivider:    { type: 'string', default: '' },

      showLogo:    { type: 'boolean', default: true },
      showDate:    { type: 'boolean', default: true },
      showSummary: { type: 'boolean', default: true },
      showTag:     { type: 'boolean', default: true },
      showAttribution: { type: 'boolean', default: false },
      maxItems:    { type: 'number',  default: 10 },
      dateFormat:  { type: 'string',  default: 'date' },

      preset:       { type: 'string',  default: 'theme', enum: ['theme','stocktitan-dark','nyse','nasdaq','bloomberg','ft'] },
      prevSnapshot: { type: 'object',  default: {} },
      colorsHydrated: { type: 'boolean', default: false }

    },
    edit: (props) => {
      const { attributes, setAttributes } = props;
      const blockProps = useBlockProps({ 'data-show-logo': attributes.showLogo ? 'true' : 'false' });

        function onChangePreset(v) {
        // Snapshot what the user currently sees (preset + effective colors)
        const snapshot = makeSnapshot(attributes);
        setAttributes({ preset: v, prevSnapshot: snapshot });

        // Auto-fill chips from the new preset (better UX)
        const presetMap = getPresetMap(v);
        setColors(setAttributes, presetMap);
        }


        function revertToPrevious() {
        const snap = attributes.prevSnapshot;
        if (!hasSnapshot(snap)) return;

        // 1) restore the previous preset immediately
        setAttributes({ preset: snap.preset, prevSnapshot: {} });

        // 2) restore the exact colors the user saw back then (fully populated)
        setColors(setAttributes, snap.colors);
        }

        function usePresetDefaults() {
        // Reapply the CURRENT preset’s default colors to every chip.
        // If preset is 'theme', “defaults” means inherit → chips must be empty.
        if (attributes.preset === 'theme') {
            clearColors(setAttributes);         // inherit theme palette
        } else {
            setColors(setAttributes, getPresetMap(attributes.preset)); // fill chips with preset swatches
        }
        }

      useEffect(() => {
        // Run only once per block instance
        if (attributes.colorsHydrated) return;

        // If preset is 'theme' we can’t resolve theme CSS vars to hex – keep chips empty.
        if (!attributes.preset || attributes.preset === 'theme') {
            setAttributes({ colorsHydrated: true });
            return;
        }

        // Fill only the empty chips from the saved preset
        const presetMap = PRESET_COLORS[attributes.preset] || PRESET_COLORS.theme;
        const updates = {};
        let changed = false;

        COLOR_KEYS.forEach((k) => {
            const v = attributes[k];
            if (!v || String(v).trim() === '') {
            const pv = presetMap[k] ?? '';
            if (pv) { updates[k] = pv; changed = true; }
            }
        });

        if (changed) {
            setAttributes({ ...updates, colorsHydrated: true });
        } else {
            setAttributes({ colorsHydrated: true });
        }
        }, []);

      return (
        div(blockProps,
          wp.element.createElement(InspectorControls, {},

            // ── CONTENT ──────────────────────────────────────────────────
            wp.element.createElement(PanelBody, { title: __('Content', 'stocktitan-news-feed-block'), initialOpen: true },
              wp.element.createElement(ToggleControl, {
                label: __('Show company logo', 'stocktitan-news-feed-block'),
                checked: !!attributes.showLogo,
                onChange: (v) => setAttributes({ showLogo: !!v })
              }),
              wp.element.createElement(ToggleControl, {
                label: __('Show Date', 'stocktitan-news-feed-block'),
                checked: !!attributes.showDate,
                onChange: (v) => setAttributes({ showDate: !!v })
              }),
              attributes.showDate && wp.element.createElement(SelectControl, {
                label: __('Date Format', 'stocktitan-news-feed-block'),
                value: attributes.dateFormat,
                options: [
                  { label: __('Date only', 'stocktitan-news-feed-block'), value: 'date' },
                  { label: __('UTC (formatted)', 'stocktitan-news-feed-block'), value: 'utc' },
                  { label: __('Market hours (New York)', 'stocktitan-news-feed-block'), value: 'ny' },
                  { label: __('Local time (browser)', 'stocktitan-news-feed-block'), value: 'local' }
                ],
                onChange: (v) => setAttributes({ dateFormat: v })
              }),
              wp.element.createElement(ToggleControl, {
                label: __('Show Summary', 'stocktitan-news-feed-block'),
                checked: !!attributes.showSummary,
                onChange: (v) => setAttributes({ showSummary: !!v })
              }),
              wp.element.createElement(ToggleControl, {
                label: __('Show Tags', 'stocktitan-news-feed-block'),
                checked: !!attributes.showTag,
                onChange: (v) => setAttributes({ showTag: !!v })
              }),
              wp.element.createElement(RangeControl, {
                label: __('Max Items', 'stocktitan-news-feed-block'),
                min: 1, max: 50,
                value: attributes.maxItems,
                onChange: (v) => setAttributes({ maxItems: v })
              })
            ),

            // ── STYLE ────────────────────────────────────────────────────
            wp.element.createElement(PanelBody, { title: __('Style', 'stocktitan-news-feed-block'), initialOpen: true },
              wp.element.createElement(SelectControl, {
                label: __('Color Preset', 'stocktitan-news-feed-block'),
                value: attributes.preset,
                options: [
                  { label: __('Theme default', 'stocktitan-news-feed-block'), value: 'theme' },
                  { label: __('StockTitan Dark Mode', 'stocktitan-news-feed-block'), value: 'stocktitan-dark' },
                  { label: __('NYSE (Light)', 'stocktitan-news-feed-block'), value: 'nyse' },
                  { label: __('NASDAQ (Light)', 'stocktitan-news-feed-block'), value: 'nasdaq' },
                  { label: __('Bloomberg Terminal', 'stocktitan-news-feed-block'), value: 'bloomberg' },
                  { label: __('Financial Times', 'stocktitan-news-feed-block'), value: 'ft' }
                ],
                onChange: onChangePreset
              }),
              wp.element.createElement('div', { style: { display: 'flex', gap: 8, marginTop: 8, flexWrap: 'wrap' } },
                wp.element.createElement(Button, {
                  variant: 'secondary',
                  disabled: !hasSnapshot(attributes.prevSnapshot),
                  onClick: revertToPrevious
                }, __('Revert to previous colors & preset', 'stocktitan-news-feed-block')),
                wp.element.createElement(Button, {
                  variant: 'secondary',
                  disabled: (function(){
                    if (attributes.preset === 'theme') {
                      for (var i = 0; i < COLOR_KEYS.length; i++) {
                        var k = COLOR_KEYS[i];
                        if (attributes[k] && String(attributes[k]).trim() !== '') return false;
                      }
                      return true;
                    }
                    var pmap = getPresetMap(attributes.preset);
                    for (var j = 0; j < COLOR_KEYS.length; j++) {
                      var key = COLOR_KEYS[j];
                      var cur = attributes[key] || '';
                      var def = pmap[key] || '';
                      if (cur !== def) return false;
                    }
                    return true;
                  })(),
                  onClick: usePresetDefaults
                }, __('Use current preset defaults', 'stocktitan-news-feed-block'))
              )
            ),

            // ── COLORS ───────────────────────────────────────────────────
            wp.element.createElement(PanelColorSettings, {
              title: __('Colors', 'stocktitan-news-feed-block'),
              initialOpen: false,
              colorSettings: [
                { value: attributes.colorBackground, onChange: (v) => setAttributes({ colorBackground: v || '' }), label: __('Background', 'stocktitan-news-feed-block') },
                { value: attributes.colorTitle,      onChange: (v) => setAttributes({ colorTitle: v || '' }),      label: __('Title', 'stocktitan-news-feed-block') },
                { value: attributes.colorSummary,    onChange: (v) => setAttributes({ colorSummary: v || '' }),    label: __('Summary', 'stocktitan-news-feed-block') },
                { value: attributes.colorDate,       onChange: (v) => setAttributes({ colorDate: v || '' }),       label: __('Date', 'stocktitan-news-feed-block') },
                { value: attributes.colorSymbol,     onChange: (v) => setAttributes({ colorSymbol: v || '' }),     label: __('Symbol', 'stocktitan-news-feed-block') },
                { value: attributes.colorExchange,   onChange: (v) => setAttributes({ colorExchange: v || '' }),   label: __('Exchange', 'stocktitan-news-feed-block') },
                { value: attributes.colorTag,        onChange: (v) => setAttributes({ colorTag: v || '' }),        label: __('Tag (text)', 'stocktitan-news-feed-block') },
                { value: attributes.colorTagBackground, onChange: (v) => setAttributes({ colorTagBackground: v || '' }), label: __('Tag (background)', 'stocktitan-news-feed-block') },
                { value: attributes.colorDivider,    onChange: (v) => setAttributes({ colorDivider: v || '' }),    label: __('Divider line', 'stocktitan-news-feed-block') }
              ]
            }),

            // ── ADVANCED ─────────────────────────────────────────────────
            wp.element.createElement(PanelBody, { title: __('Advanced', 'stocktitan-news-feed-block'), initialOpen: false },
              wp.element.createElement(TextControl, {
                label: __('Container ID', 'stocktitan-news-feed-block'),
                help: __('Slug-like: letters, numbers, dashes/underscores', 'stocktitan-news-feed-block'),
                value: attributes.containerID,
                onChange: (v) => setAttributes({ containerID: v })
              }),
              wp.element.createElement(ToggleControl, {
                label: __('Show attribution link', 'stocktitan-news-feed-block'),
                help: __('Adds a small "Powered by StockTitan" link below the list', 'stocktitan-news-feed-block'),
                checked: !!attributes.showAttribution,
                onChange: (v) => setAttributes({ showAttribution: !!v })
              })
            )
          ),
          ServerSideRender && wp.element.createElement(ServerSideRender, {
            block: 'stocktitan-news-feed/news-feed',
            attributes: attributes
          })
        )
      );
    },
    save: () => null
  });

  function div(props, ...children) { return wp.element.createElement('div', props, ...children); }
  
  // Ensure local-time conversion works inside the block editor canvas (including iframes)
  (function ensureEditorLocalizer(){
    try {
      if (typeof window === 'undefined') return;
      if (window.__stnfEditorLocInit) return; window.__stnfEditorLocInit = 1;

      function parseISOToDate(iso){
        if (!iso || typeof iso !== 'string') return null;
        var d = new Date(iso);
        if (!isNaN(d)) return d;
        if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?$/.test(iso)) {
          var d2 = new Date(iso + 'Z');
          if (!isNaN(d2)) return d2;
        }
        return null;
      }
      function buildIntlOptions(df, tf){
        var opts = { year: 'numeric' };
        if (/F/.test(df)) opts.month = 'long';
        else if (/M/.test(df)) opts.month = 'short';
        else if (/m/.test(df)) opts.month = '2-digit';
        else if (/n/.test(df)) opts.month = 'numeric';
        if (/d/.test(df)) opts.day = '2-digit';
        else if (/j/.test(df)) opts.day = 'numeric';
        if (/y/.test(df) && !/Y/.test(df)) opts.year = '2-digit';
        if (tf) {
          if (/H/.test(tf)) { opts.hourCycle = 'h23'; opts.hour = '2-digit'; }
          else if (/G/.test(tf)) { opts.hourCycle = 'h23'; opts.hour = 'numeric'; }
          else if (/h/.test(tf)) { opts.hourCycle = 'h12'; opts.hour = '2-digit'; }
          else if (/g/.test(tf)) { opts.hourCycle = 'h12'; opts.hour = 'numeric'; }
          if (/i/.test(tf)) opts.minute = '2-digit';
          if (/s/.test(tf)) opts.second = '2-digit';
        }
        return opts;
      }
      function getDocLocale(doc){
        try {
          var l = (doc && doc.documentElement && doc.documentElement.lang) ? doc.documentElement.lang : '';
          if (l && typeof l === 'string') return l;
        } catch(e){}
        try { return (doc && doc.defaultView && doc.defaultView.navigator && doc.defaultView.navigator.language) || navigator.language || 'en'; } catch(e) { return 'en'; }
      }

      function toText(d, df, tf, doc){
        try { var locale = getDocLocale(doc || document); var fmt = new Intl.DateTimeFormat(locale, buildIntlOptions(df||'', tf||'')); return fmt.format(d); }
        catch(e){ return d.toLocaleString(); }
      }

      function localizeIn(doc){
        if (!doc) return;
        doc.querySelectorAll('.stnf time[data-localize="1"]:not([data-localized])').forEach(function(el){
          var iso = el.getAttribute('datetime');
          var d = parseISOToDate(iso);
          if (!d) return;
          var df = el.getAttribute('data-df') || '';
          var tf = el.getAttribute('data-tf') || '';
          var tgt = el.querySelector('.stnf-date-txt') || el;
          tgt.textContent = toText(d, df, tf, doc);
          el.setAttribute('data-localized','1');
        });
      }

      function setupDoc(doc){
        try {
          localizeIn(doc);
          var MO = (doc.defaultView && doc.defaultView.MutationObserver) ? doc.defaultView.MutationObserver : MutationObserver;
          var mo = new MO(function(muts){
            for (var i=0;i<muts.length;i++) {
              var m = muts[i];
              if (m.addedNodes && m.addedNodes.length) { localizeIn(doc); break; }
            }
          });
          mo.observe(doc.body || doc, { childList: true, subtree: true });
        } catch(e) {}
      }

      function scanIframes(){
        document.querySelectorAll('iframe').forEach(function(ifr){
          try {
            var doc = ifr.contentDocument;
            if (doc && !doc.__stnfLocAttached) { doc.__stnfLocAttached = 1; setupDoc(doc); }
          } catch(e){}
        });
      }

      function onReady(fn){ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fn); else fn(); }
      onReady(function(){
        setupDoc(document);
        scanIframes();
        try { var moTop = new MutationObserver(scanIframes); moTop.observe(document.body, { childList: true, subtree: true }); } catch(e){}
      });
    } catch(e){}
  })();
})();
