import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { VitePWA } from 'vite-plugin-pwa'
import path from 'path'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    react(),
    VitePWA({
      registerType: 'autoUpdate',
      includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'android-chrome-192x192.png', 'android-chrome-512x512.png'],
      manifest: false, // We use our own manifest at /static/site.webmanifest
      workbox: {
        // Cache static assets
        globPatterns: ['**/*.{js,css,html,ico,png,svg,woff,woff2}'],
        // Runtime caching rules
        runtimeCaching: [
          {
            // Cache pattern preview images
            urlPattern: /\/static\/.*\.webp$/,
            handler: 'CacheFirst',
            options: {
              cacheName: 'pattern-previews',
              expiration: {
                maxEntries: 500,
                maxAgeSeconds: 60 * 60 * 24 * 30, // 30 days
              },
            },
          },
          {
            // Cache static assets from backend
            urlPattern: /\/static\/.*\.(png|jpg|ico|svg)$/,
            handler: 'CacheFirst',
            options: {
              cacheName: 'static-assets',
              expiration: {
                maxEntries: 100,
                maxAgeSeconds: 60 * 60 * 24 * 7, // 7 days
              },
            },
          },
          {
            // Network-first for API calls (always want fresh data, but cache as fallback)
            urlPattern: /\/api\//,
            handler: 'NetworkFirst',
            options: {
              cacheName: 'api-cache',
              expiration: {
                maxEntries: 50,
                maxAgeSeconds: 60 * 5, // 5 minutes
              },
              networkTimeoutSeconds: 10,
            },
          },
        ],
      },
      devOptions: {
        enabled: false, // Disable in dev mode to avoid caching issues
      },
    }),
  ],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
  server: {
    port: parseInt(process.env.PORT || '5173'),
    host: true, // Listen on all interfaces (0.0.0.0) for mobile/network access
    allowedHosts: true, // Allow all hosts for local network development
    proxy: {
      // WebSocket endpoints
      '/ws': {
        target: 'ws://localhost:8080',
        ws: true,
        // Suppress connection errors (common during backend restarts)
        configure: (proxy, _options) => {
          // Handle proxy errors silently for expected connection issues
          const isConnectionError = (err: Error & { code?: string }) => {
            const msg = err.message || ''
            const code = err.code || ''
            // Check error code (most reliable for AggregateError)
            if (['ECONNRESET', 'ECONNREFUSED', 'EPIPE', 'ETIMEDOUT'].includes(code)) {
              return true
            }
            // Check message as fallback
            if (msg.includes('ECONNRESET') || msg.includes('ECONNREFUSED') ||
                msg.includes('EPIPE') || msg.includes('ETIMEDOUT') ||
                msg.includes('AggregateError')) {
              return true
            }
            return false
          }

          const handleError = (err: Error) => {
            if (isConnectionError(err)) {
              return // Silently ignore connection errors
            }
            // Only log unexpected errors
            console.error('WebSocket proxy error:', err.message)
          }

          proxy.on('error', handleError)
          proxy.on('proxyReqWs', (_proxyReq, _req, socket) => {
            socket.on('error', (err) => {
              if (!isConnectionError(err)) {
                console.error('WebSocket socket error:', err.message)
              }
            })
          })
        },
      },
      // All /api endpoints
      '/api': 'http://localhost:8080',
      // Captive portal detection probes (hotspot mode)
      '/hotspot-detect.html': 'http://localhost:8080',
      '/generate_204': 'http://localhost:8080',
      '/connecttest.txt': 'http://localhost:8080',
      // Static assets
      '/static': 'http://localhost:8080',
      // Preview images
      '/preview': 'http://localhost:8080',
      // Legacy root-level API endpoints (for backwards compatibility)
      // Pattern execution
      '/send_home': 'http://localhost:8080',
      '/send_coordinate': 'http://localhost:8080',
      '/stop_execution': 'http://localhost:8080',
      '/force_stop': 'http://localhost:8080',
      '/soft_reset': 'http://localhost:8080',
      '/controller_restart': 'http://localhost:8080',
      '/pause_execution': 'http://localhost:8080',
      '/resume_execution': 'http://localhost:8080',
      '/skip_pattern': 'http://localhost:8080',
      '/reorder_playlist': 'http://localhost:8080',
      '/add_to_queue': 'http://localhost:8080',
      '/run_theta_rho': 'http://localhost:8080',
      '/run_playlist': 'http://localhost:8080',
      // Movement
      '/move_to_center': 'http://localhost:8080',
      '/move_to_perimeter': 'http://localhost:8080',
      // Speed
      '/set_speed': 'http://localhost:8080',
      // Connection
      '/serial_status': 'http://localhost:8080',
      '/list_serial_ports': 'http://localhost:8080',
      '/connect': 'http://localhost:8080',
      '/disconnect': 'http://localhost:8080',
      '/recover_sensor_homing': 'http://localhost:8080',
      // Patterns
      '/list_theta_rho_files': 'http://localhost:8080',
      '/list_theta_rho_files_with_metadata': 'http://localhost:8080',
      '/preview_thr': 'http://localhost:8080',
      '/preview_thr_batch': 'http://localhost:8080',
      '/get_theta_rho_coordinates': 'http://localhost:8080',
      '/delete_theta_rho_file': 'http://localhost:8080',
      '/upload_theta_rho': 'http://localhost:8080',
      // Playlists
      '/list_all_playlists': 'http://localhost:8080',
      '/get_playlist': 'http://localhost:8080',
      '/create_playlist': 'http://localhost:8080',
      '/modify_playlist': 'http://localhost:8080',
      '/delete_playlist': 'http://localhost:8080',
      '/rename_playlist': 'http://localhost:8080',
      '/add_to_playlist': 'http://localhost:8080',
      // LED
      '/get_led_config': 'http://localhost:8080',
      '/set_led_config': 'http://localhost:8080',
    },
  },
  build: {
    outDir: '../static/dist',
    emptyOutDir: true,
  },
})
