import { el, queue } from "deka-dom-el";
import { addEventListener, registerClientFile } from "../ssr.js";
import { relative } from "node:path";

const dir= new URL("./", import.meta.url).pathname;
const dirFE= "irelands";
// Track all component instances for client-side rehydration
const componentsRegistry = new Map();
/**
 * Creates a component that shows code and its runtime output
 * with server-side pre-rendering and client-side rehydration
 *
 * @param {object} attrs
 * @param {URL} attrs.src - Path to the file containing the component
 * @param {string} [attrs.exportName="default"] - Name of the export to use
 * @param {string} attrs.page_id - ID of the current page
 * @param {object} [attrs.props={}] - Props to pass to the component
 */
export function ireland({ src, exportName = "default", props = {} }) {
	// relative src against the current directory
	const path= "./"+relative(dir, src.pathname);
	const id = "ireland-" + generateComponentId(src);
	const element = el.mark({ type: "later", name: ireland.name });
	queue(import(path).then(module => {
		const component = module[exportName];
		element.replaceWith(el(component, props, mark(id)));
	}));

	if(!componentsRegistry.size)
		addEventListener("oneachrender", registerClientPart);
	componentsRegistry.set(id, {
		src,
		path: dirFE+"/"+path.split("/").pop(),
		exportName,
		props,
	});

	return element;
}

function registerClientPart(){
	const todo= Array.from(componentsRegistry.entries())
		.map(([ id, d ]) => {
			registerClientFile(d.src, {
				folder: dirFE,
				// not all browsers support importmap
				replacer(file){
					return file
						.replaceAll(/ from "deka-dom-el(\/signals)?";/g, ` from "./esm-with-signals.js";`);
				}
			});
			return [ id, d ];
		});
	const store = JSON.stringify(JSON.stringify(todo));
	registerClientFile(new URL("./ireland.js.js", import.meta.url));
	registerClientFile(new URL("../../dist/esm-with-signals.js", import.meta.url), { folder: dirFE });
	document.head.append(
		// not all browsers support importmap
		el("script", { type: "importmap" }).append(`
{
	"imports": {
		"deka-dom-el": "./${dirFE}/esm-with-signals.js",
		"deka-dom-el/signals": "./${dirFE}/esm-with-signals.js"
	}
}
		`.trim())
	);
	document.body.append(
		el("script", { type: "module" }).append(`
import { loadIrelands } from "./ireland.js.js";
loadIrelands(new Map(JSON.parse(${store})));
		`.trim())
	)
}
function mark(id) { return el=> el.dataset.ddeMark= id; }
const store_prev= new Map();
/** @param {URL} src */
function generateComponentId(src){
	const candidate= parseInt(relative((new URL("..", import.meta.url)).pathname, src.pathname)
		.split("")
		.map(ch=> ch.charCodeAt(0))
		.join(""), 10)
		.toString(36)
		.replace(/000+/g, "");
	const count= 1 + ( store_prev.get(candidate) || 0 );
	store_prev.set(candidate, count);
	return count.toString()+"-"+candidate;
}