import { ipcMain, BrowserWindow } from 'electron';
import { WebSocketClient } from './websocket-client.js';
import { PriceIndex } from '../shared/types.js';
import * as db from './database.js';

let wsClient: WebSocketClient | null = null;

export function setupIpcHandlers(mainWindow: BrowserWindow): void {
  const wsUrl = process.env.WS_URL || 'ws://localhost:3000/ws';
  
  // Initialize WebSocket client only once
  if (!wsClient) {
    wsClient = new WebSocketClient(wsUrl);
  }

  // Helper to safely send to renderer (window may be destroyed or hidden)
  const safeSend = (channel: string, ...args: any[]) => {
    try {
      if (mainWindow && !mainWindow.isDestroyed() && mainWindow.webContents && !mainWindow.webContents.isDestroyed()) {
        mainWindow.webContents.send(channel, ...args);
      }
    } catch (error) {
      // Window was destroyed, ignore
    }
  };

  // Forward WebSocket events to renderer
  wsClient.on('connected', () => {
    safeSend('ws:connected');
  });

  wsClient.on('disconnected', () => {
    safeSend('ws:disconnected');
  });

  wsClient.on('priceUpdate', (data: PriceIndex) => {
    safeSend('ws:priceUpdate', data);
  });

  wsClient.on('historyData', (data: any) => {
    safeSend('ws:historyData', data);
  });

  wsClient.on('error', (error: Error) => {
    safeSend('ws:error', error.message);
  });

  wsClient.on('maxReconnectAttemptsReached', () => {
    safeSend('ws:maxReconnectAttemptsReached');
  });

  // Remove existing handlers
  try { ipcMain.removeHandler('ws:connect'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('ws:disconnect'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('ws:getStatus'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('ws:send'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('api:getLatestPrices'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('window:minimize'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('window:maximize'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('window:close'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('window:isMaximized'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('window:hideToTray'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('alerts:getAll'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('alerts:add'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('alerts:update'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('alerts:delete'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('settings:getCustomAuecAmount'); } catch (e) { /* ignore */ }
  try { ipcMain.removeHandler('settings:setCustomAuecAmount'); } catch (e) { /* ignore */ }

  // IPC handlers for renderer requests
  ipcMain.handle('ws:connect', async () => {
    wsClient?.connect();
    return { success: true };
  });

  ipcMain.handle('ws:disconnect', async () => {
    wsClient?.disconnect();
    return { success: true };
  });

  ipcMain.handle('ws:getStatus', async () => {
    return {
      connected: wsClient?.isConnected() || false,
      state: wsClient?.getConnectionState() || 'DISCONNECTED',
    };
  });

  ipcMain.handle('ws:send', async (_event, message: any) => {
    wsClient?.sendMessage(message);
    return { success: true };
  });

  // Fetch initial data from API
  ipcMain.handle('api:getLatestPrices', async () => {
    try {
      const apiUrl = process.env.API_URL || 'http://localhost:3000';
      const response = await fetch(`${apiUrl}/api/prices/latest`);
      const data = await response.json();
      return data;
    } catch (error) {
      console.error('Failed to fetch latest prices:', error);
      return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
    }
  });

  // Window control handlers
  ipcMain.handle('window:minimize', () => {
    mainWindow.minimize();
  });

  ipcMain.handle('window:maximize', () => {
    if (mainWindow.isMaximized()) {
      mainWindow.unmaximize();
    } else {
      mainWindow.maximize();
    }
  });

  ipcMain.handle('window:close', () => {
    mainWindow.close();
  });

  ipcMain.handle('window:isMaximized', () => {
    return mainWindow.isMaximized();
  });

  ipcMain.handle('window:hideToTray', () => {
    mainWindow.hide();
  });

  // Alert management handlers
  ipcMain.handle('alerts:getAll', async () => {
    try {
      return db.getAllAlerts();
    } catch (error) {
      console.error('Failed to get alerts:', error);
      return [];
    }
  });

  ipcMain.handle('alerts:add', async (_event, alert: db.PriceAlert) => {
    try {
      db.addAlert(alert);
      return { success: true };
    } catch (error) {
      console.error('Failed to add alert:', error);
      return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
    }
  });

  ipcMain.handle('alerts:update', async (_event, alert: db.PriceAlert) => {
    try {
      db.updateAlert(alert);
      return { success: true };
    } catch (error) {
      console.error('Failed to update alert:', error);
      return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
    }
  });

  ipcMain.handle('alerts:delete', async (_event, id: string) => {
    try {
      db.deleteAlert(id);
      return { success: true };
    } catch (error) {
      console.error('Failed to delete alert:', error);
      return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
    }
  });

  // Custom AUEC amount handlers
  ipcMain.handle('settings:getCustomAuecAmount', async () => {
    try {
      return db.getCustomAuecAmount();
    } catch (error) {
      console.error('Failed to get custom AUEC amount:', error);
      return null;
    }
  });

  ipcMain.handle('settings:setCustomAuecAmount', async (_event, amount: number) => {
    try {
      db.setCustomAuecAmount(amount);
      return { success: true };
    } catch (error) {
      console.error('Failed to set custom AUEC amount:', error);
      return { success: false, error: error instanceof Error ? error.message : 'Unknown error' };
    }
  });

  // Auto-connect on startup
  wsClient.connect();
}

export function cleanupIpcHandlers(): void {
  if (wsClient) {
    wsClient.disconnect();
    wsClient = null;
  }
  
  // Safely remove handlers (won't throw if they don't exist)
  try {
    ipcMain.removeHandler('ws:connect');
    ipcMain.removeHandler('ws:disconnect');
    ipcMain.removeHandler('ws:getStatus');
    ipcMain.removeHandler('ws:send');
    ipcMain.removeHandler('api:getLatestPrices');
    ipcMain.removeHandler('window:minimize');
    ipcMain.removeHandler('window:maximize');
    ipcMain.removeHandler('window:close');
    ipcMain.removeHandler('window:isMaximized');
    ipcMain.removeHandler('window:hideToTray');
    ipcMain.removeHandler('alerts:getAll');
    ipcMain.removeHandler('alerts:add');
    ipcMain.removeHandler('alerts:update');
    ipcMain.removeHandler('alerts:delete');
    ipcMain.removeHandler('settings:getCustomAuecAmount');
    ipcMain.removeHandler('settings:setCustomAuecAmount');
  } catch (error) {
    // Handlers may not exist, ignore
  }
}
