import { app, ipcMain, shell, globalShortcut, safeStorage } from 'electron'
import Store from 'electron-store'
import { Buffer } from 'buffer'
import process from 'process'
import {
  registerGlobalShortcuts,
  setupSpotlightIPC
} from './spotlightWindow.js'
import {
  createWindow,
  setupMainWindowIPC,
  setupMainWindowAppEvents,
  setupDevAuthServer,
  setupSingleInstanceLock,
  handleDeepLinkFromArgv
} from './mainWindow.js'
import { setupAppUpdateIPC } from './appupdate.js'

// --- Auth session storage (main process) ---
const authStore = new Store({
  name: 'auth-session'
})
const AUTH_SESSION_KEY = 'authSession'
const appSettingsStore = new Store({
  name: 'settings'
})
const APP_SETTINGS_KEY = 'appSettings'

const serializeAuthSession = (session) => {
  const sessionJson = JSON.stringify(session)

  if (safeStorage.isEncryptionAvailable()) {
    const encrypted = safeStorage.encryptString(sessionJson).toString('base64')
    return {
      encrypted: true,
      value: encrypted
    }
  }

  return {
    encrypted: false,
    value: sessionJson
  }
}

const deserializeAuthSession = (storedValue) => {
  if (!storedValue) return null

  if (typeof storedValue === 'object' && storedValue.encrypted === true) {
    if (!safeStorage.isEncryptionAvailable()) {
      console.warn(
        '[auth-session] Encrypted auth session exists but encryption is unavailable on this system.'
      )
      return null
    }
    const decrypted = safeStorage.decryptString(
      Buffer.from(storedValue.value, 'base64')
    )
    return JSON.parse(decrypted)
  }

  if (typeof storedValue === 'object' && typeof storedValue.value === 'string') {
    return JSON.parse(storedValue.value)
  }

  if (typeof storedValue === 'string') {
    return JSON.parse(storedValue)
  }

  // Legacy safety net if the object shape already matches the session structure.
  if (typeof storedValue === 'object' && storedValue.token) {
    return storedValue
  }

  return null
}

const gotTheLock = setupSingleInstanceLock(app)

if (gotTheLock) {
  app.whenReady().then(() => {
    createWindow()
    registerGlobalShortcuts()
    setupSpotlightIPC()
    setupMainWindowIPC()
    setupAppUpdateIPC(app)
    setupMainWindowAppEvents(app)
    setupDevAuthServer()
    handleDeepLinkFromArgv()
  })
}

app.on('will-quit', () => {
  globalShortcut.unregisterAll()
})

// IPC handler to get OS
ipcMain.handle('os-info', () => {
  return {
    platform: process.platform
  }
})

ipcMain.handle('auth-session-get', async () => {
  try {
    const storedValue = authStore.get(AUTH_SESSION_KEY)
    return deserializeAuthSession(storedValue)
  } catch (e) {
    console.warn('[auth-session] Failed to read auth session.', e?.message || e)
    return null
  }
})

ipcMain.handle('auth-session-set', async (event, session) => {
  try {
    if (!session || typeof session !== 'object') return false
    authStore.set(AUTH_SESSION_KEY, serializeAuthSession(session))
    return true
  } catch (e) {
    console.warn('[auth-session] Failed to write auth session.', e?.message || e)
    return false
  }
})

ipcMain.handle('auth-session-clear', async () => {
  try {
    authStore.delete(AUTH_SESSION_KEY)
    return true
  } catch (e) {
    console.warn('[auth-session] Failed to clear auth session.', e?.message || e)
    return false
  }
})

ipcMain.handle('app-settings-get', async () => {
  try {
    const settings = appSettingsStore.get(APP_SETTINGS_KEY)
    return settings && typeof settings === 'object' ? settings : {}
  } catch (e) {
    console.warn('[app-settings] Failed to read settings.', e?.message || e)
    return {}
  }
})

ipcMain.handle('app-settings-set', async (event, settings) => {
  try {
    if (!settings || typeof settings !== 'object') return false
    appSettingsStore.set(APP_SETTINGS_KEY, settings)
    return true
  } catch (e) {
    console.warn('[app-settings] Failed to write settings.', e?.message || e)
    return false
  }
})

// IPC handler for opening external URLs
ipcMain.handle('open-external-url', (event, url) => {
  shell.openExternal(url)
})
