import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import path from 'node:path'
import fs from 'node:fs'

const monacoEditorPath = path.resolve(
  __dirname,
  '../node_modules/.pnpm/monaco-editor@0.55.1/node_modules/monaco-editor',
);
const workspaceRoot = path.resolve(__dirname, '..', '..');
const commonPlatRoot = path.join(workspaceRoot, 'learning_ai_common_plat');

function commonPlatSourceEntry(pkg: string): string | null {
  const sourceEntry = path.join(commonPlatRoot, 'packages', pkg, 'src', 'index.ts');
  return fs.existsSync(sourceEntry) ? sourceEntry : null;
}

// Resolve a @bytelyst/* package: prefer web/node_modules, fall back to vendor/
function bytelystAlias(pkg: string): string {
  const sourceEntry = commonPlatSourceEntry(pkg);
  if (sourceEntry) return sourceEntry;

  const nmPath     = path.resolve(__dirname, 'node_modules/@bytelyst', pkg);
  const vendorPath = path.resolve(__dirname, '../vendor/bytelyst', pkg);
  if (fs.existsSync(nmPath))     return nmPath;
  if (fs.existsSync(vendorPath)) return vendorPath;
  return nmPath; // let Vite surface the missing-module error
}

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    react(),
    tailwindcss(),
  ],
  // Shared files (../shared/*.ts) live outside web/ so Vite resolves their imports
  // from the repo root where @bytelyst/* are not installed. Redirect all @bytelyst/*
  // imports first to web/node_modules, then fall back to the monorepo vendor/ dir.
  resolve: {
    // Deduplicate React so the vendored react-auth dist resolves the same react instance
    dedupe: ['react', 'react-dom', 'react/jsx-runtime', 'react-router-dom'],
    alias: [
      // Vendor packages that live only in vendor/ (not in web/node_modules/)
      { find: '@bytelyst/api-client',       replacement: bytelystAlias('api-client') },
      { find: '@bytelyst/design-tokens',    replacement: path.join(commonPlatRoot, 'packages', 'design-tokens') },
      { find: '@bytelyst/errors',           replacement: bytelystAlias('errors') },
      { find: '@bytelyst/kill-switch-client', replacement: bytelystAlias('kill-switch-client') },
      { find: '@bytelyst/react-auth',       replacement: bytelystAlias('react-auth') },
      { find: '@bytelyst/telemetry-client', replacement: bytelystAlias('telemetry-client') },
      { find: '@bytelyst/ui',               replacement: bytelystAlias('ui') },
      // Monaco is an explicit web dependency, but this workspace often runs
      // against pnpm's root store without a web/node_modules symlink when the
      // private mobile registry is unavailable. Keep local worker imports
      // resolvable for Vite in that partially installed state.
      { find: /^monaco-editor$/,            replacement: monacoEditorPath },
      { find: /^monaco-editor\/(.+)/,       replacement: `${monacoEditorPath}/$1` },
      // General catch-all: every other @bytelyst/* → web/node_modules
      {
        find: /^@bytelyst\/(.+)/,
        replacement: path.resolve(__dirname, 'node_modules/@bytelyst/$1'),
      },
    ],
  },
  test: {
    environment: 'jsdom',
    setupFiles: ['./src/test/setup.ts'],
    include: ['src/**/*.test.ts', 'src/**/*.test.tsx', 'src/**/*.dom.test.tsx'],
  },
  build: {
    chunkSizeWarningLimit: 5000,
    rollupOptions: {
      output: {
        manualChunks(id) {
          if (id.includes('monaco-editor') || id.includes('@monaco-editor')) {
            return 'monaco-vendor';
          }
          if (id.includes('/node_modules/lucide-react/')) {
            return 'ui-vendor';
          }
          if (id.includes('/node_modules/')) {
            return 'vendor';
          }
          return undefined;
        },
      },
    },
  },
})
