/**
 * GM Player Privacy Selector Menu
 * 
 * A settings menu entry that allows the GM to select a player and view their privacy settings.
 * This provides read-only access to all players' privacy panels.
 * 
 * Extends ApplicationV2 to be compatible with FoundryVTT's registerMenu API.
 */

import { PlayerPrivacyPanel } from '../player/PlayerPrivacyPanel.js';

// Conditional base class for test compatibility
// At module load time in tests, foundry is undefined → fallback class is used
const _AppBase =
  typeof foundry !== 'undefined' &&
  foundry.applications?.api?.ApplicationV2
    ? foundry.applications.api.ApplicationV2
    : class _FallbackApp {
        static DEFAULT_OPTIONS = {};
        get rendered() { return this._rendered ?? false; }
        set rendered(v) { this._rendered = v; }
        get element() { return this._element ?? null; }
        set element(v) { this._element = v; }
        async render() { this._rendered = true; }
        async close() { this._rendered = false; }
        _onRender() {}
        _onClose() {}
      };

/**
 * Static references to DI dependencies (set during module initialization).
 */
let _adapter = null;
let _playerPrivacyManager = null;
let _portraitFallbackHandler = null;

/**
 * Flag to track if dependencies have been initialized.
 */
let _isInitialized = false;

/**
 * Initialize static dependencies.
 * Called once during module initialization.
 * @param {import('../../foundry/FoundryAdapter.js').FoundryAdapter} adapter
 * @param {import('../../core/PlayerPrivacyManager.js').PlayerPrivacyManager} playerPrivacyManager
 * @param {import('../../core/PortraitFallbackHandler.js').PortraitFallbackHandler} [portraitFallbackHandler]
 */
export function initGMPlayerPrivacySelector(adapter, playerPrivacyManager, portraitFallbackHandler = null) {
  if (!adapter || typeof adapter !== 'object') {
    throw new TypeError('initGMPlayerPrivacySelector: adapter is required');
  }
  if (!playerPrivacyManager || typeof playerPrivacyManager !== 'object') {
    throw new TypeError('initGMPlayerPrivacySelector: playerPrivacyManager is required');
  }
  
  _adapter = adapter;
  _playerPrivacyManager = playerPrivacyManager;
  _portraitFallbackHandler = portraitFallbackHandler;
  _isInitialized = true;
  
  // Register the settings menu
  _registerSettingsMenu();
}

/**
 * Check if dependencies have been initialized.
 * @returns {boolean}
 */
export function isInitialized() {
  return _isInitialized;
}

/**
 * Register the GM-only settings menu.
 */
function _registerSettingsMenu() {
  _adapter.settings.registerMenu('scrying-pool', 'gmPlayerPrivacySelector', {
    name: 'SCRYING_POOL.Settings.GMPlayerPrivacySelector',
    label: 'SCRYING_POOL.Settings.GMPlayerPrivacySelectorLabel',
    hint: 'SCRYING_POOL.Settings.GMPlayerPrivacySelectorHint',
    icon: 'fa-solid fa-users',
    type: GMPlayerPrivacySelectorMenu,
    restricted: true, // GM only
  });
}

/**
 * GM Player Privacy Selector Menu class.
 * When instantiated by Foundry, it creates a user selector dialog.
 * Extends ApplicationV2 (or fallback) for Foundry settings menu compatibility.
 */
export class GMPlayerPrivacySelectorMenu extends _AppBase {
  static DEFAULT_OPTIONS = {
    id: 'scrying-pool-gm-privacy-selector',
    classes: ['scrying-pool', 'gm-privacy-selector'],
    window: {
      title: 'Player Privacy Selector',
      resizable: false,
      width: 400,
      height: 'auto',
    },
    position: {},
  };

  /**
   * @param {object} [options] - Foundry options (unused, but required by settings menu API)
   */
  constructor(options = {}) {
    super(options);
    this._adapter = _adapter;
    this._playerPrivacyManager = _playerPrivacyManager;
    this._options = options;
    this._rendered = false;
  }

  /**
   * Get rendered state.
   * @returns {boolean}
   */
  get rendered() {
    return this._rendered;
  }

  /**
   * Get the element.
   * @returns {HTMLElement|null}
   */
  get element() {
    return this._element ?? null;
  }

  /**
   * Set the element.
   * @param {HTMLElement} v - The element to set
   */
  set element(v) {
    this._element = v;
  }

  /**
   * Store references to created panels for cleanup.
   * @type {PlayerPrivacyPanel[]}
   */
  _panels = [];

  /**
   * Store reference to close button element.
   * @type {HTMLElement|null}
   */
  _closeButton = null;

  /**
   * Render the user selection dialog.
   * @returns {Promise<void>}
   */
  async render() {
    // Prevent double rendering
    if (this._rendered) {
      return;
    }
    
    try {
      if (!_isInitialized) {
        throw new Error('GMPlayerPrivacySelector: Dependencies not initialized. Call initGMPlayerPrivacySelector first.');
      }
      
      const users = this._adapter.users.all?.() ?? [];
      
      // Escape user data to prevent XSS
      const escapeHtml = (str) => {
        if (str == null) return '';
        const div = document.createElement('div');
        div.textContent = String(str);
        return div.innerHTML;
      };
    
      const html = `
      <div class="sp-gm-privacy-selector">
        <div class="sp-dialog-header">
          <h2>${this._adapter.i18n.localize('SCRYING_POOL.Settings.GMPlayerPrivacySelector')}</h2>
          <button type="button" class="sp-close-button" aria-label="Close">
            <i class="fas fa-times"></i>
          </button>
        </div>
        <p>${this._adapter.i18n.localize('SCRYING_POOL.Settings.GMPlayerPrivacySelectorHint')}</p>
        <div class="sp-user-list">
          ${users.map(user => {
            const name = escapeHtml(user.name ?? '');
            const id = escapeHtml(user.id ?? '');
            const role = user.isGM ? 'GM' : 'Player';
            return `
            <div class="sp-user-item" 
                 data-user-id="${id}"
                 data-tooltip="${name} — ${role}">
              <span class="sp-user-name">${name}</span>
              <span class="sp-user-role">${role}</span>
            </div>
          `;}).join('')}
        </div>
      </div>
    `;
    
      // Create a dialog element
      this._element = document.createElement('div');
      this._element.innerHTML = html;
      this._element.classList.add('scrying-pool', 'gm-privacy-selector-dialog');
      
      // Use CSS classes instead of inline styles
      this._element.style.position = 'fixed';
      this._element.style.top = '50%';
      this._element.style.left = '50%';
      this._element.style.transform = 'translate(-50%, -50%)';
      this._element.style.zIndex = '1000';
      
      // Add to DOM
      if (document.body) {
        document.body.appendChild(this._element);
      }
    
      // Cache close button and add handler
      this._closeButton = this._element.querySelector('.sp-close-button');
      if (this._closeButton) {
        this._closeButton.addEventListener('click', () => this.close());
      }
      
      // Add click handlers for each user
      this._element.querySelectorAll('.sp-user-item').forEach(item => {
        item.addEventListener('click', () => {
          const userId = item.dataset.userId;
          if (userId) {
            this._openPrivacyPanel(userId);
          }
        });
      });
    
      this._rendered = true;
    } catch (err) {
      console.error('[ScryingPool] GMPlayerPrivacySelector render failed:', err);
      throw err;
    }
  }

  /**
   * Close the dialog and clean up resources.
   * @returns {Promise<void>}
   */
  async close() {
    // Remove all event listeners by cloning and replacing the element
    if (this._element && this._element.parentNode) {
      this._element.parentNode.removeChild(this._element);
    }
    
    // Clean up panel references
    for (const panel of this._panels) {
      try {
        await panel.close();
      } catch (err) {
        console.error('[ScryingPool] Error closing privacy panel:', err);
      }
    }
    this._panels = [];
    
    this._closeButton = null;
    this._element = null;
    this._rendered = false;
  }

  /**
   * Open the PlayerPrivacyPanel for a specific user.
   * @param {string} userId - The user ID to view
   */
  _openPrivacyPanel(userId) {
    if (!_isInitialized) {
      console.error('[ScryingPool] GMPlayerPrivacySelector: Cannot open panel, dependencies not initialized');
      return;
    }
    
    if (!userId || typeof userId !== 'string') {
      console.error('[ScryingPool] GMPlayerPrivacySelector: Invalid userId');
      return;
    }
    
    try {
      const panel = new PlayerPrivacyPanel(
        this._adapter,
        this._playerPrivacyManager,
        userId,
        _portraitFallbackHandler
      );
      this._panels.push(panel);
      panel.render(true);
    } catch (err) {
      console.error('[ScryingPool] GMPlayerPrivacySelector: Failed to create privacy panel:', err);
    }
  }
}

// Legacy export for backwards compatibility
export { GMPlayerPrivacySelectorMenu as GMPlayerPrivacySelector };
