window.uiAPI = {
  displayResults,
  displayError,
};

// Function to handle time and duration conversion
function displayResults(data) {
  const resultsElement = document.getElementById('results');
  const downloadContainer = document.getElementById('download-container');

  // Apply time conversion if enabled
  const convertTime = document.getElementById('convertTimeOption').checked;
  const replaceKeys = document.getElementById('replaceKeysOption').checked;
  let displayData = data;

  // Use the original data stored in appState for processing
  if (convertTime || replaceKeys) {
    const timezone = document.getElementById('timezoneSelect').value;
    // Use the original unprocessed data for processing
    const sourceData = window.appState.originalData || data;
    displayData = window.backendAPI.processTimestamps(
      structuredClone(sourceData),
      timezone
    );
  } else if (window.appState.originalData) {
    // If no processing is selected, use original data
    displayData = structuredClone(window.appState.originalData);
  }

  // Format the data
  let formattedData = '';
  if (window.appState.outputFormat === 'yaml') {
    formattedData = window.backendAPI.jsonToYAML(displayData);
    document.getElementById('downloadJson').textContent = 'Download YAML Data';
  } else {
    formattedData = JSON.stringify(displayData, null, 2);
    document.getElementById('downloadJson').textContent = 'Download JSON Data';
  }

  resultsElement.textContent = formattedData;
  resultsElement.style.display = 'block';
  downloadContainer.style.display = 'block';
}

// Helper function to display errors
function displayError(message) {
  const errorElement = document.getElementById('error');
  const loadingElement = document.getElementById('loading');
  const resultsElement = document.getElementById('results');

  errorElement.textContent = message;
  loadingElement.style.display = 'none';

  // Clear previous results to ensure they can be redrawn
  resultsElement.style.display = 'none';
  resultsElement.textContent = '';

  // Keep tutorial hidden if previously dismissed
  if (window.appState.tutorialDismissed) {
    document.querySelectorAll('.tutorial').forEach((element) => {
      element.style.display = 'none';
    });
  }
}

// Configure client-side logging settings
const clientLogger = {
  // Control how much we log to reduce spam
  settings: {
    enableDetailedNetworkLogs: false, // Set to false to reduce network logging
    logScrollEvents: false, // Disable scroll event logging
    logMouseMovements: false, // Disable mouse movement logging
    logFocusEvents: false, // Disable focus event logging
    logResizeEvents: false, // Disable resize event logging
    minimumInactivityTime: 300000, // Only log inactivity after 5 minutes (300000ms)
    clickDebounceTime: 1000, // Debounce click logging to once per second
  },
  // Throttle function to limit how often a function can run
  throttle(func, limit) {
    let lastRun;
    return function (...args) {
      if (!lastRun || Date.now() - lastRun >= limit) {
        lastRun = Date.now();
        func.apply(this, args);
      }
    };
  },
  // Logging function with filtering
  log(eventType, data) {
    // Use sendBeacon for reliability during page unload
    if (navigator.sendBeacon) {
      const blob = new Blob(
        [
          JSON.stringify({
            eventType,
            timestamp: new Date().toISOString(),
            ...data,
          }),
        ],
        { type: 'application/json' }
      );

      navigator.sendBeacon('/api/log', blob);
    } else {
      // Fallback for browsers that don't support sendBeacon
      fetch('/api/log', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        keepalive: true,
        body: JSON.stringify({
          eventType,
          timestamp: new Date().toISOString(),
          ...data,
        }),
      }).catch((e) => console.error('Logging error:', e));
    }
  },
};

// Function to check if we're in demo mode
function checkDemoMode() {
  console.log('Checking for demo mode...');
  fetch('/health')
    .then((response) => {
      if (!response.ok) {
        throw new Error(`HTTP error ${response.status}`);
      }
      return response.json();
    })
    .then((data) => {
      console.log('Demo mode status:', data.demoMode);
      // Check for URL parameter as well
      const urlParams = new URLSearchParams(window.location.search);
      const demoParam = urlParams.get('demo');

      if (data.demoMode || demoParam === 'true') {
        enableDemoMode();
      } else if (demoParam === 'false' || !data.demoMode) {
        disableDemoMode();
      }

      // Update request limit information
      updateRequestLimitInfo();
    })
    .catch((error) => {
      console.error('Error checking demo mode:', error);
    });
}

// Function to enable demo mode UI
function enableDemoMode() {
  console.log('Enabling demo mode UI...');

  // Get the SSO token input field
  const ssoTokenInput = document.getElementById('ssoToken');
  if (ssoTokenInput) {
    // Disable the input
    ssoTokenInput.disabled = true;
    // Add a placeholder indicating demo mode
    ssoTokenInput.placeholder = 'Demo Mode - No SSO Token Required';
    // Gray it out with a CSS class
    ssoTokenInput.classList.add('demo-mode');

    // Add a demo mode indicator above the form
    const formContainer = document.querySelector('.form-container');
    if (formContainer) {
      // Check if notice already exists to avoid duplicates
      if (!document.querySelector('.demo-notice')) {
        const demoNotice = document.createElement('div');
        demoNotice.className = 'demo-notice';
        demoNotice.innerHTML =
          '<strong>🎮 Demo Mode Active</strong> - Using a pre-configured token. No need to enter your own SSO token.';
        formContainer.insertBefore(demoNotice, formContainer.firstChild);
      }
    }
  }

  // Ensure this is applied to window.appState
  window.appState = window.appState || {};
  window.appState.demoMode = true;
}

function disableDemoMode() {
  const ssoTokenInput = document.getElementById('ssoToken');
  if (ssoTokenInput) {
    ssoTokenInput.disabled = false;
    ssoTokenInput.placeholder = 'Enter your SSO token';
    ssoTokenInput.classList.remove('demo-mode');
  }

  const demoNotice = document.querySelector('.demo-notice');
  if (demoNotice) {
    demoNotice.remove();
  }

  window.appState = window.appState || {};
  window.appState.demoMode = false;
}

function updateRequestLimitInfo() {
  fetch('/health')
    .then((response) => response.json())
    .then((data) => {
      const limitInfoElement = document.querySelector('.request-limit-info');
      if (data.requestsRemaining !== null) {
        const message =
          data.requestsRemaining > 0 ?
            `Demo mode requests remaining: <strong>${data.requestsRemaining}</strong> (Resets hourly)`
          : `Request limit reached. Please try again later or use your own SSO token.`;

        if (limitInfoElement) {
          limitInfoElement.innerHTML = `<small>${message}</small>`;
        } else {
          const formContainer = document.querySelector('.form-container');
          if (formContainer) {
            const limitInfo = document.createElement('div');
            limitInfo.className = 'request-limit-info';
            limitInfo.innerHTML = `<small>${message}</small>`;
            formContainer.appendChild(limitInfo);
          }
        }
      }
    });
}

window.addEventListener('popstate', checkDemoMode);

// Initialize once DOM is loaded
document.addEventListener('DOMContentLoaded', function () {
  checkDemoMode(); // Check demo mode first
  initTabSwitching();
  addEnterKeyListeners();
  addSyncListeners();
  setupProcessingOptions();
  setupFormatSelector();
  setupTimeOptions();
  setupDownloadButton();
  initializeSessionTracking();
  // Call initially and then set up a refresh interval
  updateRequestLimitInfo();
});

// Tab switching logic
function initTabSwitching() {
  document.querySelectorAll('.tab').forEach((tab) => {
    tab.addEventListener('click', () => {
      document
        .querySelectorAll('.tab')
        .forEach((t) => t.classList.remove('active'));
      document
        .querySelectorAll('.tab-content')
        .forEach((c) => c.classList.remove('active'));

      tab.classList.add('active');
      const tabId = tab.getAttribute('data-tab');
      document.getElementById(`${tabId}-tab`).classList.add('active');
    });
  });
}

function triggerActiveTabButton() {
  const activeTab = document
    .querySelector('.tab.active')
    .getAttribute('data-tab');
  switch (activeTab) {
    case 'stats':
      document.getElementById('fetchStats').click();
      break;
    case 'matches':
      document.getElementById('fetchMatches').click();
      break;
    case 'user':
      document.getElementById('fetchUserInfo').click();
      break;
    case 'cdn':
      document.getElementById('fetchCDNData').click();
      break;
    case 'other':
      document.getElementById('fuzzySearch').click();
      break;
  }
}

function addEnterKeyListeners() {
  // Use event delegation for handling Enter key press
  document.addEventListener('keypress', function (event) {
    if (event.key === 'Enter') {
      // Get the active element
      const activeElement = document.activeElement;

      if (!activeElement || !activeElement.id) return;

      // Mapping of input fields to their submit buttons
      const inputToButtonMapping = {
        ssoToken: null, // Will trigger active tab button
        username: null, // Will trigger active tab button
        matchUsername: 'fetchMatches',
        matchId: 'fetchMatchInfo',
        userUsername: 'fetchUserInfo',
        searchUsername: 'fuzzySearch',
      };

      if (activeElement.id in inputToButtonMapping) {
        if (inputToButtonMapping[activeElement.id]) {
          // Click the specific button
          document
            .getElementById(inputToButtonMapping[activeElement.id])
            .click();
        } else {
          // Trigger the active tab button
          triggerActiveTabButton();
        }
      }
    }
  });
}

// Setup processing options (sanitize/replace)
function setupProcessingOptions() {
  document
    .getElementById('sanitizeOption')
    .addEventListener('change', function () {
      if (window.appState.currentData) {
        // Process current data without re-fetching
        displayResults(window.appState.currentData);
      }
    });

  document
    .getElementById('replaceKeysOption')
    .addEventListener('change', function () {
      if (window.appState.currentData) {
        // Process current data without re-fetching
        displayResults(window.appState.currentData);
      }
    });
}

// Setup format selector
function setupFormatSelector() {
  document
    .getElementById('outputFormat')
    .addEventListener('change', function () {
      window.appState.outputFormat = this.value;
      if (window.appState.currentData) {
        displayResults(window.appState.currentData);
      }
    });
}

// Time options
function setupTimeOptions() {
  const convertTimeCheckbox = document.getElementById('convertTimeOption');
  const timezoneSelect = document.getElementById('timezoneSelect');

  convertTimeCheckbox.addEventListener('change', function () {
    timezoneSelect.disabled = !this.checked;

    if (window.appState.currentData) {
      displayResults(window.appState.currentData); // Refresh the display
    }
  });

  timezoneSelect.addEventListener('change', function () {
    if (window.appState.currentData) {
      displayResults(window.appState.currentData); // Refresh the display
    }
  });
}

// Download Button
function setupDownloadButton() {
  const downloadBtn = document.getElementById('downloadJson');
  if (!downloadBtn) return;

  downloadBtn.addEventListener('click', function () {
    const resultsElement = document.getElementById('results');
    const jsonData = resultsElement.textContent;

    if (!jsonData) {
      alert('No data to download');
      return;
    }

    // Create a Blob with the data
    const contentType =
      window.appState.outputFormat === 'yaml' ?
        'text/yaml'
      : 'application/json';
    const blob = new Blob([jsonData], { type: contentType });

    // Create a temporary link element
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);

    // Generate a filename with timestamp
    const date = new Date();
    const timestamp = `${date.getFullYear()}-${String(
      date.getMonth() + 1
    ).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}_${String(
      date.getHours()
    ).padStart(2, '0')}-${String(date.getMinutes()).padStart(2, '0')}`;
    const extension = window.appState.outputFormat === 'yaml' ? 'yaml' : 'json';
    a.download = `cod_stats_${timestamp}.${extension}`;

    // Trigger download
    document.body.appendChild(a);
    a.click();

    // Clean up
    document.body.removeChild(a);
  });
}

// Function to synchronize username across tabs
function syncUsernames() {
  const mainUsername = document.getElementById('username').value.trim();

  // Only sync if there's a value
  if (mainUsername) {
    document.getElementById('matchUsername').value = mainUsername;
    document.getElementById('userUsername').value = mainUsername;
    document.getElementById('searchUsername').value = mainUsername;
  }

  // Also sync platform across tabs when it changes
  const mainPlatform = document.getElementById('platform').value;
  document.getElementById('matchPlatform').value = mainPlatform;
  document.getElementById('userPlatform').value = mainPlatform;
  document.getElementById('searchPlatform').value = mainPlatform;
}

// Sync listeners for persistent usernames
function addSyncListeners() {
  // Add change listeners for username sync
  document.getElementById('username').addEventListener('change', syncUsernames);
  document
    .getElementById('matchUsername')
    .addEventListener('change', function () {
      document.getElementById('username').value = this.value;
      syncUsernames();
    });
  document
    .getElementById('userUsername')
    .addEventListener('change', function () {
      document.getElementById('username').value = this.value;
      syncUsernames();
    });
  document
    .getElementById('searchUsername')
    .addEventListener('change', function () {
      document.getElementById('username').value = this.value;
      syncUsernames();
    });

  // Add change listeners for platform sync
  document.getElementById('platform').addEventListener('change', syncUsernames);
}

// Initialize session tracking when the page loads
function initializeSessionTracking() {
  // Generate a unique session ID
  const sessionId =
    Date.now().toString(36) + Math.random().toString(36).substr(2);
  const sessionStart = Date.now();
  let lastActivity = Date.now();
  let activityTimer;

  // Store user's device and viewport info
  const deviceInfo = {
    screenWidth: window.screen.width,
    screenHeight: window.screen.height,
    viewportWidth: window.innerWidth,
    viewportHeight: window.innerHeight,
    pixelRatio: window.devicePixelRatio,
    userAgent: navigator.userAgent,
  };

  // Log initial session start with device info
  clientLogger.log('session_start', {
    sessionId,
    deviceInfo,
    referrer: document.referrer,
    landingPage: window.location.pathname,
  });

  // Update last activity time on user interactions
  ['click', 'mousemove', 'keypress', 'scroll', 'touchstart'].forEach(
    (event) => {
      document.addEventListener(event, () => (lastActivity = Date.now()));
    }
  );

  // Track clicks with throttling to reduce spam
  let lastClickTime = 0;
  document.addEventListener('click', (e) => {
    const now = Date.now();
    if (now - lastClickTime < clientLogger.settings.clickDebounceTime) {
      return; // Skip if clicked too recently
    }
    lastClickTime = now;

    const target = e.target;
    // Build an object with element details
    const elementInfo = {
      tagName: target.tagName,
      id: target.id || undefined,
      className: target.className || undefined,
      text: target.innerText ? target.innerText.substring(0, 100) : undefined,
      href: target.href || target.closest('a')?.href,
    };

    clientLogger.log('element_click', {
      sessionId,
      elementInfo,
      path: window.location.pathname,
    });
  });

  /*
  // Helper function to extract data attributes
  function getDataAttributes(element) {
    if (!element.dataset) return {};
    return Object.entries(element.dataset).reduce((acc, [key, value]) => {
      acc[key] = value;
      return acc;
    }, {});
  } */

  // Track tab visibility changes
  document.addEventListener('visibilitychange', () => {
    clientLogger.log('visibility_change', {
      sessionId,
      visibilityState: document.visibilityState,
      timestamp: Date.now(),
    });
  });

  // Track navigation between tabs/elements with focus events (if enabled)
  if (clientLogger.settings.logFocusEvents) {
    document.addEventListener('focusin', (e) => {
      const target = e.target;
      if (target.tagName) {
        clientLogger.log('focus_change', {
          sessionId,
          element: {
            tagName: target.tagName,
            id: target.id || undefined,
            className: target.className || undefined,
          },
        });
      }
    });
  }

  // Track scroll events with throttling (if enabled)
  if (clientLogger.settings.logScrollEvents) {
    document.addEventListener(
      'scroll',
      clientLogger.throttle(() => {
        clientLogger.log('scroll', {
          sessionId,
          scrollPosition: {
            y: window.scrollY,
          },
          percentScrolled: Math.round(
            (window.scrollY /
              (document.documentElement.scrollHeight - window.innerHeight)) *
              100
          ),
        });
      }, 1000) // Log at most once per second
    );
  }

  // Track window resize events with throttling (if enabled)
  if (clientLogger.settings.logResizeEvents) {
    window.addEventListener(
      'resize',
      clientLogger.throttle(() => {
        clientLogger.log('window_resize', {
          sessionId,
          dimensions: {
            width: window.innerWidth,
            height: window.innerHeight,
          },
        });
      }, 1000) // Log at most once per second
    );
  }

  // Monitor form interactions - only for submits and important changes
  document.addEventListener('submit', (e) => {
    const form = e.target;
    clientLogger.log('form_submit', {
      sessionId,
      formId: form.id || undefined,
      formName: form.getAttribute('name') || undefined,
    });
  });

  // Activity check every 60 seconds
  activityTimer = setInterval(() => {
    const inactiveTime = Date.now() - lastActivity;
    // Log if user has been inactive for more than the minimum threshold
    if (inactiveTime > clientLogger.settings.minimumInactivityTime) {
      clientLogger.log('user_inactive', {
        sessionId,
        inactiveTime: Math.round(inactiveTime / 1000),
      });
    }
  }, 60000);

  // Log session end when page is closed
  window.addEventListener('beforeunload', () => {
    clearInterval(activityTimer);
    const duration = Math.round((Date.now() - sessionStart) / 1000);
    clientLogger.log('session_end', {
      sessionId,
      duration,
      path: window.location.pathname,
    });
  });

  // Track pushState and replaceState for SPA navigation
  const originalPushState = history.pushState;
  const originalReplaceState = history.replaceState;

  history.pushState = function () {
    originalPushState.apply(this, arguments);
    handleHistoryChange();
  };

  history.replaceState = function () {
    originalReplaceState.apply(this, arguments);
    handleHistoryChange();
  };

  function handleHistoryChange() {
    clientLogger.log('page_view', {
      sessionId,
      path: window.location.pathname,
      query: window.location.search,
      title: document.title,
    });
  }

  // Track network requests only if detailed network logging is enabled
  if (clientLogger.settings.enableDetailedNetworkLogs) {
    const originalFetch = window.fetch;
    window.fetch = function () {
      const startTime = Date.now();
      const url = arguments[0];
      const method = arguments[1]?.method || 'GET';

      // Skip logging for log endpoint to avoid infinite loops
      if (typeof url === 'string' && url.includes('/api/log')) {
        return originalFetch.apply(this, arguments);
      }

      // Only log the URL and method, not the payload
      clientLogger.log('network_request_start', {
        sessionId,
        url: typeof url === 'string' ? url : url.url,
        method,
      });

      return originalFetch
        .apply(this, arguments)
        .then((response) => {
          clientLogger.log('network_request_complete', {
            sessionId,
            url: typeof url === 'string' ? url : url.url,
            method,
            status: response.status,
            duration: Date.now() - startTime,
          });
          return response;
        })
        .catch((error) => {
          clientLogger.log('network_request_error', {
            sessionId,
            url: typeof url === 'string' ? url : url.url,
            method,
            error: error.message,
            duration: Date.now() - startTime,
          });
          throw error;
        });
    };
  }

  // Track errors
  window.addEventListener('error', (e) => {
    clientLogger.log('js_error', {
      sessionId,
      message: e.message,
      source: e.filename,
      lineno: e.lineno,
      colno: e.colno,
    });
  });
}

// Fetch stats
document.getElementById('fetchStats').addEventListener('click', async () => {
  const username = document.getElementById('username').value.trim();
  const ssoToken = document.getElementById('ssoToken').value.trim();
  const platform = document.getElementById('platform').value;
  const game = document.getElementById('game').value;
  const apiCall = document.getElementById('apiCall').value;

  const sanitize = document.getElementById('sanitizeOption').checked;
  const replaceKeys = document.getElementById('replaceKeysOption').checked;

  await window.backendAPI.fetchData('/api/stats', {
    username,
    ssoToken,
    platform,
    game,
    apiCall,
    sanitize,
    replaceKeys,
  });
});

// Fetch match history
document.getElementById('fetchMatches').addEventListener('click', async () => {
  const username = document.getElementById('matchUsername').value.trim();
  const ssoToken = document.getElementById('ssoToken').value.trim();
  const platform = document.getElementById('matchPlatform').value;
  const game = document.getElementById('matchGame').value;

  const sanitize = document.getElementById('sanitizeOption').checked;
  const replaceKeys = document.getElementById('replaceKeysOption').checked;

  await window.backendAPI.fetchData('/api/matches', {
    username,
    ssoToken,
    platform,
    game,
    sanitize,
    replaceKeys,
  });
});

// Fetch match details
document
  .getElementById('fetchMatchInfo')
  .addEventListener('click', async () => {
    const matchId = document.getElementById('matchId').value.trim();
    const ssoToken = document.getElementById('ssoToken').value.trim();
    const platform = document.getElementById('matchPlatform').value;
    const game = document.getElementById('matchGame').value;

    const sanitize = document.getElementById('sanitizeOption').checked;
    const replaceKeys = document.getElementById('replaceKeysOption').checked;

    if (!matchId) {
      displayError('Match ID is required');
      return;
    }

    await window.backendAPI.fetchData('/api/matchInfo', {
      matchId,
      ssoToken,
      platform,
      game,
      sanitize,
      replaceKeys,
    });
  });

// Fetch user info
document.getElementById('fetchUserInfo').addEventListener('click', async () => {
  const username = document.getElementById('userUsername').value.trim();
  const ssoToken = document.getElementById('ssoToken').value.trim();
  const platform = document.getElementById('userPlatform').value;
  const userCall = document.getElementById('userCall').value;

  const sanitize = document.getElementById('sanitizeOption').checked;
  const replaceKeys = document.getElementById('replaceKeysOption').checked;

  // For event feed and identities, username is not required
  if (
    !username &&
    userCall !== 'eventFeed' &&
    userCall !== 'friendFeed' &&
    userCall !== 'identities'
  ) {
    displayError('Username is required for this API call');
    return;
  }

  await window.backendAPI.fetchData('/api/user', {
    username,
    ssoToken,
    platform,
    userCall,
    sanitize,
    replaceKeys,
  });
});

// Fetch CDN Data
document.getElementById('fetchCDNData').addEventListener('click', async () => {
  const ssoToken = document.getElementById('ssoToken').value.trim();
  const cdnCall = document.getElementById('cdnCall').value;

  const sanitize = document.getElementById('sanitizeOption').checked;
  const replaceKeys = document.getElementById('replaceKeysOption').checked;

  await window.backendAPI.fetchData('/api/cdn', {
    ssoToken,
    cdnCall,
    sanitize,
    replaceKeys,
  });
});

// Fuzzy search
document.getElementById('fuzzySearch').addEventListener('click', async () => {
  const username = document.getElementById('searchUsername').value.trim();
  const ssoToken = document.getElementById('ssoToken').value.trim();
  const platform = document.getElementById('searchPlatform').value;

  const sanitize = document.getElementById('sanitizeOption').checked;
  const replaceKeys = document.getElementById('replaceKeysOption').checked;

  if (!username) {
    displayError('Username is required for search');
    return;
  }

  await window.backendAPI.fetchData('/api/search', {
    username,
    ssoToken,
    platform,
    sanitize,
    replaceKeys,
  });
});
