import { warnOnce } from '../core/app-dom.js';

export function initFilterDrawer(options = {}) {
  const {
    root = document,
    drawerSelector = '[data-filter-drawer]',
    openSelector = '[data-filter-drawer-open]',
    closeSelector = '[data-filter-drawer-close]',
    applySelector = '[data-filter-drawer-apply]',
    resetSelector = '[data-filter-drawer-reset]',
    onOpen = null,
    onClose = null,
    onApply = null,
    onReset = null,
    onDiscard = null
  } = options;

  const host = root && typeof root.querySelector === 'function' ? root : document;
  const drawer = host.querySelector(drawerSelector);
  if (!drawer) {
    warnOnce('UI_EL_MISSING', `Missing filter drawer: ${drawerSelector}`, { module: 'filter-drawer' });
    return null;
  }

  const openButtons = Array.from(host.querySelectorAll(openSelector));
  const closeButtons = Array.from(drawer.querySelectorAll(closeSelector));
  const applyButton = drawer.querySelector(applySelector);
  const resetButton = drawer.querySelector(resetSelector);
  const applyBaseLabel = applyButton ? String(applyButton.textContent || '').trim() : '';
  const openButtonBaseLabels = new WeakMap();

  const panel = drawer.querySelector('[data-filter-drawer-panel]') || drawer;

  let isOpen = false;
  let lockedScrollY = 0;
  let lastTrigger = null;

  if (!drawer.hasAttribute('role')) {
    drawer.setAttribute('role', 'dialog');
  }
  if (!drawer.hasAttribute('aria-modal')) {
    drawer.setAttribute('aria-modal', 'true');
  }
  drawer.setAttribute('aria-hidden', drawer.hidden ? 'true' : 'false');
  if (!panel.hasAttribute('tabindex')) {
    panel.setAttribute('tabindex', '-1');
  }

  const lockPageScroll = () => {
    const body = document.body;
    if (body.dataset.filterDrawerLock === '1') {return;}

    lockedScrollY = window.scrollY || window.pageYOffset || 0;
    body.dataset.filterDrawerLock = '1';
    body.style.position = 'fixed';
    body.style.top = `-${lockedScrollY}px`;
    body.style.left = '0';
    body.style.right = '0';
    body.style.width = '100%';
  };

  const unlockPageScroll = () => {
    const body = document.body;
    if (body.dataset.filterDrawerLock !== '1') {return;}

    body.style.position = '';
    body.style.top = '';
    body.style.left = '';
    body.style.right = '';
    body.style.width = '';
    delete body.dataset.filterDrawerLock;
    window.scrollTo(0, lockedScrollY);
  };

  const getFocusableElements = () => {
    const selectors = [
      'a[href]',
      'area[href]',
      'input:not([type="hidden"]):not([disabled])',
      'select:not([disabled])',
      'textarea:not([disabled])',
      'button:not([disabled])',
      '[tabindex]:not([tabindex="-1"])'
    ];

    return Array.from(panel.querySelectorAll(selectors.join(','))).filter((element) => {
      if (!element) {return false;}
      if (element.getAttribute('aria-hidden') === 'true') {return false;}
      if (element instanceof HTMLElement && element.hidden) {return false;}
      return true;
    });
  };

  const focusFirstField = () => {
    const focusable = getFocusableElements()[0] || panel;
    if (focusable && typeof focusable.focus === 'function') {
      focusable.focus();
    }
  };

  const setOpen = (nextOpen) => {
    isOpen = nextOpen;
    drawer.hidden = !nextOpen;
    drawer.setAttribute('aria-hidden', nextOpen ? 'false' : 'true');
    drawer.classList.toggle('is-open', nextOpen);
    document.body.classList.toggle('filter-drawer-open', nextOpen);
    if (nextOpen) {
      lockPageScroll();
    } else {
      unlockPageScroll();
    }
    openButtons.forEach((button) => {
      button.setAttribute('aria-expanded', nextOpen ? 'true' : 'false');
    });
    if (!nextOpen) {
      if (lastTrigger && typeof lastTrigger.focus === 'function' && document.contains(lastTrigger)) {
        lastTrigger.focus();
      }
      lastTrigger = null;
      if (typeof onClose === 'function') {
        onClose();
      }
      return;
    }
    if (typeof onOpen === 'function') {
      onOpen();
    }
    focusFirstField();
  };

  const open = (trigger = null) => {
    if (isOpen) {return;}
    lastTrigger = trigger && typeof trigger.focus === 'function'
      ? trigger
      : (document.activeElement instanceof HTMLElement ? document.activeElement : null);
    setOpen(true);
  };

  const close = (mode = 'discard') => {
    if (!isOpen) {return;}
    if (mode === 'discard' && typeof onDiscard === 'function') {
      onDiscard();
    }
    setOpen(false);
  };

  openButtons.forEach((button) => {
    button.addEventListener('click', (event) => {
      event.preventDefault();
      open(button);
    });
  });

  closeButtons.forEach((button) => {
    button.addEventListener('click', (event) => {
      event.preventDefault();
      close('discard');
    });
  });

  if (applyButton) {
    applyButton.addEventListener('click', async (event) => {
      event.preventDefault();
      if (applyButton.disabled) {
        return;
      }
      let shouldClose = true;
      if (typeof onApply === 'function') {
        const result = await onApply();
        shouldClose = result !== false;
      }
      if (shouldClose) {
        close('apply');
      }
    });
  }

  if (resetButton) {
    resetButton.addEventListener('click', async (event) => {
      event.preventDefault();
      if (typeof onReset === 'function') {
        await onReset();
      }
    });
  }

  drawer.addEventListener('click', (event) => {
    if (!isOpen) {return;}
    if (!panel.contains(event.target)) {
      close('discard');
    }
  });

  document.addEventListener('keydown', (event) => {
    if (!isOpen) {return;}
    if (event.key === 'Escape') {
      event.preventDefault();
      close('discard');
      return;
    }

    if (event.key !== 'Tab') {return;}
    const focusable = getFocusableElements();
    if (!focusable.length) {
      event.preventDefault();
      panel.focus();
      return;
    }

    const first = focusable[0];
    const last = focusable[focusable.length - 1];
    const active = document.activeElement;
    if (event.shiftKey) {
      if (active === first || !panel.contains(active)) {
        event.preventDefault();
        last.focus();
      }
      return;
    }

    if (active === last) {
      event.preventDefault();
      first.focus();
    }
  });

  const setApplyEnabled = (enabled) => {
    if (!applyButton) {return;}
    const nextEnabled = enabled === true;
    applyButton.disabled = !nextEnabled;
    applyButton.setAttribute('aria-disabled', nextEnabled ? 'false' : 'true');
  };

  const setApplyCount = (count) => {
    if (!applyButton) {return;}
    const parsed = Number.parseInt(String(count ?? '0'), 10);
    const normalized = Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
    applyButton.textContent = normalized > 0
      ? `${applyBaseLabel} (${normalized})`
      : applyBaseLabel;
  };

  const setTriggerCount = (count) => {
    const parsed = Number.parseInt(String(count ?? '0'), 10);
    const normalized = Number.isFinite(parsed) && parsed > 0 ? parsed : 0;

    openButtons.forEach((button) => {
      const baseLabel = openButtonBaseLabels.get(button)
        || String(button.getAttribute('aria-label') || button.textContent || '').trim();

      if (!baseLabel) {return;}
      if (!openButtonBaseLabels.has(button)) {
        openButtonBaseLabels.set(button, baseLabel);
      }

      const nextLabel = normalized > 0 ? `${baseLabel} (${normalized})` : baseLabel;
      const icon = button.querySelector('i');
      if (icon) {
        while (icon.nextSibling) {
          icon.parentNode?.removeChild(icon.nextSibling);
        }
        icon.insertAdjacentText('afterend', ` ${nextLabel}`);
      } else {
        button.textContent = nextLabel;
      }
      button.setAttribute('aria-label', nextLabel);
      button.setAttribute('data-tooltip', nextLabel);
    });
  };

  setApplyEnabled(false);
  setApplyCount(0);
  setTriggerCount(0);

  return {
    open,
    close,
    isOpen: () => isOpen,
    drawer,
    setApplyEnabled,
    setApplyCount,
    setTriggerCount
  };
}
