import {
	readFileSync,
	writeFileSync,
	existsSync,
	readdirSync,
	copyFileSync,
	rmSync,
	unlinkSync
} from 'fs';
import { resolve } from 'path';
import type { Plugin } from 'vite';

const GUIDE_FOR_FRONTEND = `
<!--
  This is a static build of the frontend.
  It is automatically generated by the build process.
  Do not edit this file directly.
  To make changes, refer to the "Web UI" section in the README.
-->
`.trim();

const OUTPUT_DIR = process.env.LLAMA_UI_OUT_DIR ?? './dist';

export function llamaCppBuildPlugin(): Plugin {
	return {
		name: 'llamacpp:build',
		apply: 'build',
		closeBundle() {
			setTimeout(() => {
				try {
					const outDir = resolve(OUTPUT_DIR);
					const indexPath = resolve(outDir, 'index.html');
					if (!existsSync(indexPath)) return;

					let content = readFileSync(indexPath, 'utf-8');

					// Inline favicon as base64 data URL
					const faviconPath = resolve('static/favicon.svg');
					if (existsSync(faviconPath)) {
						const faviconContent = readFileSync(faviconPath, 'utf-8');
						const faviconBase64 = Buffer.from(faviconContent).toString('base64');
						const faviconDataUrl = `data:image/svg+xml;base64,${faviconBase64}`;
						content = content.replace(/href="[^"]*favicon\.svg"/g, `href="${faviconDataUrl}"`);
						console.log('✓ Inlined favicon.svg as base64 data URL');
					}

					content = content.replace(/\r/g, '');
					content = GUIDE_FOR_FRONTEND + '\n' + content;

					// Keep the Vite hash as a query string so each build busts the browser cache
					content = content.replace(/\/_app\/immutable\/bundle\.([^".]+)\.js/g, './bundle.js?$1');
					content = content.replace(
						/\/_app\/immutable\/assets\/bundle\.([^".]+)\.css/g,
						'./bundle.css?$1'
					);
					content = content.replace(/__sveltekit_[a-z0-9]+/g, '__sveltekit__');

					writeFileSync(indexPath, content, 'utf-8');
					console.log('✓ Updated index.html');

					// Copy bundle.*.js -> bundle.js at output root
					const immutableDir = resolve(outDir, '_app/immutable');
					const bundleDir = resolve(outDir, '_app/immutable/assets');

					if (existsSync(immutableDir)) {
						const jsFiles = readdirSync(immutableDir).filter((f) => f.match(/^bundle\..+\.js$/));
						if (jsFiles.length > 0) {
							copyFileSync(resolve(immutableDir, jsFiles[0]), resolve(outDir, 'bundle.js'));
							// Normalize __sveltekit_<hash> to __sveltekit__ in bundle.js
							const bundleJsPath = resolve(outDir, 'bundle.js');
							let bundleJs = readFileSync(bundleJsPath, 'utf-8');
							bundleJs = bundleJs.replace(/__sveltekit_[a-z0-9]+/g, '__sveltekit__');
							writeFileSync(bundleJsPath, bundleJs, 'utf-8');
							console.log(`✓ Copied ${jsFiles[0]} -> bundle.js`);
						}
					}

					// Copy bundle.*.css -> bundle.css at output root
					if (existsSync(bundleDir)) {
						const cssFiles = readdirSync(bundleDir).filter((f) => f.match(/^bundle\..+\.css$/));
						if (cssFiles.length > 0) {
							copyFileSync(resolve(bundleDir, cssFiles[0]), resolve(outDir, 'bundle.css'));
							console.log(`✓ Copied ${cssFiles[0]} -> bundle.css`);
						}
					}

					// Cleanup: remove _app directory, favicon.svg, and legacy index.html.gz
					const appDir = resolve(outDir, '_app');
					if (existsSync(appDir)) {
						rmSync(appDir, { recursive: true, force: true });
						console.log('✓ Removed _app directory');
					}

					const faviconOut = resolve(outDir, 'favicon.svg');
					if (existsSync(faviconOut)) {
						unlinkSync(faviconOut);
						console.log('✓ Removed favicon.svg');
					}
				} catch (error) {
					console.error('Failed to process build output:', error);
				}
			}, 100);
		}
	};
}
