import { app, BrowserWindow, ipcMain, Menu } from 'electron'
import path, { dirname } from 'path'
import { fileURLToPath } from 'url'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

let win
let sidebarViewMenuSections = []

const PROTOCOL_PREFIX = 'farmcontrol://'

function findProtocolUrl(args) {
  return args.find(
    (arg) => typeof arg === 'string' && arg.startsWith(PROTOCOL_PREFIX)
  )
}

function sendNavigateToRenderer(redirectPath) {
  const deliver = () => {
    win.webContents.send('navigate', redirectPath)
    win.show()
    win.focus()
  }

  if (!win || win.isDestroyed()) {
    createWindow()
    win.webContents.once('did-finish-load', () => {
      setTimeout(deliver, 100)
    })
    return
  }

  if (win.webContents.isLoading()) {
    win.webContents.once('did-finish-load', () => {
      setTimeout(deliver, 100)
    })
    return
  }

  deliver()
}

function toElectronSidebarMenuItems(items = []) {
  return items
    .map((item) => {
      if (item?.type === 'divider') {
        return { type: 'separator' }
      }

      const menuItem = {
        label: item.label
      }

      if (item?.children && Array.isArray(item.children) && item.children.length) {
        menuItem.submenu = toElectronSidebarMenuItems(item.children)
      } else if (item?.path) {
        menuItem.click = () => sendNavigateToRenderer(item.path)
      } else {
        menuItem.enabled = false
      }

      return menuItem
    })
    .filter(Boolean)
}

function buildApplicationMenuTemplate() {
  const env = (process.env.NODE_ENV || 'development').trim()
  const viewSubmenu = sidebarViewMenuSections.map((section) => ({
    label: section.label,
    submenu: toElectronSidebarMenuItems(section.items || [])
  }))

  if (viewSubmenu.length === 0) {
    viewSubmenu.push({ label: 'No sidebar items available', enabled: false })
  }

  if (env === 'development') {
    viewSubmenu.push(
      { type: 'separator' },
      {
        label: 'Toggle Developer Tools',
        accelerator:
          process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
        click: () => {
          if (win && !win.isDestroyed()) {
            win.webContents.toggleDevTools()
          }
        }
      }
    )
  }

  const template = [
    { role: 'fileMenu' },
    { role: 'editMenu' },
    { label: 'View', submenu: viewSubmenu },
    { role: 'windowMenu' }
  ]

  if (process.platform === 'darwin') {
    template.unshift({ role: 'appMenu' })
  }

  return template
}

function applyApplicationMenu() {
  const menu = Menu.buildFromTemplate(buildApplicationMenuTemplate())
  Menu.setApplicationMenu(menu)
}

export function handleDeepLink(url) {
  if (!url?.startsWith(`${PROTOCOL_PREFIX}app`)) return
  const redirectPath = url.replace(`${PROTOCOL_PREFIX}app`, '') || '/'
  sendNavigateToRenderer(redirectPath)
}

export function handleDeepLinkFromArgv() {
  if (process.platform === 'darwin') return
  const url = findProtocolUrl(process.argv)
  if (url) handleDeepLink(url)
}

export function setupSingleInstanceLock(app) {
  const gotTheLock = app.requestSingleInstanceLock()
  if (!gotTheLock) {
    app.quit()
    return false
  }

  app.on('second-instance', (_event, commandLine) => {
    const url = findProtocolUrl(commandLine)
    if (url) {
      handleDeepLink(url)
    } else if (win && !win.isDestroyed()) {
      if (win.isMinimized()) win.restore()
      win.show()
      win.focus()
    }
  })

  return true
}

function attachKeyboardShortcuts(browserWindow) {
  if (!browserWindow) return
  // Keyboard shortcuts for the main window can be added here if needed
}

function sendNavigationGesture(browserWindow, direction) {
  if (!browserWindow || browserWindow.isDestroyed()) return
  browserWindow.webContents.send('navigation-gesture', direction)
}

function setupNavigationGestures(browserWindow) {
  if (!browserWindow) return

  if (process.platform === 'darwin') {
    browserWindow.on('swipe', (_event, direction) => {
      if (direction === 'left') {
        sendNavigationGesture(browserWindow, 'back')
      } else if (direction === 'right') {
        sendNavigationGesture(browserWindow, 'forward')
      }
    })
  }

  browserWindow.on('app-command', (_event, command) => {
    if (command === 'browser-backward') {
      sendNavigationGesture(browserWindow, 'back')
    } else if (command === 'browser-forward') {
      sendNavigationGesture(browserWindow, 'forward')
    }
  })
}

function setupWindowEvents() {
  if (!win) return
  win.on('maximize', () => {
    win.webContents.send('window-state', {
      isMaximized: true
    })
  })
  win.on('enter-full-screen', () => {
    win.webContents.send('window-state', {
      isFullScreen: true
    })
  })
  win.on('leave-full-screen', () => {
    win.webContents.send('window-state', {
      isFullScreen: false
    })
  })
  win.on('unmaximize', () => {
    win.webContents.send('window-state', {
      isMaximized: false
    })
  })
}

export function createWindow() {
  win = new BrowserWindow({
    width: 1200,
    height: 800,
    frame: false,
    titleBarStyle: 'hiddenInset',
    trafficLightPosition: { x: 14, y: 12 },
    backgroundColor: '#141414',
    icon: path.join(__dirname, './logo512.png'),
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  })

  applyApplicationMenu()

  // For development, load from localhost; for production, load the built index.html
  if (process.env.ELECTRON_START_URL) {
    win.loadURL(process.env.ELECTRON_START_URL)
  } else {
    win.loadFile(path.join(__dirname, '../build/index.html'))
  }

  setupWindowEvents()
  attachKeyboardShortcuts(win)
  setupNavigationGestures(win)

  if (process.platform === 'darwin') {
    win.maximize()
  } else if (process.platform === 'win32') {
    win.maximize()
  }
}

export function getWindow() {
  return win
}

export function getElectronVersion() {
  return process.versions.electron
}

export function setupMainWindowIPC() {
  // IPC handler to get window state
  ipcMain.handle('window-state', () => {
    if (!win || win.isDestroyed())
      return { isFullScreen: false, isMaximized: false }
    return {
      isFullScreen: win ? win.isFullScreen() : false,
      isMaximized: win ? win.isMaximized() : false
    }
  })

  // IPC handlers for window controls
  ipcMain.on('window-control', (event, action) => {
    if (!win && action !== 'quit') return
    switch (action) {
      case 'minimize':
        win.minimize()
        break
      case 'maximize':
        if (win.isMaximized()) {
          win.unmaximize()
        } else {
          win.maximize()
        }
        break
      case 'close':
        win.close()
        break
      case 'fullscreen':
        win.setFullScreen(!win.isFullScreen())
        break
      case 'quit':
        app.quit()
        break
      case 'toggle-devtools':
        if (win && !win.isDestroyed()) {
          win.webContents.toggleDevTools()
        }
        break
      default:
        break
    }
  })

  ipcMain.handle('open-internal-url', (event, url) => {
    if (!win || win.isDestroyed()) {
      createWindow()
      // Wait for window to finish loading before sending navigate event
      win.webContents.once('did-finish-load', () => {
        setTimeout(() => {
          win.webContents.send('navigate', url)
          win.show()
          win.focus()
        }, 100)
      })
    } else {
      win.webContents.send('navigate', url)
      win.show()
      win.focus()
    }
    return true
  })

  ipcMain.handle('set-sidebar-view-menu', (event, sidebarSections) => {
    if (!Array.isArray(sidebarSections)) {
      return false
    }

    sidebarViewMenuSections = sidebarSections
    applyApplicationMenu()
    return true
  })

  ipcMain.handle('electron-version', () => getElectronVersion())
}

export function setupMainWindowAppEvents(app) {
  app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit()
  })

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })

  app.on('open-url', (event, url) => {
    event.preventDefault()
    handleDeepLink(url)
  })
}

export function setupDevAuthServer() {
  const env = (process.env.NODE_ENV || 'development').trim()
  if (env == 'development') {
    import('express').then(({ default: express }) => {
      const app = express()
      const port = 3500

      app.use((req, res) => {
        const redirectPath = req.originalUrl
        res.send(
          `Open Farmcontrol to continue... (Redirect path: ${redirectPath})`
        )
        if (win && win.webContents) {
          win.webContents.send('navigate', redirectPath)
          win.show()
          win.focus()
        }
      })

      app.listen(port, () => {})
    })
  }
}
