import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, join } from "node:path";
import type { FileContent } from "./git.ts";

const __dirname = dirname(fileURLToPath(import.meta.url));

const CODEMIRROR_BUNDLE = readFileSync(join(__dirname, "assets/codemirror-bundle.js"), "utf8");
const CODEMIRROR_APP = readFileSync(join(__dirname, "assets/codemirror-app.js"), "utf8");
const REVIEW_CSS = readFileSync(join(__dirname, "assets/review.css"), "utf8");
const ICON_PR = readFileSync(join(__dirname, "assets/git-pull-request-favicon.svg"), "utf8");
const PULL_REQUEST_FAVICON_DATA_URL = `data:image/svg+xml;base64,${Buffer.from(ICON_PR).toString("base64")}`;
const ICON_FILE = readFileSync(join(__dirname, "assets/file.svg"), "utf8");
const ICON_FOLDER = readFileSync(join(__dirname, "assets/folder.svg"), "utf8");

export interface ReviewHeaderContext {
	repoName: string;
	branch: string;
	base: string;
	repoRoot?: string;
}

export function renderReviewHtml(
	files: FileContent[],
	title: string,
	context?: ReviewHeaderContext,
): string {
	const resolvedContext = context ?? parseContextFromTitle(title);
	const { branch, base } = resolvedContext;

	const totalAdditions = files.reduce((sum, f) => sum + f.additions, 0);
	const totalDeletions = files.reduce((sum, f) => sum + f.deletions, 0);
	const fileCount = files.length;

	return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="dark" />
<title>${escapeHtml(title)}</title>
<link rel="icon" href="${PULL_REQUEST_FAVICON_DATA_URL}" />
<style>${REVIEW_CSS}</style>
</head>
<body>
<main class="review-shell">
	<header class="status-bar">
		<div class="status-bar-left">
			${ICON_PR}
			<span class="status-bar-item status-bar-branch">
				${escapeHtml(base)}
				<span class="status-bar-sep">←</span>
				${escapeHtml(branch)}
			</span>
		</div>
		<div class="status-bar-right">
			<div class="view-toggle">
				<button id="btn-side" class="view-toggle-btn active" type="button">Side</button>
				<button id="btn-unified" class="view-toggle-btn" type="button">Unified</button>
			</div>
			<span class="status-bar-item status-bar-stats">
				${fileCount} files
				<span class="additions">+${totalAdditions}</span>
				<span class="deletions">-${totalDeletions}</span>
			</span>
		</div>
	</header>
	<div class="review-body">
		<div id="file-list"></div>
		<div id="editor"></div>
	</div>
</main>
<script>
window.__FILES__ = ${safeScriptJson(files)};
window.__ICONS__ = { file: ${safeScriptJson(ICON_FILE)}, folder: ${safeScriptJson(ICON_FOLDER)} };
</script>
<script>${CODEMIRROR_BUNDLE}</script>
<script>${CODEMIRROR_APP}</script>
</body>
</html>`;
}

function parseContextFromTitle(title: string): ReviewHeaderContext {
	const match = title.match(/^(.*?):\s+(.*?)\s+vs\s+(.*?)$/);
	if (!match) {
		return { repoName: "repo", branch: "HEAD", base: "main", repoRoot: "" };
	}
	return {
		repoName: match[1]?.trim() || "repo",
		branch: match[2]?.trim() || "HEAD",
		base: match[3]?.trim() || "main",
		repoRoot: "",
	};
}

function safeScriptJson(value: unknown): string {
	return JSON.stringify(value)
		.replaceAll("<", "\\u003c")
		.replaceAll(">", "\\u003e")
		.replaceAll("&", "\\u0026")
		.replaceAll("\u2028", "\\u2028")
		.replaceAll("\u2029", "\\u2029");
}

function escapeHtml(value: string): string {
	return value
		.replaceAll("&", "&amp;")
		.replaceAll("<", "&lt;")
		.replaceAll(">", "&gt;")
		.replaceAll('"', "&quot;")
		.replaceAll("'", "&#39;");
}
