import { defineConfig, type Plugin } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';
import path from 'path';
import { readFileSync } from 'fs';

// Vite invalidates its dep prebundle by hashing the nearest lockfile up from root — which in a
// production install is the WORKSPACE's lockfile (backend deps only). `bloby update` swaps
// frontend deps in the root node_modules without ever touching that lockfile, so prebundles
// silently went stale across updates. Keying the cache dir by package version forces exactly one
// clean re-optimize per release while keeping persistence across normal restarts.
// (vite-dev.ts sweeps old .vite-v* dirs at boot.)
let cacheVersion = 'dev';
try { cacheVersion = JSON.parse(readFileSync(path.resolve(__dirname, 'package.json'), 'utf-8')).version || 'dev'; } catch {}
const workspaceClient = process.env.BLOBY_WORKSPACE
  ? path.join(process.env.BLOBY_WORKSPACE, 'client')
  : path.resolve(__dirname, 'workspace/client');

// Backs workspace-guard.js's reconnect staleness check: Vite's reload-on-reconnect
// is suppressed client-side, and on reconnect the client fetches this stamp and
// reloads ONLY if frontend code actually changed while it was disconnected.
// Seeded with Date.now() (not 0) so a Vite/supervisor restart — which resets this
// module — always reads as "changed" → clients reload after restarts, which is
// exactly right (in-memory HMR state is gone).
function blobyFeStamp(): Plugin {
  let stamp = Date.now();
  return {
    name: 'bloby-fe-stamp',
    // hotUpdate (not legacy handleHotUpdate): fires on create/update/delete and
    // for .html edits that trigger full-reload. It runs once per environment, so
    // only count the client one.
    hotUpdate() {
      if (this.environment.name !== 'client') return;
      stamp++;
    },
    configureServer(server) {
      // Reached through the supervisor's catch-all proxy to Vite. connect mounts
      // by prefix, so reject subpaths to keep this an exact match.
      server.middlewares.use('/__bloby/fe-stamp', (req, res, next) => {
        const rest = (req.url || '').split('?')[0];
        if (rest !== '' && rest !== '/') return next();
        res.setHeader('Content-Type', 'application/json');
        res.setHeader('Cache-Control', 'no-store');
        res.end(JSON.stringify({ stamp }));
      });
    },
  };
}

export default defineConfig({
  root: process.env.BLOBY_WORKSPACE
    ? path.join(process.env.BLOBY_WORKSPACE, 'client')
    : 'workspace/client',
  cacheDir: path.join(workspaceClient, 'node_modules', '.vite-v' + cacheVersion),
  resolve: {
    alias: {
      '@': process.env.BLOBY_WORKSPACE
        ? path.join(process.env.BLOBY_WORKSPACE, 'client/src')
        : path.resolve(__dirname, 'workspace/client/src'),
    },
    // Prevent React dual-instance when workspace/node_modules has its own copy
    dedupe: ['react', 'react-dom'],
  },
  build: {
    outDir: '../../dist',
    emptyOutDir: true,
  },
  server: {
    port: 5173,
    proxy: {
      '/app/api': {
        target: 'http://localhost:7404',
        rewrite: (path) => path.replace(/^\/app/, ''),
      },
      '/api': 'http://localhost:7400',
    },
    warmup: {
      clientFiles: ['./src/main.tsx'],
    },
    watch: {
      ignored: [
        '**/app.db*',
        '**/.backend.log',
        '**/files/**',
        '**/.env',
        '**/backend/**',
        '**/*.db',
        '**/*.db-journal',
        '**/*.db-wal',
        '**/*.db-shm',
        '**/*.sqlite',
        '**/*.log',
      ],
    },
  },
  optimizeDeps: {
    include: [
      'react',
      'react-dom',
      'react-dom/client',
      'react/jsx-runtime',
      'react-router',
      'driver.js',
      'lucide-react',
      'framer-motion',
      'recharts',
      'zustand',
      'sonner',
      'use-sync-external-store',
      'use-sync-external-store/shim',
      // Statically imported by the workspace template's UI kit (button.tsx etc.) but missing
      // here — the first request for an un-prebundled dep triggers a mid-session
      // re-optimization AND a Vite-forced full page reload. Pre-bundle them up front.
      'radix-ui',
      'class-variance-authority',
      'clsx',
      'tailwind-merge',
    ],
  },
  plugins: [react(), tailwindcss(), blobyFeStamp()],
});
