'use strict';

var main = require('./main.js');
var electron = require('electron');
require('child_process');
require('fs');
require('rimraf');
require('redux');
require('path');
require('i18next');
require('reselect');
require('electron-store');
require('detect-browsers');
require('electron-log');
require('node:tls');
require('semver');
require('os');
require('electron-dl');
require('@bugsnag/js');
require('util');
require('archiver');
require('https');
require('axios');
require('@ewsjs/xhr');
require('ews-javascript-api');
require('node:fs/promises');
require('node:path');
require('jsonwebtoken');
require('moment');
require('process');
require('electron-updater');

/**
 * Internal picker provider that uses the React UI and desktopCapturer cache.
 * This provider works in both main and renderer processes:
 * - handleDisplayMediaRequest: called from main process, uses ipc.ts state
 * - initialize: called from renderer process, preloads UI and cache
 *
 * Note: This provider needs access to state in ipc.ts. The factory will
 * pass a handler function that encapsulates the internal picker logic.
 */
class InternalPickerProvider {
  constructor() {
    main._defineProperty(this, "type", 'internal');
    main._defineProperty(this, "requiresInternalUI", true);
    main._defineProperty(this, "requiresCacheWarming", true);
    main._defineProperty(this, "isInitialized", false);
    main._defineProperty(this, "handleRequestFn", null);
    main._defineProperty(this, "initializeFn", null);
  }
  /**
   * Set the handler function from main process (ipc.ts)
   * This encapsulates all the internal picker logic with access to ipc.ts state
   */
  setHandleRequestHandler(handler) {
    this.handleRequestFn = handler;
  }

  /**
   * Set the initialize function from renderer process (video-call-window.ts)
   * This encapsulates the UI preload and cache warming logic
   */
  setInitializeHandler(handler) {
    this.initializeFn = handler;
  }
  handleDisplayMediaRequest(callback) {
    if (this.handleRequestFn) {
      this.handleRequestFn(callback);
    } else {
      console.error('InternalPickerProvider: handleRequest handler not set. This should be set by ipc.ts');
      callback({
        video: false
      });
    }
  }
  async initialize() {
    if (this.isInitialized) return;
    console.log('Screen picker [internal]: initializing cache and UI');
    if (this.initializeFn) {
      await this.initializeFn();
    } else {
      console.warn('InternalPickerProvider: initialize handler not set. Call setInitializeHandler() first.');
    }
    this.isInitialized = true;
  }
  cleanup() {
    // Clear caches, reset state
    this.isInitialized = false;
  }
}

class PortalPickerProvider {
  constructor() {
    main._defineProperty(this, "type", 'portal');
    main._defineProperty(this, "requiresInternalUI", false);
    main._defineProperty(this, "requiresCacheWarming", false);
  }
  handleDisplayMediaRequest(callback) {
    // On Linux/Wayland, calling getSources() triggers the XDG portal picker.
    // The portal typically returns exactly one source on selection or an empty array
    // on cancellation; we defensively check for > 0 and use only the first source.
    console.log('Screen picker [portal]: triggering XDG portal picker via getSources()');
    electron.desktopCapturer.getSources({
      types: ['screen', 'window']
    }).then(sources => {
      if (sources.length > 0) {
        // User selected a source via portal picker
        callback({
          video: sources[0]
        });
      } else {
        // User cancelled or no source available
        console.warn('Screen picker [portal]: No source selected by user');
        callback({
          video: false
        });
      }
    }).catch(error => {
      console.error('Screen picker [portal]: Failed to get source from XDG portal:', error);
      callback({
        video: false
      });
    });
  }
  async initialize() {
    // Portal picker requires no initialization
    console.log('Screen picker [portal]: initialized (no-op)');
  }
  cleanup() {
    // Portal picker requires no cleanup
    console.log('Screen picker [portal]: cleanup (no-op)');
  }
}

function detectPickerType() {
  if (process.platform === 'linux') {
    const sessionType = process.env.XDG_SESSION_TYPE;
    const desktop = process.env.XDG_CURRENT_DESKTOP || '';
    const isWayland = sessionType === 'wayland';
    const hasPortal = /GNOME|KDE|XFCE|Cinnamon|MATE|Pantheon|Budgie|Unity/i.test(desktop);
    if (isWayland || hasPortal) {
      return 'portal';
    }
  }

  // Future: Add macOS native picker detection here
  // if (process.platform === 'darwin' && hasMacOSNativePicker()) {
  //   return 'native-macos';
  // }

  return 'internal';
}
let cachedProvider = null;
function createScreenPicker() {
  if (cachedProvider) return cachedProvider;
  const type = detectPickerType();
  switch (type) {
    case 'portal':
      cachedProvider = new PortalPickerProvider();
      break;
    case 'internal':
    default:
      cachedProvider = new InternalPickerProvider();
  }
  console.log(`Screen picker: using ${cachedProvider.type} provider`);
  return cachedProvider;
}
function getScreenPicker() {
  if (!cachedProvider) {
    throw new Error('Screen picker not initialized. Call createScreenPicker() first.');
  }
  return cachedProvider;
}
function resetScreenPicker() {
  var _cachedProvider;
  (_cachedProvider = cachedProvider) === null || _cachedProvider === undefined || _cachedProvider.cleanup();
  cachedProvider = null;
}

exports.InternalPickerProvider = InternalPickerProvider;
exports.PortalPickerProvider = PortalPickerProvider;
exports.createScreenPicker = createScreenPicker;
exports.detectPickerType = detectPickerType;
exports.getScreenPicker = getScreenPicker;
exports.resetScreenPicker = resetScreenPicker;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,[encoded data, 13028 characters]
