import { defineConfig } from 'vite';
import solid from 'vite-plugin-solid';
import path from 'path';
import { URL } from 'node:url';

const frontendDevHost = process.env.FRONTEND_DEV_HOST ?? '0.0.0.0';
const frontendDevPort = Number(
  process.env.FRONTEND_DEV_PORT ?? process.env.VITE_PORT ?? process.env.PORT ?? 5173,
);

const backendProtocol = process.env.PULSE_DEV_API_PROTOCOL ?? 'http';
const backendHost = process.env.PULSE_DEV_API_HOST ?? '127.0.0.1';
const backendPort = Number(
  process.env.PULSE_DEV_API_PORT ??
  process.env.FRONTEND_PORT ??
  process.env.PORT ??
  7655,
);

const backendUrl =
  process.env.PULSE_DEV_API_URL ?? `${backendProtocol}://${backendHost}:${backendPort}`;

const backendWsUrl =
  process.env.PULSE_DEV_WS_URL ??
  (() => {
    try {
      const parsed = new URL(backendUrl);
      parsed.protocol = parsed.protocol === 'https:' ? 'wss:' : 'ws:';
      return parsed.toString();
    } catch {
      return backendUrl
        .replace(/^http:\/\//i, 'ws://')
        .replace(/^https:\/\//i, 'wss://');
    }
  })();

export default defineConfig({
  plugins: [solid()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
    conditions: ['import', 'browser', 'default'],
  },
  server: {
    port: frontendDevPort,
    host: frontendDevHost, // Listen on all interfaces for remote access
    strictPort: true,
    proxy: {
      '/ws': {
        target: backendWsUrl,
        ws: true,
        changeOrigin: true,
        // Browser WebSocket connections are long-lived, disable timeouts
        proxyTimeout: 0,
        timeout: 0,
        configure: (proxy, _options) => {
          proxy.options.timeout = 0;
          proxy.options.proxyTimeout = 0;

          proxy.on('proxyReqWs', (proxyReq, req, socket) => {
            socket.setTimeout(0);
            socket.setNoDelay(true);
            socket.setKeepAlive(true, 30000);
          });
          proxy.on('open', (proxySocket) => {
            proxySocket.setTimeout(0);
            proxySocket.setNoDelay(true);
            proxySocket.setKeepAlive(true, 30000);
          });
        },
      },
      // SSE endpoint for AI chat streaming
      '/api/ai/execute/stream': {
        target: backendUrl,
        changeOrigin: true,
        // SSE requires special handling to prevent proxy timeouts
        // Set timeout to 0 to completely disable
        timeout: 0,
        proxyTimeout: 0,
        configure: (proxy, _options) => {
          // Completely disable http-proxy internal timeouts
          proxy.options.timeout = 0;
          proxy.options.proxyTimeout = 0;

          // Set proxy-level timeouts
          proxy.on('proxyReq', (proxyReq, req, res) => {
            // Disable socket timeouts for SSE
            req.socket.setTimeout(0);
            req.socket.setNoDelay(true);
            req.socket.setKeepAlive(true, 30000);
            // Also set on the proxy request
            proxyReq.socket?.setTimeout(0);
          });
          proxy.on('proxyRes', (proxyRes, req, res) => {
            // Disable response socket timeout
            res.socket?.setTimeout(0);
            res.socket?.setNoDelay(true);
            res.socket?.setKeepAlive(true, 30000);
            // Also disable on proxy response socket
            proxyRes.socket?.setTimeout(0);
          });
          proxy.on('error', (err, req, res) => {
            console.error('[SSE Proxy Error]', err.message);
          });
        },
      },
      // SSE endpoint for AI alert investigation (one-click investigate from alerts page)
      '/api/ai/investigate-alert': {
        target: backendUrl,
        changeOrigin: true,
        // SSE requires special handling to prevent proxy timeouts
        timeout: 0,
        proxyTimeout: 0,
        configure: (proxy, _options) => {
          proxy.options.timeout = 0;
          proxy.options.proxyTimeout = 0;

          proxy.on('proxyReq', (proxyReq, req, res) => {
            req.socket.setTimeout(0);
            req.socket.setNoDelay(true);
            req.socket.setKeepAlive(true, 30000);
            proxyReq.socket?.setTimeout(0);
          });
          proxy.on('proxyRes', (proxyRes, req, res) => {
            res.socket?.setTimeout(0);
            res.socket?.setNoDelay(true);
            res.socket?.setKeepAlive(true, 30000);
            proxyRes.socket?.setTimeout(0);
          });
          proxy.on('error', (err, req, res) => {
            console.error('[SSE Proxy Error - Investigate Alert]', err.message);
          });
        },
      },
      // SSE endpoint for AI patrol streaming
      '/api/ai/patrol/stream': {
        target: backendUrl,
        changeOrigin: true,
        timeout: 0,
        proxyTimeout: 0,
        configure: (proxy, _options) => {
          proxy.options.timeout = 0;
          proxy.options.proxyTimeout = 0;

          proxy.on('proxyReq', (proxyReq, req, res) => {
            req.socket.setTimeout(0);
            req.socket.setNoDelay(true);
            req.socket.setKeepAlive(true, 30000);
            proxyReq.socket?.setTimeout(0);
          });
          proxy.on('proxyRes', (proxyRes, req, res) => {
            res.socket?.setTimeout(0);
            res.socket?.setNoDelay(true);
            res.socket?.setKeepAlive(true, 30000);
            proxyRes.socket?.setTimeout(0);
          });
          proxy.on('error', (err, req, res) => {
            console.error('[SSE Proxy Error - Patrol Stream]', err.message);
          });
        },
      },
      '/api/agent/ws': {
        target: backendWsUrl,
        ws: true,
        changeOrigin: true,
        // Agent WebSocket connections are long-lived, disable timeouts
        // proxyTimeout: 0 disables the proxy-to-target timeout
        // timeout: 0 disables the client-to-proxy timeout
        proxyTimeout: 0,
        timeout: 0,
        configure: (proxy, _options) => {
          // Disable http-proxy's internal timeout (default is 2 minutes but seems to be 10s)
          proxy.options.timeout = 0;
          proxy.options.proxyTimeout = 0;

          proxy.on('proxyReqWs', (proxyReq, req, socket) => {
            // Disable socket timeouts for WebSocket connections
            socket.setTimeout(0);
            socket.setNoDelay(true);
            socket.setKeepAlive(true, 30000);
          });
          proxy.on('open', (proxySocket) => {
            // Also disable timeout on the proxy socket
            proxySocket.setTimeout(0);
            proxySocket.setNoDelay(true);
            proxySocket.setKeepAlive(true, 30000);
          });
          proxy.on('error', (err, req, res) => {
            console.error('[Agent WS Proxy Error]', err.message);
          });
        },
      },
      '/api': {
        target: backendUrl,
        changeOrigin: true,
        cookieDomainRewrite: '',
      },
      '/install-docker-agent.sh': {
        target: backendUrl,
        changeOrigin: true,
      },
      '/install-container-agent.sh': {
        target: backendUrl,
        changeOrigin: true,
      },
      '/install-host-agent.sh': {
        target: backendUrl,
        changeOrigin: true,
      },
      '/install-host-agent.ps1': {
        target: backendUrl,
        changeOrigin: true,
      },
      '/install.sh': {
        target: backendUrl,
        changeOrigin: true,
      },
      '/install.ps1': {
        target: backendUrl,
        changeOrigin: true,
      },
      '/download': {
        target: backendUrl,
        changeOrigin: true,
      },
    },
  },
  build: {
    target: 'esnext',
  },
  test: {
    environment: 'jsdom',
    globals: true,
    setupFiles: ['./src/test/setup.ts'],
  },
});
