/**
 * Cascading multi-select — filters child options based on parent selection.
 */
import { getMultiSelectInstance } from './app-multiselect-init.js';
import { warnOnce, resolveHost } from '../core/app-dom.js';

const parseValueList = (value) =>
  String(value || '')
    .split(',')
    .map((item) => item.trim())
    .filter(Boolean);

const setDisabledState = (option, disabled) => {
  option.dataset.disabled = disabled ? '1' : '0';
  option.classList.toggle('is-disabled', disabled);
  option.setAttribute('aria-disabled', disabled ? 'true' : 'false');
  option.style.pointerEvents = disabled ? 'none' : '';
};

const toggleSelectAll = (instance, disabled) => {
  const selectAll = instance?.element?.querySelector('.multi-select-all');
  if (!selectAll) {return;}
  selectAll.classList.toggle('is-disabled', disabled);
  selectAll.setAttribute('aria-disabled', disabled ? 'true' : 'false');
  selectAll.style.pointerEvents = disabled ? 'none' : '';
};

export const initMultiSelectCascade = ({
  parent,
  child,
  map = {},
  mode = 'disable',
  clearInvalid = true,
  root = document,
} = {}) => {
  const host = resolveHost(root);
  const parentInput = typeof parent === 'string' ? host.querySelector(parent) : parent;
  const childInput = typeof child === 'string' ? host.querySelector(child) : child;
  if (!parentInput || !childInput) {
    if (!parentInput) {
      warnOnce('UI_EL_MISSING', `Missing multiselect parent: ${parent}`, { module: 'multiselect-cascade' });
    }
    if (!childInput) {
      warnOnce('UI_EL_MISSING', `Missing multiselect child: ${child}`, { module: 'multiselect-cascade' });
    }
    return { destroy: () => {} };
  }

  const childInstance = getMultiSelectInstance(childInput, host);
  if (!childInstance) {
    warnOnce('UI_INIT_MISSING', 'Missing multiselect instance for child', { module: 'multiselect-cascade' });
    return { destroy: () => {} };
  }

  const apply = () => {
    const selectedParents = parseValueList(parentInput.value);
    const allowAll = selectedParents.length === 0;
    const allowed = new Set();

    if (!allowAll) {
      selectedParents.forEach((id) => {
        const entries = map[id] || [];
        entries.forEach((entry) => allowed.add(String(entry)));
      });
    }

    if (clearInvalid && !allowAll) {
      const selected = childInstance.selectedValues || [];
      selected.forEach((value) => {
        if (!allowed.has(String(value))) {
          childInstance.unselect(value);
        }
      });
    }

    const options = childInstance.element.querySelectorAll('.multi-select-option');
    let disabledCount = 0;
    options.forEach((option) => {
      const isAllowed = allowAll || allowed.has(String(option.dataset.value || ''));
      const disabled = mode === 'disable' ? !isAllowed : false;
      if (disabled) {disabledCount += 1;}
      setDisabledState(option, disabled);
    });

    toggleSelectAll(childInstance, disabledCount > 0);
  };

  parentInput.addEventListener('change', apply);
  apply();

  return {
    destroy: () => {
      parentInput.removeEventListener('change', apply);
      const options = childInstance.element.querySelectorAll('.multi-select-option');
      options.forEach((option) => setDisabledState(option, false));
      toggleSelectAll(childInstance, false);
    },
  };
};
