const SummaryManager = (function() {
  const config = {
    refreshInterval: window.config?.cacheDuration || 30000,
    summaryEndpoint: '/json',
    retryDelay: 5000,
    maxRetries: 3,
    requestTimeout: 15000,
    debug: false
  };

  let refreshTimer = null;
  let webSocket = null;
  let fetchRetryCount = 0;
  let lastSuccessfulData = null;

  function updateElement(elementId, value) {
    const element = document.getElementById(elementId);
    if (!element) return false;

    const safeValue = (value !== undefined && value !== null)
      ? value
      : (element.dataset.lastValue || 0);

    element.dataset.lastValue = safeValue;

    if (elementId === 'sent-bids-counter' || elementId === 'recv-bids-counter') {
      const svg = element.querySelector('svg');
      element.textContent = safeValue;
      if (svg) {
        element.insertBefore(svg, element.firstChild);
      }
    } else {
      element.textContent = safeValue;
    }

    if (['offers-counter', 'bid-requests-counter', 'sent-bids-counter',
         'recv-bids-counter', 'swaps-counter', 'network-offers-counter',
         'watched-outputs-counter'].includes(elementId)) {
      element.classList.remove('bg-blue-500', 'bg-gray-400');
      element.classList.add(safeValue > 0 ? 'bg-blue-500' : 'bg-gray-400');
    }

    if (elementId === 'swaps-counter') {
      const swapContainer = document.getElementById('swapContainer');
      if (swapContainer) {
        const isSwapping = safeValue > 0;
        if (isSwapping) {
          swapContainer.innerHTML = document.querySelector('#swap-in-progress-green-template').innerHTML || '';
          swapContainer.style.animation = 'spin 2s linear infinite';
        } else {
          swapContainer.innerHTML = document.querySelector('#swap-in-progress-template').innerHTML || '';
          swapContainer.style.animation = 'none';
        }
      }
    }
    return true;
  }

  function updateUIFromData(data) {
    if (!data) return;

    updateElement('network-offers-counter', data.num_network_offers);
    updateElement('offers-counter', data.num_sent_active_offers);
    updateElement('offers-counter-mobile', data.num_sent_active_offers);
    updateElement('sent-bids-counter', data.num_sent_active_bids);
    updateElement('recv-bids-counter', data.num_recv_active_bids);
    updateElement('bid-requests-counter', data.num_available_bids);
    updateElement('swaps-counter', data.num_swapping);
    updateElement('watched-outputs-counter', data.num_watched_outputs);

    updateTooltips(data);

    const shutdownButtons = document.querySelectorAll('.shutdown-button');
    shutdownButtons.forEach(button => {
      button.setAttribute('data-active-swaps', data.num_swapping);
      if (data.num_swapping > 0) {
        button.classList.add('shutdown-disabled');
        button.setAttribute('data-disabled', 'true');
        button.setAttribute('title', 'Caution: Swaps in progress');
      } else {
        button.classList.remove('shutdown-disabled');
        button.removeAttribute('data-disabled');
        button.removeAttribute('title');
      }
    });
  }

  function updateTooltips(data) {
    debugLog(`updateTooltips called with data:`, data);

    const yourOffersTooltip = document.getElementById('tooltip-your-offers');
    debugLog('Looking for tooltip-your-offers element:', yourOffersTooltip);

    if (yourOffersTooltip) {
      const newContent = `
        <p><b>Total offers:</b> ${data.num_sent_offers || 0}</p>
        <p><b>Active offers:</b> ${data.num_sent_active_offers || 0}</p>
      `;

      const totalParagraph = yourOffersTooltip.querySelector('p:first-child');
      const activeParagraph = yourOffersTooltip.querySelector('p:last-child');

      debugLog('Found paragraphs:', { totalParagraph, activeParagraph });

      if (totalParagraph && activeParagraph) {
        totalParagraph.innerHTML = `<b>Total offers:</b> ${data.num_sent_offers || 0}`;
        activeParagraph.innerHTML = `<b>Active offers:</b> ${data.num_sent_active_offers || 0}`;
        debugLog(`Updated Your Offers tooltip paragraphs: total=${data.num_sent_offers}, active=${data.num_sent_active_offers}`);
      } else {
        yourOffersTooltip.innerHTML = newContent;
        debugLog(`Replaced Your Offers tooltip content: total=${data.num_sent_offers}, active=${data.num_sent_active_offers}`);
      }

      refreshTooltipInstances('tooltip-your-offers', newContent);
    } else {
      debugLog('Your Offers tooltip element not found - checking all tooltip elements');
      const allTooltips = document.querySelectorAll('[id*="tooltip"]');
      debugLog('All tooltip elements found:', Array.from(allTooltips).map(el => el.id));
    }

    const bidsTooltip = document.getElementById('tooltip-bids');
    if (bidsTooltip) {
      const newBidsContent = `
        <p><b>Sent bids:</b> ${data.num_sent_bids || 0} (${data.num_sent_active_bids || 0} active)</p>
        <p><b>Received bids:</b> ${data.num_recv_bids || 0} (${data.num_recv_active_bids || 0} active)</p>
      `;

      const sentParagraph = bidsTooltip.querySelector('p:first-child');
      const recvParagraph = bidsTooltip.querySelector('p:last-child');

      if (sentParagraph && recvParagraph) {
        sentParagraph.innerHTML = `<b>Sent bids:</b> ${data.num_sent_bids || 0} (${data.num_sent_active_bids || 0} active)`;
        recvParagraph.innerHTML = `<b>Received bids:</b> ${data.num_recv_bids || 0} (${data.num_recv_active_bids || 0} active)`;
        debugLog(`Updated Bids tooltip: sent=${data.num_sent_bids}(${data.num_sent_active_bids}), recv=${data.num_recv_bids}(${data.num_recv_active_bids})`);
      } else {
        bidsTooltip.innerHTML = newBidsContent;
        debugLog(`Replaced Bids tooltip content: sent=${data.num_sent_bids}(${data.num_sent_active_bids}), recv=${data.num_recv_bids}(${data.num_recv_active_bids})`);
      }

      refreshTooltipInstances('tooltip-bids', newBidsContent);
    } else {
      debugLog('Bids tooltip element not found');
    }
  }

  function refreshTooltipInstances(tooltipId, newContent) {
    const triggers = document.querySelectorAll(`[data-tooltip-target="${tooltipId}"]`);

    triggers.forEach(trigger => {
      if (trigger._tippy) {
        trigger._tippy.setContent(newContent);
        debugLog(`Updated Tippy instance content for ${tooltipId}`);
      } else {
        if (window.TooltipManager && typeof window.TooltipManager.create === 'function') {
          window.TooltipManager.create(trigger, newContent, {
            placement: trigger.getAttribute('data-tooltip-placement') || 'top'
          });
          debugLog(`Created new Tippy instance for ${tooltipId}`);
        }
      }
    });

    if (window.TooltipManager && typeof window.TooltipManager.refreshTooltip === 'function') {
      window.TooltipManager.refreshTooltip(tooltipId, newContent);
      debugLog(`Refreshed tooltip via TooltipManager for ${tooltipId}`);
    }

    if (window.TooltipManager && typeof window.TooltipManager.initializeTooltips === 'function') {
      CleanupManager.setTimeout(() => {
        window.TooltipManager.initializeTooltips(`[data-tooltip-target="${tooltipId}"]`);
        debugLog(`Re-initialized tooltips for ${tooltipId}`);
      }, 50);
    }
  }

  function debugLog(message) {
    if (config.debug && console && console.log) {
      console.log(`[SummaryManager] ${message}`);
    }
  }

  function cacheSummaryData(data) {
    if (!data) return;

    localStorage.setItem('summary_data_cache', JSON.stringify({
      timestamp: Date.now(),
      data: data
    }));
  }

  function getCachedSummaryData() {
    let cachedData = null;

    cachedData = localStorage.getItem('summary_data_cache');
    if (!cachedData) return null;

    const parsedCache = JSON.parse(cachedData);
    const maxAge = 24 * 60 * 60 * 1000;

    if (Date.now() - parsedCache.timestamp < maxAge) {
      return parsedCache.data;
    }

    return null;
  }

  function fetchSummaryDataWithTimeout() {
    if (window.ApiManager) {
      return window.ApiManager.makeRequest(config.summaryEndpoint, 'GET', {
        'Accept': 'application/json',
        'Cache-Control': 'no-cache',
        'Pragma': 'no-cache'
      });
    }

    const controller = new AbortController();
    const timeoutId = CleanupManager.setTimeout(() => controller.abort(), config.requestTimeout);

    return fetch(config.summaryEndpoint, {
      signal: controller.signal,
      headers: {
        'Accept': 'application/json',
        'Cache-Control': 'no-cache',
        'Pragma': 'no-cache'
      }
    })
    .then(response => {
      if (window.CleanupManager) {
        window.CleanupManager.clearTimeout(timeoutId);
      } else {
        clearTimeout(timeoutId);
      }

      if (!response.ok) {
        throw new Error(`HTTP error! Status: ${response.status}`);
      }

      return response.json();
    })
    .catch(error => {
      if (window.CleanupManager) {
        window.CleanupManager.clearTimeout(timeoutId);
      } else {
        clearTimeout(timeoutId);
      }
      throw error;
    });
  }

  function setupWebSocket() {
    if (webSocket) {
      webSocket.close();
    }

    const wsPort = window.config?.wsPort ||
                   (typeof determineWebSocketPort === 'function' ? determineWebSocketPort() : '11700');

    const wsUrl = "ws://" + window.location.hostname + ":" + wsPort;
    webSocket = new WebSocket(wsUrl);

    webSocket.onopen = () => {
      publicAPI.fetchSummaryData()
        .then(() => {})
        .catch(() => {});
    };

    webSocket.onmessage = (event) => {
      let data;

      try {
        data = JSON.parse(event.data);
      } catch (error) {
        if (window.logger && window.logger.error) {
          window.logger.error('WebSocket message processing error: ' + error.message);
        }
        return;
      }

      if (data.event) {
        const summaryEvents = ['new_offer', 'offer_revoked', 'new_bid', 'bid_accepted', 'swap_completed'];
        if (summaryEvents.includes(data.event)) {
          publicAPI.fetchSummaryData()
            .then(() => {})
            .catch(() => {});
        }

        if (window.NotificationManager && typeof window.NotificationManager.handleWebSocketEvent === 'function') {
          window.NotificationManager.handleWebSocketEvent(data);
        }
      }
    };

    webSocket.onclose = () => {
      CleanupManager.setTimeout(setupWebSocket, 5000);
    };
  }

  function ensureSwapTemplates() {
    if (!document.getElementById('swap-in-progress-template')) {
      const template = document.createElement('template');
      template.id = 'swap-in-progress-template';
      template.innerHTML = document.querySelector('[id^="swapContainer"]')?.innerHTML || '';
      document.body.appendChild(template);
    }

    if (!document.getElementById('swap-in-progress-green-template') &&
        document.querySelector('[id^="swapContainer"]')?.innerHTML) {
      const greenTemplate = document.createElement('template');
      greenTemplate.id = 'swap-in-progress-green-template';
      greenTemplate.innerHTML = document.querySelector('[id^="swapContainer"]')?.innerHTML || '';
      document.body.appendChild(greenTemplate);
    }
  }

  function startRefreshTimer() {
    stopRefreshTimer();

    publicAPI.fetchSummaryData()
      .then(() => {})
      .catch(() => {});

    refreshTimer = CleanupManager.setInterval(() => {
      publicAPI.fetchSummaryData()
        .then(() => {})
        .catch(() => {});
    }, config.refreshInterval);
  }

  function stopRefreshTimer() {
    if (refreshTimer) {
      clearInterval(refreshTimer);
      refreshTimer = null;
    }
  }

  const publicAPI = {
    initialize: function(options = {}) {
      Object.assign(config, options);

      ensureSwapTemplates();

      const cachedData = getCachedSummaryData();
      if (cachedData) {
        updateUIFromData(cachedData);
      }

      if (window.WebSocketManager && typeof window.WebSocketManager.initialize === 'function') {
        const wsManager = window.WebSocketManager;

        if (!wsManager.isConnected()) {
          wsManager.connect();
        }

        wsManager.addMessageHandler('message', (data) => {
          if (data.event) {
            const summaryEvents = ['new_offer', 'offer_revoked', 'new_bid', 'bid_accepted', 'swap_completed'];
            if (summaryEvents.includes(data.event)) {
              this.fetchSummaryData()
                .then(() => {})
                .catch(() => {});
            }

            if (window.NotificationManager && typeof window.NotificationManager.handleWebSocketEvent === 'function') {
              window.NotificationManager.handleWebSocketEvent(data);
            }
          }
        });
      } else {
        setupWebSocket();
      }

      startRefreshTimer();

      if (window.CleanupManager) {
        window.CleanupManager.registerResource('summaryManager', this, (mgr) => mgr.dispose());
      }

      return this;
    },

    fetchSummaryData: function() {
      return fetchSummaryDataWithTimeout()
        .then(data => {
          lastSuccessfulData = data;
          cacheSummaryData(data);
          fetchRetryCount = 0;

          updateUIFromData(data);

          return data;
        })
        .catch(error => {
          if (window.logger && window.logger.error) {
            window.logger.error('Summary data fetch error: ' + error.message);
          }

          if (fetchRetryCount < config.maxRetries) {
            fetchRetryCount++;

            if (window.logger && window.logger.warn) {
              window.logger.warn(`Retrying summary data fetch (${fetchRetryCount}/${config.maxRetries}) in ${config.retryDelay/1000}s`);
            }

            return new Promise(resolve => {
              CleanupManager.setTimeout(() => {
                resolve(this.fetchSummaryData());
              }, config.retryDelay);
            });
          } else {
            const cachedData = lastSuccessfulData || getCachedSummaryData();

            if (cachedData) {
              if (window.logger && window.logger.warn) {
                window.logger.warn('Using cached summary data after fetch failures');
              }
              updateUIFromData(cachedData);
            }

            fetchRetryCount = 0;

            throw error;
          }
        });
    },

    updateTooltips: function(data) {
      updateTooltips(data || lastSuccessfulData);
    },

    updateUI: function(data) {
      updateUIFromData(data || lastSuccessfulData);
    },

    startRefreshTimer: function() {
      startRefreshTimer();
    },

    stopRefreshTimer: function() {
      stopRefreshTimer();
    },

    dispose: function() {
      stopRefreshTimer();

      if (webSocket && webSocket.readyState === WebSocket.OPEN) {
        webSocket.close();
      }

      webSocket = null;
    }
  };

  return publicAPI;
})();

window.SummaryManager = SummaryManager;

document.addEventListener('DOMContentLoaded', function() {
  if (!window.summaryManagerInitialized) {
    window.SummaryManager = SummaryManager.initialize();
    window.summaryManagerInitialized = true;
  }
});

console.log('SummaryManager initialized');
