import 'dotenv/config'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import { app, shell, BrowserWindow, ipcMain } from 'electron'
import filesystemPlugin from '@takerofnotes/plugin-filesystem'
import supabasePlugin from '@takerofnotes/plugin-supabase'
import PluginRegistry from './core/PluginRegistry.js'
import PluginConfig from './core/PluginConfig.js'
import NotesAPI from './core/NotesAPI.js'
import { join } from 'path'

const preloadPath = join(__dirname, '../preload/index.mjs')
const rendererPath = join(__dirname, '../renderer/index.html')

// Main window
function createWindow() {
    const mainWindow = new BrowserWindow({
        width: 354,
        height: 549,
        show: false,
        autoHideMenuBar: true,
        webPreferences: {
            preload: preloadPath,
            sandbox: false,
        },
    })

    mainWindow.on('ready-to-show', () => {
        mainWindow.show()
    })

    mainWindow.webContents.setWindowOpenHandler((details) => {
        shell.openExternal(details.url)
        return { action: 'deny' }
    })

    if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
        mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
    } else {
        mainWindow.loadFile(rendererPath)
    }
}

// Open note in new window
function createNoteWindow(noteId) {
    const noteWindow = new BrowserWindow({
        width: 354,
        height: 549,
        autoHideMenuBar: true,
        webPreferences: {
            preload: preloadPath,
            contextIsolation: true,
            nodeIntegration: false,
            sandbox: false,
        },
    })

    if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
        noteWindow.loadURL(
            `${process.env['ELECTRON_RENDERER_URL']}/#/note/${noteId}`,
        )
    } else {
        noteWindow.loadFile(rendererPath, {
            hash: `/note/${noteId}`,
        })
    }
}

app.whenReady().then(async () => {
    // Open note in new window
    ipcMain.on('open-note-window', (_, noteId) => {
        createNoteWindow(noteId)
    })

    // Create plugin registry
    const registry = new PluginRegistry()

    // Register built-in plugins
    registry.register(filesystemPlugin)
    registry.register(supabasePlugin)

    // Pull plugin config
    const config = await new PluginConfig(filesystemPlugin).load()

    // Create instance of active adapter
    const plugin = registry.get(config.activeAdapter)
    // const plugin = registry.get(supabasePlugin.id)
    const adapter = plugin.createAdapter(config.adapterConfig)
    // const adapter = plugin.createAdapter({
    //     supabaseKey: process.env.SUPABASE_KEY,
    //     supabaseUrl: process.env.SUPABASE_URL,
    // })

    // Init Notes API
    const notesAPI = new NotesAPI(
        adapter,
        '729a0d21d783654c68f1a0123e2a0e986350de536b5324f1f35876ea12ffeaf5',
    )
    await notesAPI.init()

    // Broadcast note changes to all windows
    const broadcastNoteChange = (event, data) => {
        BrowserWindow.getAllWindows().forEach((win) => {
            win.webContents.send(event, data)
        })
    }

    // Handle Notes API
    ipcMain.handle('notesAPI:call', async (_, method, args) => {
        if (!notesAPI[method]) {
            throw new Error('Invalid method')
        }

        const result = await notesAPI[method](...args)

        // Broadcast changes to all windows
        if (method === 'createNote') {
            broadcastNoteChange('note-created', result)
        } else if (method === 'updateNote') {
            broadcastNoteChange('note-updated', result)
        } else if (method === 'updateNoteMetadata') {
            broadcastNoteChange('note-updated', result)
        } else if (method === 'deleteNote') {
            broadcastNoteChange('note-deleted', { id: args[0] })
        }

        return result
    })

    electronApp.setAppUserModelId('com.electron')

    app.on('browser-window-created', (_, window) => {
        optimizer.watchWindowShortcuts(window)
    })

    createWindow()

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

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