import { fileURLToPath, URL } from 'node:url'

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
// import vueDevTools from 'vite-plugin-vue-devtools'
import Components from 'unplugin-vue-components/vite'
import { PrimeVueResolver } from '@primevue/auto-import-resolver'
import Info from 'unplugin-info/vite'
import AutoImport from 'unplugin-auto-import/vite'
import { unheadComposablesImports } from 'unhead'
import mockData, { type RouteConfig } from 'vite-plugin-mock-data'
import manifestJSON from 'rollup-plugin-manifest-json'
import { type ManifestOptions } from 'rollup-plugin-manifest-json/lib/types'

// https://vite.dev/config/
export default defineConfig(({ mode }) => {
  console.log('Building in mode', mode)

  process.env = { ...loadEnv(mode, process.cwd()), ...process.env }

  const manifest: ManifestOptions & { id?: string } = Object.fromEntries(
    Object.entries({
      name: process.env.VITE_MANIFEST_NAME,
      short_name: process.env.VITE_MANIFEST_SHORT_NAME,
      id: process.env.VITE_MANIFEST_ID,
      start_url: process.env.VITE_MANIFEST_START_URL,
      scope: process.env.VITE_MANIFEST_SCOPE,
    }).filter((entry) => entry[1] !== undefined),
  )

  return {
    build: {
      sourcemap: mode === 'development',
      reportCompressedSize: false,

      rollupOptions: {
        output: {
          manualChunks(id) {
            if (id.includes('node_modules')) {
              // PouchDB и его плагины
              if (id.includes('pouchdb')) {
                return 'vendor_pouchdb'
              }

              // QR-коды и библиотеки для работы с ними
              if (id.includes('qr-code-styling')) {
                return 'vendor_qr-code-styling'
              }

              // PrimeVue и связанные модули
              if (id.includes('primevue')) {
                return 'vendor_primevue'
              }

              // SVGO и зависимости
              if (id.includes('svgo') || id.includes('@trysound')) {
                return 'vendor_svgo'
              }

              // Танстэк Vue Query и ядро
              if (id.includes('@tanstack')) {
                return 'vendor_tanstack-query'
              }

              // Vue и связанные библиотеки
              if (id.includes('vue')) {
                return 'vendor_vue'
              }

              if (id.includes('css-tree')) {
                return 'vendor_css-tree'
              }

              if (id.includes('css-what')) {
                return 'vendor_css-what'
              }

              if (id.includes('domutils')) {
                return 'vendor_domutils'
              }

              if (id.includes('source-map-js')) {
                return 'vendor_source-map-js'
              }

              if (id.includes('csso')) {
                return 'vendor_csso'
              }
              if (id.includes('entities')) {
                return 'vendor_entities'
              }

              // Остальные модули из node_modules в vendor
              return 'vendor'
            }

            if (id.includes('src/api/')) {
              return 'api'
            }
            if (id.includes('src/utils/')) {
              return 'utils'
            }

            // По умолчанию ничего не делим
            return null
          },
        },
      },
    },
    plugins: [
      vue(),

      Info(),

      AutoImport({
        imports: [
          'vue',
          'vue-router',
          unheadComposablesImports[0],
          {
            from: '@tanstack/vue-query',
            imports: ['useQuery', 'useMutation'],
          },
          // {
          //   from: '@hereconnect/types',
          //   type: true,
          // },
        ],
      }),

      Components({
        resolvers: [PrimeVueResolver()],
        dirs: ['src/components', 'src/layouts'],
      }),

      // vueDevTools(),

      mockData({
        mockRoutes: {
          '/manifest.json': {
            async handler(req, res) {
              const { default: manifestJSON } = await import('./src/manifest.json')
              const result = { ...manifestJSON, ...manifest, id: `//${req.headers.host}` }
              res.statusCode = 200
              res.setHeader('Content-Type', 'application/json;charset=utf-8')
              res.end(JSON.stringify(result, null, 2))
            },
          } satisfies RouteConfig,
          'POST /debug': {
            async handler(req, res) {
              process.stdout.write('\ndebug: ')
              req.pipe(process.stdout)
              res.statusCode = 200
              res.setHeader('Content-Type', 'application/json')
              res.end('true')
            },
          } satisfies RouteConfig,
        },
      }),
      {
        ...manifestJSON({
          input: 'src/manifest.json', // Required
          output: './manifest.json',
          minify: mode === 'production',
          manifest,
        }),
        apply: 'build',
      },
    ],
    define: {
      global: 'window', // it is needed for PouchDB
    },
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url)),
      },
    },
    server: {
      proxy: {
        '/api': {
          target: process.env.VITE_PROXY_API_URL,
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/api/, ''),
        },
      },
    },
  }
})
