/// <reference types="vitest" />
import { dirname, extname, relative, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import fs from 'node:fs'

import react from '@vitejs/plugin-react'
import { glob } from 'glob'
import { defineConfig } from 'vite'
import dts from 'vite-plugin-dts'
import { libInjectCss } from 'vite-plugin-lib-inject-css'
// import ensureDirectives from './plugins/rollup-plugin-ensure-directives'
import preserveDirectives from 'rollup-preserve-directives'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    libInjectCss(),
    dts({
      include: ['lib'],
      exclude: [
        'node_modules',
        '**/*.css',
        '**/*.test.ts',
        '**/*.stories.tsx',
        'lib/tokens/*.mdx',
        'lib/tokens/*.css',
        'lib/tokens/*.tsx',
      ],
      // rollupTypes: true,
      bundledPackages: ['class-variance-authority', 'clsx'],
    }),
    preserveDirectives(),
  ],
  build: {
    cssCodeSplit: true,
    copyPublicDir: false,
    lib: {
      entry: [resolve(__dirname, 'lib/index.ts')],
      formats: ['es'],
    },
    rollupOptions: {
      plugins: [],
      external: [
        'react',
        'react-dom',
        'react/jsx-runtime',
        'react-aria-components',
      ],
      onwarn(warning, defaultHandler) {
        if (
          warning.code === 'MODULE_LEVEL_DIRECTIVE' &&
          warning.message.includes('use client')
        ) {
          return
        }

        // When using the directive 'use client' in components, rollup throws an error.
        // See: https://github.com/vitejs/vite/issues/15012#issuecomment-1815854072
        // We ignore sourcemap_error on the first character for component files
        // to be caused by the 'use client' directive
        if (
          warning.code === 'SOURCEMAP_ERROR' &&
          warning.loc?.file &&
          warning.loc.line === 1 &&
          warning.loc.column === 0
        ) {
          if (fs.statSync(warning.loc.file)) {
            const file = fs.readFileSync(warning.loc.file, {
              encoding: 'utf-8',
            })
            const lines = file.split('\n')

            if (lines[0] === "'use client'") {
              return
            }
          }
        }

        defaultHandler(warning)
      },
      input: Object.fromEntries(
        glob
          .sync(['lib/**/*.{ts,tsx,css}'], {
            ignore: ['**/types.ts', '**/*.stories.{ts,tsx}', 'lib/tokens/*'],
          })
          .map((file) => {
            return [
              // The name of the entry point
              // lib/nested/foo.ts becomes nested/foo
              relative(
                'lib',
                file.slice(0, file.length - extname(file).length)
              ),
              // The absolute path to the entry file
              // lib/nested/foo.ts becomes /project/lib/nested/foo.ts
              fileURLToPath(new URL(file, import.meta.url)),
            ]
          })
      ),
      output: {
        assetFileNames: (assetInfo) => {
          if (assetInfo.originalFileNames.length > 0) {
            const originalFileName = assetInfo.originalFileNames[0]
            if (originalFileName.indexOf('/components/') >= 0) {
              return `${dirname(originalFileName).replace('lib/', '')}/[name]-[hash][extname]`
            }
          }
          return `[name][extname]`
        },
        entryFileNames: '[name].js',
      },
    },
  },
})
