/*
 * =========================================
 *  PRIMEBRIDGE MODAL SYSTEM
 * =========================================
 *  Reusable modal dialog UI component.
 *  Backward-compatible with existing
 *  window.closeTxnModal pattern (notifications.js).
 * =========================================
 *
 *  Exposes PrimeBridge.modal via IIFE
 *  with open / close / isOpen / setContent / setTitle.
 *
 *  Dependencies: None (Vanilla JS)
 *  Load before: events.js, notifications.js
 * =========================================
 */

(function () {
  /* ------------------------------------------------------------------ */
  /*  Global namespace                                                   */
  /* ------------------------------------------------------------------ */

  window.PrimeBridge = window.PrimeBridge || {};

  /* ------------------------------------------------------------------ */
  /*  Private references (cached after first DOM access)                 */
  /* ------------------------------------------------------------------ */

  /** @type {HTMLElement|null} */
  var _overlay = null;

  /** @type {HTMLElement|null} */
  var _content = null;

  /** @type {HTMLElement|null} */
  var _bodyEl = null;

  /** @type {HTMLElement|null} */
  var _titleEl = null;

  /** @type {boolean} */
  var _initialized = false;

  /** @type {boolean} */
  var _open = false;

  /** @type {function(Event):void} */
  var _escHandler = null;
  /** @private Escape HTML entities for safe innerHTML injection. */
  var _esc = (function () {
    var _map = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
    return function (s) {
      return String(s).replace(/[&<>"']/g, function (c) { return _map[c]; });
    };
  })();

  /** @type {function(Event):void} */
  var _overlayHandler = null;

  /* ------------------------------------------------------------------ */
  /*  DOM  Template (created once on first open / init)                  */
  /* ------------------------------------------------------------------ */

  /**
   * Modal DOM structure:
   *
   *  <div id="txnModal" class="modal-overlay hidden">
   *    <div class="modal-content">
   *      <div class="modal-header">
   *        <h3 id="txnTitle">Transaction</h3>
   *        <button onclick="PrimeBridge.modal.close()"
   *                class="modal-close">&times;</button>
   *      </div>
   *      <div class="modal-body" id="txnBody"></div>
   *    </div>
   *  </div>
   */

  /**
   * Build the modal DOM fragment and inject it into the page.
   * @returns {void}
   */
  function _buildDOM() {
    var overlay = document.createElement('div');
    overlay.id = 'txnModal';
    overlay.className = 'modal-overlay hidden';

    var content = document.createElement('div');
    content.className = 'modal-content';

    var header = document.createElement('div');
    header.className = 'modal-header';

    var title = document.createElement('h3');
    title.id = 'txnTitle';
    title.textContent = 'Transaction';

    var closeBtn = document.createElement('button');
    closeBtn.className = 'modal-close';
    closeBtn.innerHTML = '&times;';
    closeBtn.setAttribute('onclick', 'PrimeBridge.modal.close()');
    closeBtn.setAttribute('aria-label', 'Close modal');

    header.appendChild(title);
    header.appendChild(closeBtn);

    var body = document.createElement('div');
    body.id = 'txnBody';
    body.className = 'modal-body';

    content.appendChild(header);
    content.appendChild(body);
    overlay.appendChild(content);

    document.body.appendChild(overlay);

    // Cache references
    _overlay = overlay;
    _content = content;
    _bodyEl = body;
    _titleEl = title;
  }

  /**
   * Try to grab existing DOM nodes from the page so we play nice with
   * Blade-provided markup.  Falls back to _buildDOM() if any are missing.
   * @returns {void}
   */
  function _ensureDOM() {
    if (_initialized) return;

    var overlay = document.getElementById('txnModal');
    var body = document.getElementById('txnBody');
    var title = document.getElementById('txnTitle');

    if (overlay && body && title) {
      // Use existing markup from Blade
      _overlay = overlay;
      _bodyEl = body;
      _titleEl = title;
      _content = overlay.querySelector('.modal-content');
    } else {
      _buildDOM();
    }

    _initialized = true;
  }

  /* ------------------------------------------------------------------ */
  /*  Event wiring (lazy — attached on first open)                       */
  /* ------------------------------------------------------------------ */

  /**
   * Attach global keyboard + overlay event listeners.
   * Safe to call multiple times.
   * @returns {void}
   */
  function _bindEvents() {
    if (_escHandler) return; // already bound

    // --- ESC key -------------------------------------------------------
    _escHandler = function (e) {
      if (e.key === 'Escape' || e.key === 'Esc') {
        PrimeBridge.modal.close();
      }
    };

    // --- Overlay backdrop click ----------------------------------------
    _overlayHandler = function (e) {
      // Only close when the overlay backdrop itself is clicked,
      // not when clicks bubble from .modal-content children.
      if (e.target === _overlay) {
        PrimeBridge.modal.close();
      }
    };

    document.addEventListener('keydown', _escHandler);
    _overlay.addEventListener('click', _overlayHandler);
  }

  /**
   * Tear down event listeners (called on close).
   * @returns {void}
   */
  function _unbindEvents() {
    if (_escHandler) {
      document.removeEventListener('keydown', _escHandler);
      _escHandler = null;
    }
    if (_overlayHandler) {
      _overlay.removeEventListener('click', _overlayHandler);
      _overlayHandler = null;
    }
  }

  /* ------------------------------------------------------------------ */
  /*  Body scroll lock helpers                                           */
  /* ------------------------------------------------------------------ */

  function _lockScroll() {
    document.body.style.overflow = 'hidden';
  }

  function _unlockScroll() {
    document.body.style.overflow = '';
  }

  /* ------------------------------------------------------------------ */
  /*  Public API                                                         */
  /* ------------------------------------------------------------------ */

  PrimeBridge.modal = {

    /**
     * Open the modal with the given HTML content and optional title.
     *
     * @param {string}  contentHtml - HTML string for the modal body.
     * @param {string}  [titleText='Transaction'] - Modal title text.
     * @returns {void}
     *
     * @example
     *   PrimeBridge.modal.open('<p>Hello world</p>', 'Greeting');
     */
    open: function (contentHtml, titleText) {
      _ensureDOM();

      // Prevent duplicate opens — check actual DOM state so we stay
      // in sync even if notifications.js opened the modal directly.
      if (!_overlay.classList.contains('hidden')) return;

      _bindEvents();

      // Set content
      if (contentHtml !== undefined && contentHtml !== null) {
        _bodyEl.innerHTML = contentHtml;
      }

      // Set title (default: 'Transaction' to match Blade default)
      if (titleText !== undefined && titleText !== null) {
        _titleEl.textContent = String(titleText);
      } else {
        _titleEl.textContent = 'Transaction';
      }

      // Show overlay
      _overlay.classList.remove('hidden');
      _open = true;

      // Lock body scroll
      _lockScroll();
    },

    /**
     * Close the modal.
     * @returns {void}
     */
    close: function () {
      if (!_initialized) return;

      // Check actual DOM state so close() works even when the modal was
      // opened by notifications.js's openTxnModal (which bypasses our flag).
      if (_overlay.classList.contains('hidden')) return;

      // Hide overlay
      _overlay.classList.add('hidden');
      _open = false;

      // Restore scroll
      _unlockScroll();

      // Remove listeners so they don't accumulate
      _unbindEvents();
    },

    /**
     * Check whether the modal is currently open.
     * @returns {boolean}
     */
    isOpen: function () {
      return _open;
    },

    /**
     * Replace the modal body content without affecting visibility.
     * @param {string} html - New HTML content for the modal body.
     * @returns {void}
     *
     * @example
     *   PrimeBridge.modal.setContent('<p>Updated content</p>');
     */
    setContent: function (html) {
      _ensureDOM();
      _bodyEl.innerHTML = html !== undefined && html !== null ? html : '';
    },

    /**
     * Replace the modal title text without affecting visibility.
     * @param {string} text - New title text.
     * @returns {void}
     *
     * @example
     *   PrimeBridge.modal.setTitle('Error Details');
     */
    setTitle: function (text) {
      _ensureDOM();
      _titleEl.textContent = text !== undefined && text !== null ? String(text) : 'Transaction';
    },

    /**
     * Render transaction data into a polished modal layout.
     *
     * Produces a summary section (dot + name + amount + country + status)
     * followed by labeled detail rows. Designed for live notification events.
     *
     * @param {Object} data — Event data with fields: fullName, amount,
     *   country, type, timeAgo, + optional pair, sector, instrument, etc.
     * @param {string} [dotColor] — CSS color for the summary dot.
     *   Auto-detects from type if omitted.
     * @param {string} [statusColor] — CSS color for status text.
     *   Auto-detects from type if omitted.
     * @returns {void}
     *
     * @example
     *   PrimeBridge.modal.renderTransaction({
     *     fullName: 'James S.',
     *     amount: '$12,500',
     *     country: '🇳🇬 Nigeria',
     *     type: 'deposit',
     *     timeAgo: '5 mins ago',
     *     method: 'BTC'
     *   });
     */
    renderTransaction: function (data, dotColor, statusColor) {
      if (!data || typeof data !== 'object') return;

      _ensureDOM();

      // Auto-detect colors from type
      var typeMap = {
        deposit:           ['#22c55e', '#22c55e'],
        withdrawal:        ['#ef4444', '#ef4444'],
        registration:      ['#a78bfa', '#a78bfa'],
        managedPortfolio:  ['#f59e0b', '#f59e0b'],
        selfTrading:       ['#06b6d4', '#06b6d4'],
        sectors:           ['#ec4899', '#ec4899'],
        capitalInstruments: ['#eab308', '#eab308'],
        bonus:             ['#6366f1', '#6366f1']
      };
      var colors = typeMap[data.type] || ['#6366f1', '#6366f1'];
      dotColor = dotColor || colors[0];
      statusColor = statusColor || colors[1];

      var name = data.fullName || data.user || 'Unknown User';
      var amount = data.amount || '';
      var country = data.country || data.flag || '';

      // Resolve missing flags via country registry
      if (country && PrimeBridge.countries && PrimeBridge.countries.ready()) {
        country = PrimeBridge.countries.display(country);
      }

      var timeAgo = data.timeAgo || 'just now';

      var html = '';

      // --- Summary ---
      html += '<div class="txn-summary">';
      html += '  <div class="txn-summary-avatar">' + (PrimeBridge.avatar ? PrimeBridge.avatar.svg(name) : '<div class="txn-summary-dot" style="background:' + dotColor + '"></div>') + '</div>';
      html += '  <div class="txn-summary-info">';
      html += '    <div class="txn-summary-name">' + _esc(name) + '</div>';
      if (amount) html += '    <div class="txn-summary-amount">' + _esc(amount) + '</div>';
      if (country) html += '    <div class="txn-summary-country">' + _esc(country) + '</div>';
      html += '  </div>';
      html += '  <div class="txn-summary-status" style="color:' + statusColor + '">● ' + _esc(timeAgo) + '</div>';
      html += '</div>';

      // --- Detail Rows ---
      html += '<div class="txn-body">';

      // Type-specific field sets — each type carries its identity
      // If paymentMethod data exists, inject its detail rows via strict schema
      var pmRows = [];
      if (data.paymentMethod && PrimeBridge.paymentMethods && data.paymentMethodFields) {
        pmRows = PrimeBridge.paymentMethods.getModalRows(
          data.paymentMethod.id,
          data.type,
          data.paymentMethodFields
        );
      }
      var typeFields = {
        deposit:        [['USER', name], ['COUNTRY', country], ['AMOUNT', amount]].concat(pmRows),
        withdrawal:     [['USER', name], ['COUNTRY', country], ['AMOUNT', amount]].concat(pmRows),
        registration:   [['USER', name], ['COUNTRY', country], ['PLAN', data.package], ['REFERRAL', data.referral]],
        managedPortfolio:[['USER', name], ['COUNTRY', country], ['AMOUNT', amount], ['PORTFOLIO', data.package], ['ALLOCATION', data.allocation]],
        selfTrading:    [['USER', name], ['COUNTRY', country], ['AMOUNT', amount], ['PAIR', data.pair], ['POSITION', data.position], ['LEVERAGE', data.leverage], ['PROFIT', data.profit]],
        sectors:        [['USER', name], ['COUNTRY', country], ['AMOUNT', amount], ['SECTOR', data.sector], ['ALLOCATION', data.allocation]],
        capitalInstruments: [['USER', name], ['COUNTRY', country], ['AMOUNT', amount], ['INSTRUMENT', data.instrument], ['YIELD', data.profit]],
        bonus:          [['USER', name], ['COUNTRY', country], ['AMOUNT', amount], ['CREDIT', data.method], ['WAGERING', data.wagering]]
      };

      var rows = typeFields[data.type] || typeFields.deposit;

      // Build rows: type-specific fields first, then TX ID at bottom
      var allRows = [];
      for (var ri = 0; ri < rows.length; ri++) {
        if (rows[ri][1]) allRows.push(rows[ri]);
      }
      allRows.push(['TX ID', data.txnId || '—']);
      allRows.push(['TYPE', '<span style="color:' + statusColor + '">' + _esc(data.type) + '</span>']);
      allRows.push(['STATUS', '<span style="color:' + statusColor + '">● Confirmed · ' + _esc(timeAgo) + '</span>']);

      for (var i = 0; i < allRows.length; i++) {
        html +=
          '<div class="txn-row">' +
            '<span class="txn-label">' + allRows[i][0] + '</span>' +
            '<span class="txn-value">' + allRows[i][1] + '</span>' +
          '</div>';
      }

      html += '</div>';

      _bodyEl.innerHTML = html;
    },

    /**
     * Render a data object into the modal body as key-value rows.
     *
     * Given a data object and an array of allowed keys, renders each
     * matching key-value pair as a styled row within the modal body.
     * UPDATED to use the new txn-label / txn-value CSS classes.
     *
     * @param {Object} data — The data object to render.
     * @param {string[]} [allowedKeys] — Array of key names to display.
     * @param {string} [statusText] — Footer status text.
     * @returns {void}
     *
     * @example
     *   PrimeBridge.modal.renderData({
     *     type: 'deposit',
     *     amount: '$5,234',
     *     name: 'Alex Johnson',
     *     country: '🇺🇸 USA'
     *   });
     */
    renderData: function (data, allowedKeys, statusText) {
      if (!data || typeof data !== 'object') return;

      _ensureDOM();

      var keys = allowedKeys || [
        'type', 'amount', 'package', 'pair', 'sector',
        'instrument', 'bonus', 'name', 'country', 'flag',
        'method', 'user', 'status', 'profit', 'position', 'leverage'
      ];

      var html = '<div class="txn-body">';

      for (var key in data) {
        if (data.hasOwnProperty(key) && keys.indexOf(key) !== -1) {
          var label = key.charAt(0).toUpperCase() + key.slice(1);
          html +=
            '<div class="txn-row">' +
              '<span class="txn-label">' + label + '</span>' +
              '<span class="txn-value">' + data[key] + '</span>' +
            '</div>';
        }
      }

      html +=
        '<div class="txn-row">' +
          '<span class="txn-label">Status</span>' +
          '<span class="txn-value">' + (statusText || 'Live Transaction Verified') + '</span>' +
        '</div>';

      html += '</div>';

      _bodyEl.innerHTML = html;
    }
  };

})();
