(() => {
  function init() {
    const table = document.getElementById('asset-table');
    if (!table || table.dataset.columnManagerReady === '1') return;
    table.dataset.columnManagerReady = '1';

    const scroll = document.getElementById('asset-table-scroll');
    const topScroll = document.getElementById('asset-table-scroll-top');
    const topInner = topScroll?.firstElementChild;
    const dialog = document.getElementById('column-settings-dialog');
    const list = document.getElementById('column-settings-list');
    const openButton = document.getElementById('column-settings-button');
    const showAllButton = document.getElementById('show-all-columns');
    const resetButton = document.getElementById('reset-columns');
    const menu = document.getElementById('column-context-menu');
    const hideMenuButton = document.getElementById('context-hide-column');
    const openMenuButton = document.getElementById('context-open-columns');

    const keyBase = table.dataset.storageKey || 'asset-columns-all';
    const hiddenKey = `${keyBase}-hidden`;
    const styleId = `asset-column-visibility-${keyBase.replace(/[^a-zA-Z0-9_-]/g, '-')}`;
    let contextField = null;
    let resizeFrame = 0;
    let lastContainerWidth = -1;

    const headers = () =>
      [...table.querySelectorAll('thead tr:first-child th[data-field]')];

    const fieldLabel = field => {
      const th = table.querySelector(
        `thead tr:first-child th[data-field="${CSS.escape(field)}"]`
      );
      return th?.dataset.label || th?.textContent?.trim() || field;
    };

    const allFields = () => headers().map(th => th.dataset.field);

    function getHidden() {
      try {
        const value = JSON.parse(window.AssetBrowserState?.get(hiddenKey) || '[]');
        return Array.isArray(value) ? value : [];
      } catch (_) {
        return [];
      }
    }

    function setHidden(fields) {
      window.AssetBrowserState?.set(hiddenKey, JSON.stringify([...new Set(fields)]));
    }

    function columnWidth(header) {
      const configured = Number.parseInt(header.dataset.columnWidth || '', 10);
      return Number.isFinite(configured) && configured > 0 ? configured : 180;
    }

    function visibleTableWidth(hidden) {
      const fieldWidth = headers().reduce(
        (sum, header) =>
          hidden.has(header.dataset.field) ? sum : sum + columnWidth(header),
        0
      );
      const fixedWidth = Number.parseInt(table.dataset.fixedColumnWidth || '224', 10);
      return Math.max(640, fieldWidth + fixedWidth);
    }

    function updateTopScrollbar(tableWidth) {
      if (!scroll || !topScroll || !topInner) return;
      topInner.style.width = `${tableWidth}px`;
      topScroll.hidden = tableWidth <= scroll.clientWidth + 1;
    }

    function buildList() {
      if (!list) return;
      const hidden = new Set(getHidden());
      const fragment = document.createDocumentFragment();

      allFields().forEach(field => {
        const label = document.createElement('label');
        label.className = 'checkbox-option';

        const input = document.createElement('input');
        input.type = 'checkbox';
        input.checked = !hidden.has(field);
        input.addEventListener('change', () =>
          input.checked ? showField(field) : hideField(field)
        );

        const span = document.createElement('span');
        span.textContent = fieldLabel(field);
        label.append(input, span);
        fragment.appendChild(label);
      });

      list.replaceChildren(fragment);
    }

    function applyHidden() {
      const hidden = new Set(getHidden());
      let style = document.getElementById(styleId);
      if (!style) {
        style = document.createElement('style');
        style.id = styleId;
        document.head.appendChild(style);
      }

      style.textContent = [...hidden]
        .map(field =>
          `#asset-table [data-field="${CSS.escape(field)}"]{display:none!important}`
        )
        .join('\n');

      const tableWidth = visibleTableWidth(hidden);
      table.style.width = `${tableWidth}px`;
      table.style.minWidth = `${tableWidth}px`;
      table.dataset.calculatedWidth = String(tableWidth);
      buildList();

      requestAnimationFrame(() => updateTopScrollbar(tableWidth));
      window.dispatchEvent(new Event('asset-table-columns-changed'));
    }

    function hideField(field) {
      if (!field) return;
      const hidden = getHidden();
      const visibleFields = allFields().filter(item => !hidden.includes(item));
      if (visibleFields.length <= 1 || hidden.includes(field)) return;
      hidden.push(field);
      setHidden(hidden);
      applyHidden();
    }

    function showField(field) {
      setHidden(getHidden().filter(item => item !== field));
      applyHidden();
    }

    let syncing = false;
    scroll?.addEventListener('scroll', () => {
      if (syncing || !topScroll) return;
      syncing = true;
      topScroll.scrollLeft = scroll.scrollLeft;
      syncing = false;
    }, { passive: true });

    topScroll?.addEventListener('scroll', () => {
      if (syncing || !scroll) return;
      syncing = true;
      scroll.scrollLeft = topScroll.scrollLeft;
      syncing = false;
    }, { passive: true });

    headers().forEach(th => {
      th.addEventListener('contextmenu', event => {
        event.preventDefault();
        contextField = th.dataset.field;
        if (!menu) return;
        menu.hidden = false;
        const maxX = window.innerWidth - menu.offsetWidth - 8;
        const maxY = window.innerHeight - menu.offsetHeight - 8;
        menu.style.left = `${Math.max(8, Math.min(event.clientX, maxX))}px`;
        menu.style.top = `${Math.max(8, Math.min(event.clientY, maxY))}px`;
      });
    });

    hideMenuButton?.addEventListener('click', () => {
      hideField(contextField);
      menu.hidden = true;
    });

    openMenuButton?.addEventListener('click', () => {
      menu.hidden = true;
      buildList();
      dialog?.showModal();
    });

    document.addEventListener('click', event => {
      if (menu && !menu.contains(event.target)) menu.hidden = true;
    });

    document.addEventListener('keydown', event => {
      if (event.key === 'Escape' && menu) menu.hidden = true;
    });

    openButton?.addEventListener('click', () => {
      buildList();
      dialog?.showModal();
    });

    showAllButton?.addEventListener('click', () => {
      setHidden([]);
      applyHidden();
    });

    resetButton?.addEventListener('click', () => {
      setHidden([]);
      window.AssetBrowserState?.remove?.(keyBase);
      applyHidden();
      window.location.reload();
    });

    function scheduleScrollbarUpdate() {
      cancelAnimationFrame(resizeFrame);
      resizeFrame = requestAnimationFrame(() => {
        const tableWidth = Number.parseInt(table.dataset.calculatedWidth || '0', 10);
        if (tableWidth) updateTopScrollbar(tableWidth);
      });
    }

    window.addEventListener('resize', scheduleScrollbarUpdate, { passive: true });

    if ('ResizeObserver' in window && scroll) {
      const resizeObserver = new ResizeObserver(entries => {
        const width = Math.round(entries[0]?.contentRect?.width || 0);
        if (width === lastContainerWidth) return;
        lastContainerWidth = width;
        scheduleScrollbarUpdate();
      });
      resizeObserver.observe(scroll);
    }

    window.addEventListener('asset-table-content-reloaded', event => {
      if (!event.detail?.table || event.detail.table === table) {
        applyHidden();
      }
    });

    applyHidden();
    window.dispatchEvent(new CustomEvent('asset-table-columns-ready', {
      detail: { table }
    }));
  }

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