/// <reference types="vitest" />
import type { Plugin } from 'vite'
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import { resolve } from 'path'
import { spawnSync } from 'node:child_process'

const REPO_ROOT = resolve(__dirname, '../../../..')

/**
 * Vite plugin that re-runs scripts/build-catalog.mjs whenever any
 * platform/<name>/blueprint.yaml or products/<name>/blueprint.yaml changes
 * during dev. Keeps the wizard's StepComponents grid live-reloading without
 * requiring a manual `npm run build:catalog` after every Blueprint edit.
 *
 * Build mode runs the same script via `prebuild` in package.json, so this
 * plugin only matters in dev.
 */
function rebuildCatalogOnYamlChange(): Plugin {
  const catalogScript = resolve(__dirname, 'scripts/build-catalog.mjs')

  function runCatalog(reason: string) {
    const r = spawnSync(process.execPath, [catalogScript], { stdio: 'inherit' })
    if (r.status !== 0) {
      // eslint-disable-next-line no-console
      console.error(`[build-catalog] failed (${reason})`)
    }
  }

  return {
    name: 'catalyst-rebuild-catalog',
    apply: 'serve',
    configureServer(server) {
      // Watch the entire monorepo's platform/ + products/ for blueprint.yaml
      // changes. Vite's chokidar instance handles dedup + glob.
      server.watcher.add([
        resolve(REPO_ROOT, 'platform/**/blueprint.yaml'),
        resolve(REPO_ROOT, 'products/**/blueprint.yaml'),
      ])
      const isBlueprintFile = (path: string) => /(?:^|\/)blueprint\.yaml$/.test(path)
      const handle = (event: string) => (path: string) => {
        if (!isBlueprintFile(path)) return
        runCatalog(`${event} ${path}`)
        server.ws.send({ type: 'full-reload', path: '*' })
      }
      server.watcher.on('add', handle('add'))
      server.watcher.on('change', handle('change'))
      server.watcher.on('unlink', handle('unlink'))
    },
  }
}

export default defineConfig({
  base: '/sovereign/',
  plugins: [tailwindcss(), react(), rebuildCatalogOnYamlChange()],
  resolve: {
    alias: {
      '@': resolve(__dirname, './src'),
    },
  },
  server: {
    port: 5173,
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
      },
      // The UI is served under `base: '/sovereign/'`, so fetch calls
      // emitted by `${API_BASE}/v1/...` (where API_BASE = `/sovereign/api`)
      // arrive here as `/sovereign/api/...`. Rewrite to `/api/...` so
      // catalyst-api receives the canonical path. Production traefik
      // performs the same prefix strip, so dev mirrors prod.
      '/sovereign/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (p: string) => p.replace(/^\/sovereign/, ''),
      },
    },
  },
  // Vitest config — drives `npm run test` in this package. The test runner
  // shares Vite's `resolve.alias` so `@/...` imports work in tests too.
  test: {
    environment: 'jsdom',
    globals: false,
    css: false,
    include: ['src/**/*.test.{ts,tsx}'],
  },
})
