import type { CapacitorElectronConfig } from '@capacitor-community/electron';
import { getCapacitorElectronConfig, setupElectronDeepLinking } from '@capacitor-community/electron';
import type { MenuItemConstructorOptions } from 'electron';
import { app, MenuItem, ipcMain, dialog } from 'electron';
import electronIsDev from 'electron-is-dev';
import unhandled from 'electron-unhandled';
// import { autoUpdater } from 'electron-updater';
import { promises as fs } from 'fs';
import { join } from 'path';

import { ElectronCapacitorApp, setupContentSecurityPolicy, setupReloadWatcher } from './setup';

// Use Electron's built-in single instance lock
const gotTheLock = app.requestSingleInstanceLock();

if (!gotTheLock) {
  console.log('[Electron] Another instance is already running. Exiting immediately...');
  process.exit(0);
}

// Graceful handling of unhandled errors.
unhandled({
  logger: (error) => {
    // Suppress EPIPE errors which are common in AppImages due to console output issues
    if (error.message && error.message.includes('EPIPE')) {
      return; // Don't log EPIPE errors
    }
    console.error('Unhandled error:', error);
  }
});

// Handle EPIPE errors on stdout/stderr to prevent crashes
process.stdout.on('error', (err) => {
  if (err.code === 'EPIPE') {
    // Ignore EPIPE errors on stdout
    return;
  }
  console.error('stdout error:', err);
});

process.stderr.on('error', (err) => {
  if (err.code === 'EPIPE') {
    // Ignore EPIPE errors on stderr
    return;
  }
  console.error('stderr error:', err);
});

// Define our menu templates (these are optional)
const trayMenuTemplate: (MenuItemConstructorOptions | MenuItem)[] = [new MenuItem({ label: 'Quit App', role: 'quit' })];
const appMenuBarMenuTemplate: (MenuItemConstructorOptions | MenuItem)[] = [
  { role: process.platform === 'darwin' ? 'appMenu' : 'fileMenu' },
  { role: 'editMenu' },
  { role: 'viewMenu' },
];

// Get Config options from capacitor.config
const capacitorFileConfig: CapacitorElectronConfig = getCapacitorElectronConfig();

// Initialize our app. You can pass menu templates into the app here.
// const myCapacitorApp = new ElectronCapacitorApp(capacitorFileConfig);
const myCapacitorApp = new ElectronCapacitorApp(capacitorFileConfig, trayMenuTemplate, appMenuBarMenuTemplate);

// If deeplinking is enabled then we will set it up here.
if (capacitorFileConfig.electron?.deepLinkingEnabled) {
  setupElectronDeepLinking(myCapacitorApp, {
    customProtocol: capacitorFileConfig.electron.deepLinkingCustomProtocol ?? 'mycapacitorapp',
  });
}

// If we are in Dev mode, use the file watcher components.
if (electronIsDev) {
  setupReloadWatcher(myCapacitorApp);
}

// Configure auto-updater
// DISABLED: Auto-updates not supported on Gitea hosting
// autoUpdater.on('error', (error) => {
//   console.log('Auto-updater error (suppressed):', error.message);
//   // Don't show error dialogs for update check failures
// });

// Run Application
(async () => {
  // Wait for electron app to be ready.
  await app.whenReady();
  // Security - Set Content-Security-Policy based on whether or not we are in dev mode.
  setupContentSecurityPolicy(myCapacitorApp.getCustomURLScheme());
  // Initialize our app, build windows, and load content.
  await myCapacitorApp.init();
  
  // Handle second instance launch (focus existing window and show dialog)
  app.on('second-instance', (event, commandLine, workingDirectory) => {
    console.log('[Electron] Second instance attempted to launch');
    
    // Someone tried to run a second instance, we should focus our window instead
    const mainWindow = myCapacitorApp.getMainWindow();
    if (mainWindow) {
      if (mainWindow.isMinimized()) {
        mainWindow.restore();
      }
      mainWindow.focus();
      
      // Show user-friendly dialog to inform about single instance
      dialog.showMessageBox(mainWindow, {
        type: 'info',
        title: 'TimeSafari Already Running',
        message: 'TimeSafari is already running in another window.',
        detail: 'Please use this existing TimeSafari window instead of opening a new one.',
        buttons: ['OK']
      }).catch((error) => {
        console.error('[Electron] Error showing dialog:', error);
      });
    }
  });
  
  // Auto-updates disabled - not supported on Gitea hosting
  // Only check for updates in production builds, not in development or AppImage
  // if (!electronIsDev && !process.env.APPIMAGE) {
  //   try {
  //     autoUpdater.checkForUpdatesAndNotify();
  //   } catch (error) {
  //     console.log('Update check failed (suppressed):', error);
  //   }
  // }
})();

// Handle when all of our windows are close (platforms have their own expectations).
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

// When the dock icon is clicked.
app.on('activate', async function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (myCapacitorApp.getMainWindow().isDestroyed()) {
    await myCapacitorApp.init();
  }
});

// Place all ipc or other electron api calls and custom functionality under this line

/**
 * IPC Handler for exporting data to the user's Downloads folder.
 * 
 * This provides a secure, native way to save files directly to the Downloads
 * directory using the main process's file system access.
 * 
 * @param fileName - The name of the file to save (including extension)
 * @param data - The data to write to the file (string or buffer)
 * @returns Promise<{success: boolean, path?: string, error?: string}>
 */
ipcMain.handle('export-data-to-downloads', async (_event, fileName: string, data: string) => {
  try {
    // Get the user's Downloads directory path
    const downloadsDir = app.getPath('downloads');
    const filePath = join(downloadsDir, fileName);

    // Write the file to the Downloads directory
    await fs.writeFile(filePath, data, 'utf-8');

    console.log(`[Electron Main] File exported successfully: ${filePath}`);
    
    return { 
      success: true, 
      path: filePath 
    };
  } catch (error) {
    console.error(`[Electron Main] File export failed:`, error);
    
    return { 
      success: false, 
      error: error instanceof Error ? error.message : 'Unknown error occurred' 
    };
  }
});
