const path = require('path')
const { Configuration, DefinePlugin, BannerPlugin } = require('@rspack/core')
const HtmlRspackPlugin = require('html-rspack-plugin')
const { VueLoaderPlugin } = require('vue-loader')
const { publicPath, assetsDir, outputDir, title, devPort } = require('./src/config')
const dayjs = require('dayjs')
const time = dayjs().format('YYYY-M-D HH:mm:ss')
const fs = require('fs-extra')
const { webpackBanner } = require('./layouts')

// 设置环境变量
process.env.VUE_APP_TITLE = title || 'Wagoo'
process.env.VUE_APP_UPDATE_TIME = time
process.env.BASE_URL = publicPath
// 删除这一行，避免覆盖rspack.js中设置的值
// process.env.NODE_ENV = process.env.NODE_ENV || 'development'
process.env.VUE_APP_MOCK_ENABLE = 'false' // 启用mock
process.env.VUE_APP_AUTHOR = 'Wagoo' // 设置作者

const resolve = (dir) => path.join(__dirname, dir)
// 定义一个模式变量，避免冲突
const mode = process.env.NODE_ENV || 'development'

/**
 * @type {Configuration}
 */
module.exports = {
  mode: mode,
  context: __dirname,
  entry: {
    app: './src/main.js',
  },
  output: {
    path: resolve(outputDir),
    publicPath: publicPath,
    filename: 'js/[name].[contenthash:8].js',
    chunkFilename: 'js/[name].[contenthash:8].js',
    assetModuleFilename: `${assetsDir}/[name].[hash][ext][query]`,
  },
  // 增加性能提示配置
  performance: {
    // 提高阈值以减少警告
    maxEntrypointSize: 3000000, // 3MB
    maxAssetSize: 1000000, // 1MB
    // 只在生产环境显示性能警告
    hints: mode === 'production' ? 'warning' : false,
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: [
          {
            loader: 'vue-loader',
            options: {
              compilerOptions: {
                preserveWhitespace: false,
              },
            },
          },
        ],
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@vue/cli-plugin-babel/preset'],
          },
        },
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: {
                auto: true,
                localIdentName: '[path][name]__[local]--[hash:base64:5]',
              },
            },
          },
          {
            loader: 'sass-loader',
            options: {
              additionalData: (content, loaderContext) => {
                const { resourcePath, rootContext } = loaderContext
                const relativePath = path.relative(rootContext, resourcePath)
                if (relativePath.replace(/\\/g, '/') !== 'src/styles/variables.scss') {
                  return `@import "~@/styles/variables.scss";${content}`
                }
                return content
              },
            },
          },
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024, // 10KB
          },
        },
      },
      {
        test: /\.(woff2?|eot|ttf|otf)$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 30 * 1024, // 增加到30KB
          },
        },
      },
      {
        resourceQuery: /raw/,
        type: 'asset/source',
      },
    ],
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '@': resolve('src'),
      vue$: 'vue/dist/vue.esm.js',
      path: 'path-browserify',
      fs: false,
    },
    fallback: {
      path: require.resolve('path-browserify'),
    },
  },
  plugins: [
    new VueLoaderPlugin(),
    new DefinePlugin({
      // 完全移除可能引起冲突的NODE_ENV定义，让rspack.js来处理
      'process.env.BASE_URL': JSON.stringify(process.env.BASE_URL),
      'process.env.VUE_APP_TITLE': JSON.stringify(process.env.VUE_APP_TITLE),
      'process.env.VUE_APP_MOCK_ENABLE': JSON.stringify(process.env.VUE_APP_MOCK_ENABLE),
      'process.env.VUE_APP_AUTHOR': JSON.stringify(process.env.VUE_APP_AUTHOR),
      'process.env.VUE_APP_UPDATE_TIME': JSON.stringify(process.env.VUE_APP_UPDATE_TIME),
    }),
    new HtmlRspackPlugin({
      template: './public/index.html',
      filename: 'index.html',
      title: title || 'vue-admin-better',
      inject: 'body',
      templateParameters: {
        BASE_URL: publicPath,
        VUE_APP_TITLE: process.env.VUE_APP_TITLE,
        VUE_APP_AUTHOR: process.env.VUE_APP_AUTHOR,
      },
      minify:
        mode === 'production'
          ? {
              removeComments: true,
              collapseWhitespace: true,
              removeAttributeQuotes: true,
              collapseBooleanAttributes: true,
              removeScriptTypeAttributes: true,
            }
          : false,
    }),
    // 添加版权信息到打包文件头部
    new BannerPlugin({
      banner: webpackBanner(time),
      entryOnly: false,
      include: /\.(js|css)$/,
    }),
    // 添加CopyPlugin功能，将public目录下除index.html外的文件复制到dist目录
    {
      apply(compiler) {
        compiler.hooks.afterEmit.tap('CopyPublicFolderPlugin', (compilation) => {
          // 确保目标目录存在
          const targetPath = path.resolve(__dirname, 'dist');
          fs.ensureDirSync(targetPath);
          
          // 复制public目录下的所有文件（除了index.html）
          fs.copySync(
            path.resolve(__dirname, 'public'),
            targetPath,
            {
              filter: (src) => {
                // 不复制index.html文件，因为HtmlRspackPlugin会处理它
                return !src.endsWith('index.html');
              }
            }
          );
        });
      }
    }
  ],
  optimization: {
    splitChunks: {
      automaticNameDelimiter: '-',
      chunks: 'all',
      // 增加maxInitialRequests以允许更多的初始化块
      maxInitialRequests: 6,
      // 减小最小块大小，允许更细粒度的分割
      minSize: 20000,
      cacheGroups: {
        chunk: {
          name: 'vab-chunk',
          test: /[\\/]node_modules[\\/]/,
          minSize: 131072,
          maxSize: 524288,
          chunks: 'async',
          minChunks: 2,
          priority: 10,
        },
        vue: {
          name: 'vue',
          test: /[\\/]node_modules[\\/](vue(.*)|core-js)[\\/]/,
          chunks: 'initial',
          priority: 20,
        },
        elementUI: {
          name: 'element-ui',
          test: /[\\/]node_modules[\\/]element-ui(.*)[\\/]/,
          priority: 30,
        },
        // 单独拆分常用工具库
        vendors: {
          name: 'vendors',
          test: /[\\/]node_modules[\\/](lodash|axios|qs|dayjs)[\\/]/,
          chunks: 'all',
          priority: 35,
        },
        // 拆分样式资源
        styles: {
          name: 'styles',
          test: /\.(css|scss)$/,
          chunks: 'all',
          enforce: true,
          priority: 40,
        },
        extra: {
          name: 'vab-layouts',
          test: resolve('src/layouts'),
          priority: 40,
        },
      },
    },
    // 添加压缩配置
    minimize: mode === 'production',
    // 如果是生产环境，增加tree shaking
    usedExports: mode === 'production',
  },
  devServer: {
    hot: true,
    // 修改端口，避免冲突
    port: 8090,
    historyApiFallback: true,
    static: {
      directory: path.join(__dirname, 'public'),
    },
    client: {
      overlay: {
        errors: true,
        warnings: false,
      },
    },
    open: {
      target: ['http://localhost:8090'],
    },
    // 代理 API 請求，解決開發環境跨域（dev-server 要求 proxy 為陣列）
    proxy: [
      {
        context: ['/api'],
        target: 'https://admin-api.wagoo.pet',
        // target: 'https://admin-api.wagoo.me',

        changeOrigin: true,
        pathRewrite: { '^/api': '' },
        secure: true,
      },
    ],
    setupMiddlewares: (middlewares, devServer) => {
      if (!devServer) {
        throw new Error('dev-server is not defined')
      }

      if (process.env.VUE_APP_MOCK_ENABLE === 'true') {
        const mockServer = require('./mock/index')
        mockServer(devServer.app)
      }

      return middlewares
    },
  },
}