const path = require('path')
const dotenv = require('dotenv')

const envConfig = dotenv.config()

const webpack = require('webpack')
const devConfig = require('../dev.config.js')

const serverUrl = process.env.REACT_APP_USTORE_REMOTE_SERVER_URL || ''

let ASSET_PATH =
	envConfig.parsed?.REACT_APP_ASSET_PREFIX ||
	process.env.REACT_APP_ASSET_PREFIX ||
	'/'

console.log('Using server:', process.env.REACT_APP_USTORE_REMOTE_SERVER_URL)
console.log('Using asset prefix:', ASSET_PATH)

module.exports = (env, argv) => {
	const isProduction = argv.mode === 'production'

	return {
		mode: isProduction ? 'production' : 'development',

		externals: {
			react: 'React',
			'react-dom': 'ReactDOM',
		},

		resolve: {
			alias: Object.entries(devConfig)
				.filter(([key]) => key.startsWith('$'))
				.reduce((acc, [key, value]) => {
					acc[key] = path.isAbsolute(value)
						? value
						: path.resolve(__dirname, '..', value)
					return acc
				}, {}),
			extensions: ['.js', '.jsx', '.json', '.svg'],
		},

		module: {
			rules: [
				{
					test: /\.(js|jsx)$/,
					exclude: /node_modules/,
					use: {
						loader: 'babel-loader',
						options: {
							presets: ['@babel/preset-env', '@babel/preset-react'],
						},
					},
				},
				{
					test: /\.svg$/,
					use: [
						{
							loader: require.resolve('@svgr/webpack'),
							options: {
								prettier: false,
								svgo: false,
								svgoConfig: {
									plugins: [{ removeViewBox: false }],
								},
								titleProp: true,
								ref: true,
							},
						},
						{
							loader: require.resolve('file-loader'),
							options: {
								name: 'static/media/[name].[hash][ext]',
							},
						},
					],
				},
				{
					test: /\.(png|jpe?g|gif)$/i,
					type: 'asset',
					parser: {
						dataUrlCondition: {
							maxSize: 8 * 1024,
						},
					},
					generator: {
						filename: 'static/media/[name].[hash][ext]',
					},
				},
				{
					test: /\.(woff|woff2|eot|ttf|otf)$/i,
					type: 'asset/resource',
					generator: {
						filename: 'static/fonts/[name][ext]',
					},
				},
			],
		},

		plugins: [
			new webpack.DefinePlugin({
				'process.env.NODE_ENV': JSON.stringify(
					isProduction ? 'production' : 'development'
				),
				'process.env.REACT_APP_ASSET_PREFIX': JSON.stringify(ASSET_PATH),
				'process.env.REACT_APP_USTORE_REMOTE_SERVER_URL':
					JSON.stringify(serverUrl),
				'process.env.REACT_APP_WEB_COMPONENT': JSON.stringify(
					process.env.REACT_APP_WEB_COMPONENT || ''
				),
			}),
		],

		devServer: {
			port: 3000,
			open: false,
			hot: true,
			liveReload: false,
			static: {
				directory: path.join(__dirname, '../public'),
			},
			setupMiddlewares: (middlewares, devServer) => {
				const isWebComponent = process.env.REACT_APP_WEB_COMPONENT === '1'

				if (!isWebComponent && ASSET_PATH !== '/') {
					const assetPathPrefix = ASSET_PATH.replace(/\/$/, '')
					const fs = require('fs')
					const path = require('path')

					console.log(
						`Setting up middleware for paths starting with: ${assetPathPrefix}`
					)

					middlewares.unshift({
						name: 'custom-spa-fallback',
						middleware: (req, res, next) => {
							if (!req.path.startsWith(assetPathPrefix)) {
								return next()
							}

							if (
								req.path.includes('/static/') ||
								req.path.includes('/static-internal/') ||
								req.path.includes('/assets/') ||
								req.path.includes('.js') ||
								req.path.includes('.css') ||
								req.path.includes('.map') ||
								req.path.includes('/uStoreRestAPI') ||
								req.path.includes('/ducs') ||
								req.path.includes('/widgets')
							) {
								return next()
							}

							console.log(`[Middleware] Serving index.html for ${req.path}`)

							const outputPath = devServer.compiler.outputPath
							const indexPath = path.join(outputPath, 'index.html')

							const outputFileSystem = devServer.compiler.outputFileSystem

							try {
								const html = outputFileSystem.readFileSync(indexPath, 'utf-8')
								res.setHeader('Content-Type', 'text/html')
								res.send(html)
							} catch (err) {
								console.error(
									'[Middleware] Error reading index.html:',
									err.message
								)
								next()
							}
						},
					})
				}

				const setupProxy = require('../src/setupProxy.js')
				if (typeof setupProxy === 'function') {
					setupProxy(devServer.app)
				}

				return middlewares
			},
		},
	}
}
