import {fileURLToPath, URL} from 'node:url'
import type {IncomingMessage, ServerResponse} from 'node:http'
import type {ProxyOptions} from 'vite'
import {defineConfig, loadEnv} from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import DefineOptions from 'unplugin-vue-define-options/vite'
import path from 'path'
import {createHtmlPlugin} from 'vite-plugin-html'
import fs from 'fs'
// import vueDevTools from 'vite-plugin-vue-devtools'
const envDir = './env'
// 自定义插件：重命名入口文件
const renameHtmlPlugin = (outDir: string, entry: string) => {
  return {
    name: 'rename-html',
    closeBundle: () => {
      const buildDir = path.resolve(__dirname, outDir)
      const oldFile = path.join(buildDir, entry)
      const newFile = path.join(buildDir, 'index.html')

      // 检查文件是否存在
      if (fs.existsSync(oldFile)) {
        // 删除已存在的 index.html
        if (fs.existsSync(newFile)) {
          fs.unlinkSync(newFile)
        }
        // 重命名文件
        fs.renameSync(oldFile, newFile)
      }
    },
  }
}

const createHistoryEntryFallbackPlugin = (basePath: string, entry: string) => {
  const normalizedBasePath = basePath.endsWith('/') ? basePath : `${basePath}/`
  const basePathWithoutSlash = normalizedBasePath.replace(/\/$/, '')

  const shouldRewriteToEntry = (req: IncomingMessage) => {
    if (!req.url || !req.method || !['GET', 'HEAD'].includes(req.method)) {
      return false
    }

    const url = req.url.split('?')[0]
    const accept = req.headers.accept || ''
    const isHtmlRequest = accept.includes('text/html') || accept.includes('*/*')
    const isBaseRoute = url === basePathWithoutSlash || url === normalizedBasePath
    const isHistoryRoute = url.startsWith(normalizedBasePath) && !url.slice(normalizedBasePath.length).includes('.')
    const isApiRequest = url.startsWith(`${normalizedBasePath}api`)

    return isHtmlRequest && !isApiRequest && (isBaseRoute || isHistoryRoute)
  }

  return {
    name: 'history-entry-fallback',
    configureServer(server: {middlewares: {use: (handler: (req: IncomingMessage, res: ServerResponse, next: () => void) => void) => void}}) {
      server.middlewares.use((req, res, next) => {
        if (req.url === '/') {
          res.statusCode = 302
          res.setHeader('Location', normalizedBasePath)
          res.end()
          return
        }
        if (shouldRewriteToEntry(req)) {
          req.url = `/${entry}`
        }
        next()
      })
    },
  }
}
// https://vite.dev/config/
export default defineConfig((conf: any) => {
  const mode = conf.mode
  const ENV = loadEnv(mode, envDir)
  const proxyConf: Record<string, string | ProxyOptions> = {}
  proxyConf['/admin/api'] = {
    target: 'http://127.0.0.1:8080',
    changeOrigin: true,
  }
  proxyConf['/chat/api'] = {
    target: 'http://127.0.0.1:8080',
    changeOrigin: true,
  }
  proxyConf['/doc'] = {
    target: 'http://127.0.0.1:8080',
    changeOrigin: true,
    rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
  }
  proxyConf['/schema'] = {
    target: 'http://127.0.0.1:8080',
    changeOrigin: true,
    rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
  }
  proxyConf['/static'] = {
    target: 'http://127.0.0.1:8080',
    changeOrigin: true,
    rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
  }

  // 前端静态资源转发到本身
  proxyConf[`^${ENV.VITE_BASE_PATH}.+\/oss\/file\/.*$`] = {
    target: `http://127.0.0.1:8080`,
    changeOrigin: true,
  }
  // 前端静态资源转发到本身
  proxyConf[`^${ENV.VITE_BASE_PATH}oss\/file\/.*$`] = {
    target: `http://127.0.0.1:8080`,
    changeOrigin: true,
  }
  proxyConf[`^${ENV.VITE_BASE_PATH}oss\/get_url\/.*$`] = {
    target: `http://127.0.0.1:8080`,
    changeOrigin: true,
  }
  return {
    preflight: false,
    lintOnSave: false,
    base: './',
    envDir: envDir,
    plugins: [
      vue(),
      vueJsx(),
      DefineOptions(),
      createHtmlPlugin({template: ENV.VITE_ENTRY}),
      createHistoryEntryFallbackPlugin(ENV.VITE_BASE_PATH, ENV.VITE_ENTRY),
      renameHtmlPlugin(`dist${ENV.VITE_BASE_PATH}`, ENV.VITE_ENTRY),
    ],
    server: {
      cors: true,
      host: '0.0.0.0',
      port: Number(ENV.VITE_APP_PORT),
      strictPort: true,
      proxy: proxyConf,
    },
    build: {
      outDir: `dist${ENV.VITE_BASE_PATH}`,
      rollupOptions: {
        input: ENV.VITE_ENTRY,
        output: {
          manualChunks: {
            'vendor-vue': ['vue', 'vue-router', 'pinia', 'vue-i18n', '@vueuse/core'],
            'vendor-element': ['element-plus', '@element-plus/icons-vue'],
            'vendor-markdown': ['md-editor-v3', 'marked', 'highlight.js', 'katex', 'mermaid'],
            'vendor-workflow': ['@logicflow/core', '@logicflow/extension', '@antv/layout'],
            'vendor-charts': ['echarts'],
          },
        },
      },
    },
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url)),
      },
    },
  }
})
