/**
 * Admin Currency Picker — searchable dropdown with flags.
 *
 * Usage:
 *   <button type="button" class="crtoday-currency-picker-btn" data-crtoday-picker="true" data-target="input-id" data-value="USD">
 *     <img class="crtoday-picker-flag" src="..." width="20" height="20" alt="" />
 *     <span class="crtoday-picker-code">USD</span>
 *     <span class="crtoday-picker-chevron">▾</span>
 *   </button>
 *   <input type="hidden" id="input-id" value="USD" />
 *
 * The picker reads `window.crtodayAdminCurrencies` (array of {code, name, flag, group})
 * and `window.crtodayFlagBaseUrl` for flag images path.
 *
 * @since 0.1.0
 */
(function () {
  'use strict';

  const PICKER_UI = window.crtodayCurrencyPickerI18n || {};
  const GROUP_LABELS = PICKER_UI.groupLabels || {};
  const GROUP_ORDER = PICKER_UI.groupOrder || [];
  const UI_LABELS = PICKER_UI.labels || {};

  /* ================================================================
   * State
   * ================================================================ */

  let activeDropdown = null;
  let activeBtn = null;

  /* ================================================================
   * Init
   * ================================================================ */

  function init() {
    document.querySelectorAll('[data-crtoday-picker="true"]').forEach(bindPicker);
    document.querySelectorAll('[data-crtoday-multi-picker="true"]').forEach(bindMultiPicker);
    document.addEventListener('click', handleOutsideClick);
    window.addEventListener('keydown', handleEscapeKey);
  }

  function bindPicker(btn) {
    btn.addEventListener('click', function (e) {
      e.preventDefault();
      e.stopPropagation();
      toggleDropdown(btn);
    });
  }

  /* ================================================================
   * Dropdown
   * ================================================================ */

  function toggleDropdown(btn) {
    if (activeBtn === btn && activeDropdown) {
      closeDropdown();
      return;
    }
    closeDropdown();
    openDropdown(btn);
  }

  function openDropdown(btn) {
    const currencies = window.crtodayAdminCurrencies || [];
    const flagBaseUrl = window.crtodayFlagBaseUrl || '';
    const currentCode = btn.dataset.value || '';

    const dropdown = document.createElement('div');
    dropdown.className = 'crtoday-picker-dropdown';
    dropdown.setAttribute('role', 'listbox');
    dropdown.setAttribute('aria-label', UI_LABELS.selectCurrency || '');

    /* Search */
    const searchWrap = document.createElement('div');
    searchWrap.className = 'crtoday-picker-search-wrap';
    const searchInput = document.createElement('input');
    searchInput.type = 'text';
    searchInput.className = 'crtoday-picker-search';
    searchInput.placeholder = UI_LABELS.searchCurrency || '';
    searchInput.setAttribute('aria-label', UI_LABELS.searchCurrencies || '');
    searchWrap.appendChild(searchInput);
    dropdown.appendChild(searchWrap);

    /* List container */
    const listEl = document.createElement('div');
    listEl.className = 'crtoday-picker-list';
    dropdown.appendChild(listEl);

    /* Render function */
    function renderOptions(filter) {
      listEl.innerHTML = '';
      const query = (filter || '').toLowerCase();
      const filtered = query
        ? currencies.filter(function (c) {
            return c.code.toLowerCase().includes(query) || c.name.toLowerCase().includes(query);
          })
        : currencies;

      /* Group currencies */
      GROUP_ORDER.forEach(function (gKey) {
        const items = filtered.filter(function (c) {
          return c.group === gKey;
        });
        if (items.length === 0) return;

        const group = document.createElement('div');
        group.className = 'crtoday-picker-group';
        group.dataset.group = gKey;

        const label = document.createElement('div');
        label.className = 'crtoday-picker-group-label';
        label.textContent = GROUP_LABELS[gKey] || gKey;
        group.appendChild(label);

        items.forEach(function (info) {
          const opt = createOption(info, currentCode, flagBaseUrl);
          group.appendChild(opt);
        });

        listEl.appendChild(group);
      });
    }

    renderOptions('');
    searchInput.addEventListener('input', function () {
      renderOptions(searchInput.value);
    });

    /* Keyboard navigation */
    let focusedIdx = -1;
    function getFocusableOptions() {
      return Array.from(listEl.querySelectorAll('.crtoday-picker-option'));
    }

    function moveFocus(delta) {
      const options = getFocusableOptions();
      if (options.length === 0) return;
      focusedIdx = Math.max(0, Math.min(options.length - 1, focusedIdx + delta));
      options.forEach(function (o, i) {
        o.classList.toggle('crtoday-picker-option-focused', i === focusedIdx);
      });
      options[focusedIdx].scrollIntoView({ block: 'nearest' });
    }

    dropdown.addEventListener('keydown', function (e) {
      if (e.key === 'ArrowDown') {
        e.preventDefault();
        moveFocus(1);
      } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        moveFocus(-1);
      } else if (e.key === 'Enter') {
        e.preventDefault();
        const options = getFocusableOptions();
        if (focusedIdx >= 0 && focusedIdx < options.length) {
          selectCurrency(btn, options[focusedIdx].dataset.code);
        }
      } else if (e.key === 'Escape') {
        e.preventDefault();
        closeDropdown();
        btn.focus();
      }
    });

    listEl.addEventListener('click', function (e) {
      const option = e.target.closest('.crtoday-picker-option');
      if (option && option.dataset.code) {
        selectCurrency(btn, option.dataset.code);
      }
    });

    dropdown.addEventListener('click', function (e) {
      e.stopPropagation();
    });

    /* Position */
    document.body.appendChild(dropdown);
    positionDropdown(btn, dropdown);

    activeDropdown = dropdown;
    activeBtn = btn;
    btn.setAttribute('aria-expanded', 'true');

    requestAnimationFrame(function () {
      searchInput.focus();
    });

    /* Close on scroll (except within dropdown list) */
    function onScroll(e) {
      if (activeDropdown && !activeDropdown.contains(e.target)) {
        closeDropdown();
      }
    }
    window.addEventListener('scroll', onScroll, true);
    dropdown._removeScrollListener = function () {
      window.removeEventListener('scroll', onScroll, true);
    };
  }

  function closeDropdown() {
    if (activeDropdown) {
      if (activeDropdown._removeScrollListener) {
        activeDropdown._removeScrollListener();
      }
      activeDropdown.remove();
      activeDropdown = null;
    }
    if (activeBtn) {
      activeBtn.setAttribute('aria-expanded', 'false');
      activeBtn = null;
    }
  }

  function positionDropdown(btn, dropdown) {
    const rect = btn.getBoundingClientRect();
    const gap = 4;

    dropdown.style.position = 'fixed';
    dropdown.style.left = rect.left + 'px';
    dropdown.style.width = Math.max(rect.width, 280) + 'px';

    const spaceBelow = window.innerHeight - rect.bottom - gap;
    const ddHeight = 320;

    if (spaceBelow >= ddHeight || spaceBelow >= rect.top - gap) {
      dropdown.style.top = rect.bottom + gap + 'px';
      dropdown.style.bottom = 'auto';
    } else {
      dropdown.style.top = 'auto';
      dropdown.style.bottom = window.innerHeight - rect.top + gap + 'px';
    }
  }

  function createOption(info, currentCode, flagBaseUrl) {
    const opt = document.createElement('div');
    opt.className = 'crtoday-picker-option';
    opt.setAttribute('role', 'option');
    opt.setAttribute('aria-selected', info.code === currentCode ? 'true' : 'false');
    opt.dataset.code = info.code;

    if (info.code === currentCode) {
      opt.classList.add('crtoday-picker-option-selected');
    }

    /* Flag */
    if (flagBaseUrl && info.flag) {
      const flagWrap = document.createElement('span');
      flagWrap.className = 'crtoday-picker-flag-wrap';
      const img = document.createElement('img');
      img.className = 'crtoday-picker-flag';
      img.src = flagBaseUrl + info.flag + '.webp';
      img.alt = '';
      img.width = 20;
      img.height = 20;
      img.loading = 'lazy';
      img.decoding = 'async';
      flagWrap.appendChild(img);
      opt.appendChild(flagWrap);
    }

    /* Code */
    const code = document.createElement('span');
    code.className = 'crtoday-picker-opt-code';
    code.textContent = info.code;
    opt.appendChild(code);

    /* Name */
    const name = document.createElement('span');
    name.className = 'crtoday-picker-opt-name';
    name.textContent = info.name;
    opt.appendChild(name);

    /* Checkmark for selected */
    if (info.code === currentCode) {
      const check = document.createElement('span');
      check.className = 'crtoday-picker-check';
      check.innerHTML = '✓';
      opt.appendChild(check);
    }

    return opt;
  }

  function selectCurrency(btn, code) {
    const currencies = window.crtodayAdminCurrencies || [];
    const flagBaseUrl = window.crtodayFlagBaseUrl || '';
    const info = currencies.find(function (c) {
      return c.code === code;
    });

    if (!info) {
      closeDropdown();
      return;
    }

    /* Update button */
    btn.dataset.value = code;
    const flagImg = btn.querySelector('.crtoday-picker-flag');
    const codeSpan = btn.querySelector('.crtoday-picker-code');

    if (flagImg && flagBaseUrl && info.flag) {
      flagImg.src = flagBaseUrl + info.flag + '.webp';
    }
    if (codeSpan) {
      codeSpan.textContent = code;
    }

    /* Update hidden input */
    const targetId = btn.dataset.target;
    if (targetId) {
      const input = document.getElementById(targetId);
      if (input) {
        input.value = code;
        input.dispatchEvent(new Event('input', { bubbles: true }));
        input.dispatchEvent(new Event('change', { bubbles: true }));
      }
    }

    closeDropdown();
    btn.focus();
  }

  /* ================================================================
   * Multi-select picker
   * ================================================================ */

  function bindMultiPicker(container) {
    const addBtn = container.querySelector('.crtoday-multi-picker-add');
    const tagsWrap = container.querySelector('.crtoday-multi-picker-tags');
    const hiddenInput = container.querySelector('input[type="hidden"]');

    if (!addBtn || !tagsWrap || !hiddenInput) return;

    /* Bind tag remove buttons */
    tagsWrap.addEventListener('click', function (e) {
      const removeBtn = e.target.closest('.crtoday-tag-remove');
      if (removeBtn) {
        const tag = removeBtn.closest('.crtoday-tag');
        if (tag && tag.dataset.code) {
          removeFromMulti(container, tag.dataset.code);
        }
      }
    });

    /* Bind add button */
    addBtn.addEventListener('click', function (e) {
      e.preventDefault();
      e.stopPropagation();
      toggleMultiDropdown(container, addBtn);
    });
  }

  function toggleMultiDropdown(container, addBtn) {
    if (activeBtn === addBtn && activeDropdown) {
      closeDropdown();
      return;
    }
    closeDropdown();
    openMultiDropdown(container, addBtn);
  }

  function openMultiDropdown(container, addBtn) {
    const currencies = window.crtodayAdminCurrencies || [];
    const flagBaseUrl = window.crtodayFlagBaseUrl || '';

    const dropdown = document.createElement('div');
    dropdown.className = 'crtoday-picker-dropdown';
    dropdown.setAttribute('role', 'listbox');
    dropdown.setAttribute('aria-label', UI_LABELS.selectCurrencies || '');
    dropdown.setAttribute('aria-multiselectable', 'true');

    /* Search */
    const searchWrap = document.createElement('div');
    searchWrap.className = 'crtoday-picker-search-wrap';
    const searchInput = document.createElement('input');
    searchInput.type = 'text';
    searchInput.className = 'crtoday-picker-search';
    searchInput.placeholder = UI_LABELS.searchCurrency || '';
    searchInput.setAttribute('aria-label', UI_LABELS.searchCurrencies || '');
    searchWrap.appendChild(searchInput);
    dropdown.appendChild(searchWrap);

    /* List container */
    const listEl = document.createElement('div');
    listEl.className = 'crtoday-picker-list';
    dropdown.appendChild(listEl);

    /* Render function */
    function renderOptions(filter) {
      const currentSelected = getMultiValue(container);
      listEl.innerHTML = '';
      const query = (filter || '').toLowerCase();
      const filtered = query
        ? currencies.filter(function (c) {
            return c.code.toLowerCase().includes(query) || c.name.toLowerCase().includes(query);
          })
        : currencies;

      GROUP_ORDER.forEach(function (gKey) {
        const items = filtered.filter(function (c) {
          return c.group === gKey;
        });
        if (items.length === 0) return;

        const group = document.createElement('div');
        group.className = 'crtoday-picker-group';
        group.dataset.group = gKey;

        const label = document.createElement('div');
        label.className = 'crtoday-picker-group-label';
        label.textContent = GROUP_LABELS[gKey] || gKey;
        group.appendChild(label);

        items.forEach(function (info) {
          const isSelected = currentSelected.includes(info.code);
          const opt = createMultiOption(info, isSelected, flagBaseUrl);
          group.appendChild(opt);
        });

        listEl.appendChild(group);
      });
    }

    renderOptions('');
    searchInput.addEventListener('input', function () {
      renderOptions(searchInput.value);
    });

    /* Keyboard navigation */
    let focusedIdx = -1;
    function getFocusableOptions() {
      return Array.from(listEl.querySelectorAll('.crtoday-picker-option'));
    }

    function moveFocus(delta) {
      const options = getFocusableOptions();
      if (options.length === 0) return;
      focusedIdx = Math.max(0, Math.min(options.length - 1, focusedIdx + delta));
      options.forEach(function (o, i) {
        o.classList.toggle('crtoday-picker-option-focused', i === focusedIdx);
      });
      options[focusedIdx].scrollIntoView({ block: 'nearest' });
    }

    dropdown.addEventListener('keydown', function (e) {
      if (e.key === 'ArrowDown') {
        e.preventDefault();
        moveFocus(1);
      } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        moveFocus(-1);
      } else if (e.key === 'Enter') {
        e.preventDefault();
        const options = getFocusableOptions();
        if (focusedIdx >= 0 && focusedIdx < options.length) {
          toggleMultiCurrency(container, options[focusedIdx].dataset.code, renderOptions, searchInput.value);
        }
      } else if (e.key === 'Escape') {
        e.preventDefault();
        closeDropdown();
        addBtn.focus();
      }
    });

    listEl.addEventListener('click', function (e) {
      const option = e.target.closest('.crtoday-picker-option');
      if (option && option.dataset.code) {
        toggleMultiCurrency(container, option.dataset.code, renderOptions, searchInput.value);
      }
    });

    dropdown.addEventListener('click', function (e) {
      e.stopPropagation();
    });

    /* Position */
    document.body.appendChild(dropdown);
    positionDropdown(addBtn, dropdown);

    activeDropdown = dropdown;
    activeBtn = addBtn;
    addBtn.setAttribute('aria-expanded', 'true');

    requestAnimationFrame(function () {
      searchInput.focus();
    });

    /* Close on scroll */
    function onScroll(e) {
      if (activeDropdown && !activeDropdown.contains(e.target)) {
        closeDropdown();
      }
    }
    window.addEventListener('scroll', onScroll, true);
    dropdown._removeScrollListener = function () {
      window.removeEventListener('scroll', onScroll, true);
    };
  }

  function createMultiOption(info, isSelected, flagBaseUrl) {
    const opt = document.createElement('div');
    opt.className = 'crtoday-picker-option';
    if (isSelected) {
      opt.classList.add('crtoday-picker-option-selected');
    }
    opt.setAttribute('role', 'option');
    opt.setAttribute('aria-selected', isSelected ? 'true' : 'false');
    opt.dataset.code = info.code;

    /* Checkbox indicator */
    const checkbox = document.createElement('span');
    checkbox.className = 'crtoday-picker-checkbox';
    checkbox.innerHTML = isSelected ? '☑' : '☐';
    opt.appendChild(checkbox);

    /* Flag */
    if (flagBaseUrl && info.flag) {
      const flagWrap = document.createElement('span');
      flagWrap.className = 'crtoday-picker-flag-wrap';
      const img = document.createElement('img');
      img.className = 'crtoday-picker-flag';
      img.src = flagBaseUrl + info.flag + '.webp';
      img.alt = '';
      img.width = 20;
      img.height = 20;
      img.loading = 'lazy';
      img.decoding = 'async';
      flagWrap.appendChild(img);
      opt.appendChild(flagWrap);
    }

    /* Code */
    const code = document.createElement('span');
    code.className = 'crtoday-picker-opt-code';
    code.textContent = info.code;
    opt.appendChild(code);

    /* Name */
    const name = document.createElement('span');
    name.className = 'crtoday-picker-opt-name';
    name.textContent = info.name;
    opt.appendChild(name);

    return opt;
  }

  function getMultiValue(container) {
    const hiddenInput = container.querySelector('input[type="hidden"]');
    if (!hiddenInput || !hiddenInput.value) return [];
    return hiddenInput.value.split(',').map(function (s) {
      return s.trim();
    }).filter(Boolean);
  }

  function setMultiValue(container, codes) {
    const hiddenInput = container.querySelector('input[type="hidden"]');
    const tagsWrap = container.querySelector('.crtoday-multi-picker-tags');
    const flagBaseUrl = window.crtodayFlagBaseUrl || '';
    const currencies = window.crtodayAdminCurrencies || [];

    if (hiddenInput) {
      hiddenInput.value = codes.join(',');
      hiddenInput.dispatchEvent(new Event('input', { bubbles: true }));
      hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));
    }

    if (tagsWrap) {
      /* Remove old tags except the add button */
      Array.from(tagsWrap.querySelectorAll('.crtoday-tag')).forEach(function (tag) {
        tag.remove();
      });

      /* Add new tags before the add button */
      const addBtn = tagsWrap.querySelector('.crtoday-multi-picker-add');
      codes.forEach(function (code) {
        const info = currencies.find(function (c) {
          return c.code === code;
        });
        const tag = document.createElement('span');
        tag.className = 'crtoday-tag';
        tag.dataset.code = code;

        if (info && info.flag && flagBaseUrl) {
          const flagImg = document.createElement('img');
          flagImg.className = 'crtoday-tag-flag';
          flagImg.src = flagBaseUrl + info.flag + '.webp';
          flagImg.alt = '';
          flagImg.width = 16;
          flagImg.height = 16;
          tag.appendChild(flagImg);
        }

        const codeSpan = document.createElement('span');
        codeSpan.textContent = code;
        tag.appendChild(codeSpan);

        const removeBtn = document.createElement('button');
        removeBtn.type = 'button';
        removeBtn.className = 'crtoday-tag-remove';
        const removePattern = UI_LABELS.removeCurrencyPattern || '%s';
        removeBtn.setAttribute('aria-label', removePattern.replace('%s', code));
        removeBtn.innerHTML = '×';
        tag.appendChild(removeBtn);

        if (addBtn) {
          tagsWrap.insertBefore(tag, addBtn);
        } else {
          tagsWrap.appendChild(tag);
        }
      });
    }
  }

  function toggleMultiCurrency(container, code, rerender, filter) {
    const current = getMultiValue(container);
    const idx = current.indexOf(code);

    if (idx >= 0) {
      current.splice(idx, 1);
    } else {
      current.push(code);
    }

    setMultiValue(container, current);
    if (rerender) {
      rerender(filter);
    }
  }

  function removeFromMulti(container, code) {
    const current = getMultiValue(container);
    const idx = current.indexOf(code);
    if (idx >= 0) {
      current.splice(idx, 1);
      setMultiValue(container, current);
    }
  }

  /* ================================================================
   * Event handlers
   * ================================================================ */

  function handleOutsideClick(e) {
    if (activeDropdown && !activeDropdown.contains(e.target) && activeBtn !== e.target) {
      closeDropdown();
    }
  }

  function handleEscapeKey(e) {
    if (e.key === 'Escape' && activeDropdown) {
      closeDropdown();
    }
  }

  /* ================================================================
   * Run
   * ================================================================ */

  /* Expose bindPicker so dynamically-created picker buttons can be bound. */
  window.crtodayBindPicker = bindPicker;

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
})();
