/**
 * Theme switcher — light/dark toggle and menu with server-side persistence.
 */
import { warnOnce, resolveHost } from '../core/app-dom.js';
import { postForm } from '../core/app-http.js';

const setTheme = (theme) => {
  document.documentElement.dataset.theme = theme;
  syncThemeAwareImages(theme);
};

/**
 * Swap `src` on every <img data-theme-src> to the attribute matching the
 * current theme — keeps tenant logos (topbar, login hero) in sync with the
 * theme toggle without a full page reload.
 */
const syncThemeAwareImages = (theme) => {
  const key = theme === 'dark' ? 'dark' : 'light';
  const fallback = key === 'dark' ? 'light' : 'dark';
  document.querySelectorAll('[data-theme-src]').forEach((img) => {
    if (!(img instanceof HTMLImageElement)) {
      return;
    }
    const next = img.dataset['src' + key.charAt(0).toUpperCase() + key.slice(1)]
      || img.dataset['src' + fallback.charAt(0).toUpperCase() + fallback.slice(1)]
      || '';
    if (next && img.getAttribute('src') !== next) {
      img.setAttribute('src', next);
    }
  });
};

const isDarkTheme = (theme) => theme === 'dark';

const setIcon = (iconEl, theme) => {
  if (!iconEl) {
    return;
  }
  iconEl.classList.remove('bi-sun-fill', 'bi-moon-stars-fill');
  iconEl.classList.add(isDarkTheme(theme) ? 'bi-moon-stars-fill' : 'bi-sun-fill');
};

const updateTheme = async (source, theme) => {
  const url = source.dataset.themeUrl;
  const csrfKey = source.dataset.csrfKey;
  const csrfToken = source.dataset.csrfToken;
  if (!url || !csrfKey || !csrfToken) {
    return true;
  }
  try {
    await postForm(url, { theme, [csrfKey]: csrfToken });
    return true;
  } catch {
    return false;
  }
};

export function initThemeControls(root = document, options = {}) {
  const host = resolveHost(root);
  const menuSelector = String(options.menuSelector || '[data-theme-menu]').trim() || '[data-theme-menu]';
  const toggleSelector = String(options.toggleSelector || '[data-theme-toggle]').trim() || '[data-theme-toggle]';

  const cleanupFns = [];
  const menu = host.matches?.(menuSelector) ? host : host.querySelector(menuSelector);
  if (menu instanceof HTMLElement) {
    const icon = menu.querySelector('[data-theme-icon]');
    const optionsEls = Array.from(menu.querySelectorAll('[data-theme-option]'));
    if (!optionsEls.length) {
      warnOnce('UI_EL_MISSING', 'Missing theme options', { module: 'theme-toggle' });
    } else {
      let pending = false;
      const getCurrent = () => document.documentElement.dataset.theme || '';
      const setActive = (theme) => {
        optionsEls.forEach((optionEl) => {
          const isActive = optionEl.dataset.themeValue === theme;
          optionEl.classList.toggle('active', isActive);
          if (isActive) {
            optionEl.setAttribute('aria-current', 'true');
          } else {
            optionEl.removeAttribute('aria-current');
          }
        });
      };

      setIcon(icon, getCurrent());
      setActive(getCurrent());

      optionsEls.forEach((optionEl) => {
        const onOptionClick = async (event) => {
          event.preventDefault();
          if (pending) {
            return;
          }
          const next = optionEl.dataset.themeValue || '';
          if (!next) {
            return;
          }
          const current = getCurrent();
          if (next === current) {
            return;
          }
          pending = true;
          setTheme(next);
          setIcon(icon, next);
          setActive(next);
          const ok = await updateTheme(menu, next);
          if (!ok) {
            setTheme(current);
            setIcon(icon, current);
            setActive(current);
          }
          pending = false;
        };
        optionEl.addEventListener('click', onOptionClick);
        cleanupFns.push(() => optionEl.removeEventListener('click', onOptionClick));
      });
    }
  }

  const button = host.matches?.(toggleSelector) ? host : host.querySelector(toggleSelector);
  if (button instanceof HTMLButtonElement) {
    const icon = button.querySelector('i');
    let pending = false;
    const getCurrent = () => document.documentElement.dataset.theme || '';
    setIcon(icon, getCurrent());

    const onButtonClick = async () => {
      if (pending) {
        return;
      }
      const current = getCurrent();
      const next = isDarkTheme(current) ? 'light' : 'dark';
      pending = true;
      setTheme(next);
      setIcon(icon, next);
      const ok = await updateTheme(button, next);
      if (!ok) {
        setTheme(current);
        setIcon(icon, current);
      }
      pending = false;
    };
    button.addEventListener('click', onButtonClick);
    cleanupFns.push(() => button.removeEventListener('click', onButtonClick));
  }

  const destroy = () => {
    cleanupFns.forEach((cleanup) => cleanup());
  };

  return { destroy };
}

export const initThemeToggle = initThemeControls;
