/**
    * @file SvgEditorM.js
    * @brief Основной файл SvgEditorM, реализует функционал редактирования SVG-графики на сайте
*/

/**
    * @brief Базовый SVG-элемент
    * @param width Ширина
    * @param height Высота
    * @param posX Позиция X
    * @param posY Позиция Y
    * @param id ID элемента
    * @param type Тип SVG-элемента
*/
class SVGElement {
    constructor({ width, height, posX, posY, id, type } = {}) {
        this.width = width || 100;
        this.height = height || 100;
        this.posX = posX || 100;
        this.posY = posY || 100;
        this.id = id || `svgElement_${Date.now()}`;
        this.type = type || 'svg';
        this.domNode = this.createSVGDOMNode(this.type);
    }

    createSVGDOMNode(type) {
        let { height, width, posY, posX, id } = this;
        let svg = document.createElementNS('http://www.w3.org/2000/svg', type);
        svg.setAttribute('style', 'border: 1px solid black; box-sizing: border-box;');
        svg.setAttribute('id', id);
        if (type !== 'svg') {
            svg.setAttribute('x', posX);
            svg.setAttribute('y', posY);
            svg.setAttribute('width', width);
            svg.setAttribute('height', height);
        } else {
            svg.setAttribute('width', width);
            svg.setAttribute('height', height);
        }
        svg.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', 'http://www.w3.org/1999/xlink');
        return svg;
    }
}

/**
    * @brief Класс для модификации SVG-элементов
*/
class SVGElementModifier {
    static moveSelectedElement({ handler, event }) {
        const { selected, selector, editor, offset } = handler;
        const { clientX, clientY } = event;
        if (selected) {
            if (selected.tagName.toLowerCase() === 'circle') {
                selected.setAttribute('cx', clientX + offset.x);
                selected.setAttribute('cy', clientY + offset.y);
            } else {
                selected.setAttribute('x', clientX + offset.x);
                selected.setAttribute('y', clientY + offset.y);
                selector.updateSelection(selected, editor);
            }
            selector.updateSelection(selected);
        }
    }

    static deselectElement({ handler }) {
        handler.selected = null;
    }

    static toggelHoveredElement({ handler, target }) {
        return handler.selector.updateSelection(target, handler.editor);
    }

    static selectElement({ handler, event }) {
        let { target, clientX, clientY } = event;
        const { selector, editor } = handler;
        if (selector.isSelectable(target, editor)) {
            handler.offset.x = parseFloat(target.getAttribute('x')) - clientX || 0;
            handler.offset.y = parseFloat(target.getAttribute('y')) - clientY || 0;
            handler.selected = target;
        }
    }
}

/**
    * @brief Прямоугольник
    * @param posX Позиция X
    * @param posY Позиция Y
    * @param width Ширина
    * @param height Высота
    * @param id ID элемента
*/
class Rect extends SVGElement {
    constructor({ posX, posY, width, height, id } = {}) {
        super({ type: 'rect', posX, posY, width, height, id });
        this.domNode.setAttribute('width', width || 100);
        this.domNode.setAttribute('height', height || 100);
        this.domNode.setAttribute('x', posX || 100);
        this.domNode.setAttribute('y', posY || 100);
        this.domNode.setAttribute('fill', 'rgba(0,120,200,0.2)');
        this.domNode.setAttribute('stroke', '#0078c8');
    }
}

/**
    * @brief Класс выбора фигур
    * @param id ID селектора
*/
class ShapeSelector {
    constructor(id) {
        this.id = id;
        this.selectorElem = document.getElementById(this.id);
    }

    isSelectable(element, area) {
        if (!element) return false;
        if (element.isSameNode(area)) return false;
        const tag = element.tagName ? element.tagName.toLowerCase() : '';
        return (tag === 'rect' || tag === 'circle' || tag === 'g' || tag === 'path' || tag === 'ellipse');
    }

    toggleSelectionOverElement(element) {
        let bound = element.getBoundingClientRect();
        const { style } = this.selectorElem;
        style.left = bound.left + 'px';
        style.top = bound.top + 'px';
        style.width = bound.width + 'px';
        style.height = bound.height + 'px';
        style.display = 'block';
    }

    updateSelection(element, area) {
        if (this.isSelectable(element, area)) {
            return this.toggleSelectionOverElement(element);
        }
        return this.hideSelection();
    }

    hideSelection() {
        if (this.selectorElem) this.selectorElem.style.display = 'none';
    }
}

/**
    * @brief Обработчик событий редактора
*/
class EditorEventHandler {
    constructor() {
        this.editor = null;
        this.selector = null;
        this.selected = null;
        this.offset = { x: 0, y: 0 };
    }

    startListening({ editor, selector }) {
        this.editor = editor;
        this.selector = selector;
        this.handleEditorEvents();
    }

    handleEditorEvents() {
        this.handleElementsHover();
        this.handleElementSelect();
        this.handleMoveElement();
        this.handleElementDeselect();
    }

    handleElementsHover() {
        this.editor.addEventListener('mouseover', ({ target }) => {
            SVGElementModifier.toggelHoveredElement({ handler: this, target });
        });
    }

    handleElementSelect() {
        this.editor.addEventListener('mousedown', event => {
            SVGElementModifier.selectElement({ handler: this, event });
        });
    }

    handleElementDeselect() {
        this.editor.addEventListener('mouseup', event => {
            SVGElementModifier.deselectElement({ handler: this });
        });
    }

    handleMoveElement() {
        this.editor.addEventListener('mousemove', event => {
            SVGElementModifier.moveSelectedElement({ handler: this, event });
        });
    }
}

/**
    * @brief Область для рисования
    * @param options Параметры области
*/
class Area extends SVGElement {
    constructor(options = {}) {
        super({ type: 'svg', width: options.width || 800, height: options.height || 400, id: options.id || 'mySVG' });
        this.domNode.style.border = '3px solid black';
    }

    appendElement(element) {
        this.domNode.appendChild(element);
    }

    setDimentions() { }
}

/**
    * @brief Редактор SVG
    * @param targetNode Узел-цель
    * @param playGround Игровая область
    * @param eventHandler Обработчик событий
    * @param selector Селектор фигур
*/
class Editor {
    constructor({ targetNode, playGround, eventHandler, selector }) {
        this.targetNode = targetNode;
        this.playGround = playGround;
        this.domNode = this.createEditor();
        this.selector = selector;
        this.svgElements = [];
        this.EditorEventHandler = eventHandler;
        this.EditorEventHandler.startListening({
            editor: this.domNode,
            selector: this.selector
        });
    }

    setDimentions(node, width, height) {
        node.style.width = '-webkit-fill-available';
        node.style.height = '-webkit-fill-available';
        return node;
    }

    createEditor() {
        let editor = this.playGround.domNode;
        const { width, height } = this.getEditorParams();
        this.setDimentions(editor, width, height);
        return editor;
    }

    getEditorParams() {
        let width = Math.max(this.targetNode.offsetWidth - 10, 0);
        let height = Math.max(this.targetNode.offsetHeight - 10, 0);
        return { width, height };
    }

    addElement(element) {  
        if (!element || !element.domNode) return;
        this.playGround.appendElement(element.domNode);
        this.svgElements.push(element);
    }
}

/* -----------------------------
   Инициализация (выполняется после загрузки DOM)
   ----------------------------- */

window.addEventListener('DOMContentLoaded', () => {
    let main = document.getElementById('main') || document.body;

    let selection = document.getElementById('selector');
    if (!selection) {
        selection = document.createElement('div');
        selection.id = 'selector';
        Object.assign(selection.style, {
            position: 'absolute',
            display: 'none',
            border: '1px dashed #333',
            pointerEvents: 'none',
            zIndex: 9999
        });
        document.body.appendChild(selection);
    }

    const area = new Area({ id: 'mySVG', width: 800, height: 400 });
    main.appendChild(area.domNode);

    const selector = new ShapeSelector('selector');

    const editorEventHandler = new EditorEventHandler();
    const editor = new Editor({
        targetNode: main,
        playGround: area,
        selector,
        eventHandler: editorEventHandler
    });

    const testRect = new Rect({ posX: 20, posY: 20, width: 120, height: 80, id: 'r1' });
    const testRect2 = new Rect({ posX: 200, posY: 150, width: 140, height: 90, id: 'r2' });
    editor.addElement(testRect);
    editor.addElement(testRect2);

    area.domNode.addEventListener('mouseover', (e) => {
        const tgt = e.target;
        selector.updateSelection(tgt, area.domNode);
    });

    window.addEventListener('resize', () => {
        const { width, height } = editor.getEditorParams();
        editor.setDimentions(area.domNode, width, height);
    });

    console.log('SVG Editor initialized', { area, editor, selector });
});

/* -----------------------------
   edit
   ----------------------------- */

/** @brief Селектор основного контейнера */
const MAIN_SEL = "#main";
/** @brief ID элемента outline */
const OUTLINE_ID = "outline";
/** @brief Селектор боковой панели с фигурами */
const SIDEBAR_SHAPES = ".sidebar__shapes";
/** @brief Селектор боковой панели с режимами */
const SIDEBAR_SELECTORS = ".sidebar__selectors";
/** @brief Ключ для сохранения количества изменений */
const saveCountKey = 'SvgEditorM_saveCount';

/** @brief Основной контейнер DOM */
const main = document.querySelector(MAIN_SEL);
if (!main) throw new Error("Не найден #main");

/** @brief Массив svg элементов внутри main */
let svgsInMain = Array.from(main.querySelectorAll("svg"));
/** @brief Рабочий svg элемент */
let svg;
if (svgsInMain.length === 0) {
	svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
	svg.setAttribute("style", "border: 1px solid #ccc; box-sizing: border-box; width: -webkit-fill-available; height: -webkit-fill-available;");
	svg.setAttribute("width", "1000");
	svg.setAttribute("height", "600");
	main.appendChild(svg);
} else {
	// keep first svg, remove extras to avoid duplicates
	svg = svgsInMain[0];
	for (let i = 1; i < svgsInMain.length; i++) svgsInMain[i].remove();
}

/** @brief Создает и добавляет маркер стрелки к SVG */
(function ensureArrowMarker() {
	let defs = svg.querySelector("defs");
	if (!defs) {
		defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
		svg.appendChild(defs);
	}
	if (!svg.querySelector("#arrowhead")) {
    const marker = document.createElementNS("http://www.w3.org/2000/svg", "marker");
    marker.setAttribute("id", "arrowhead");
    marker.setAttribute("markerWidth", "6"); 
    marker.setAttribute("markerHeight", "4"); 
    marker.setAttribute("refX", "4.8"); 
    marker.setAttribute("refY", "2");
    marker.setAttribute("orient", "auto");
    const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
    path.setAttribute("d", "M0,0 L6,2 L0,4 z");
    path.setAttribute("fill", "#495057");
    marker.appendChild(path);
    defs.appendChild(marker);
	}
})();

/** @brief Получает элемент outline из DOM */
const outline = document.getElementById(OUTLINE_ID);
/** @brief Счетчик для генерации уникальных ID */
let uid = 1;

/**
    * @brief Генерирует уникальный идентификатор для элемента
    * @param prefix префикс для ID
*/
function makeId(prefix = "el") { return `${prefix}_${Date.now().toString(36)}_${uid++}`; }

/**
    * @brief Преобразует координаты из клиентских в координаты SVG
    * @param clientX координата X в пикселях
    * @param clientY координата Y в пикселях
*/
function clientToSvgPoint(clientX, clientY) {
	const pt = svg.createSVGPoint();
	pt.x = clientX; pt.y = clientY;
	const ctm = svg.getScreenCTM();
	if (!ctm) return { x: clientX, y: clientY };
	const inv = ctm.inverse();
	const p = pt.matrixTransform(inv);
	return { x: p.x, y: p.y };
}

/**
    * @brief Возвращает размеры и позицию элемента в координатах экрана
    * @param el элемент SVG
*/
function screenBBoxOf(el) {
	try {
		const bbox = el.getBBox();
		const p1 = svg.createSVGPoint(); p1.x = bbox.x; p1.y = bbox.y;
		const p2 = svg.createSVGPoint(); p2.x = bbox.x + bbox.width; p2.y = bbox.y + bbox.height;
		const s1 = p1.matrixTransform(svg.getScreenCTM());
		const s2 = p2.matrixTransform(svg.getScreenCTM());
		return {
			left: Math.min(s1.x, s2.x),
			top: Math.min(s1.y, s2.y),
			width: Math.abs(s2.x - s1.x),
			height: Math.abs(s2.y - s1.y)
		};
	} catch (e) {
		const r = el.getBoundingClientRect();
		return { left: r.left, top: r.top, width: r.width, height: r.height };
	}
}

/**
    * @brief Показывает или скрывает outline вокруг элемента
    * @param el элемент SVG или null
*/
function showOutlineFor(el) {
	if (!outline) return;
	if (!el) { outline.style.display = "none"; return; }
	const b = screenBBoxOf(el);
	outline.style.display = "block";
	outline.style.position = "fixed";
	outline.style.left = `${b.left-2}px`;
	outline.style.top = `${b.top-2}px`;
	outline.style.width = `${b.width}px`;
	outline.style.height = `${b.height}px`;
	outline.style.border = "2px solid rgba(0,120,255,0.6)";
	outline.style.pointerEvents = "none";
}

/** @brief Режим работы редактора */
let mode = "Move";
/** @brief Текущий выбранный элемент */
let currentSelected = null;
/** @brief Состояние перетаскивания элемента */
let dragState = null;

document.querySelectorAll(`${SIDEBAR_SHAPES} .sidebar__shape`).forEach(node => {
	node.addEventListener("click", () => {
		const shapeName = node.textContent.trim().toLowerCase();
		createShape(shapeName);
	});
});

document.querySelectorAll(`${SIDEBAR_SELECTORS} .sidebar__selector`).forEach(node => {
	node.addEventListener("click", () => {
		document.querySelectorAll(`${SIDEBAR_SELECTORS} .sidebar__selector`).forEach(n => n.classList.remove("active"));
		node.classList.add("active");
		mode = node.textContent.trim();
	});
});

const defaultSel = document.querySelector(`${SIDEBAR_SELECTORS} .sidebar__selector`);
if (defaultSel) {
	defaultSel.classList.add("active");
	mode = defaultSel.textContent.trim();
}

/**
    * @brief Создает фигуру указанного типа в центре SVG
    * @param kind тип фигуры: rect, circle, line, arrow
*/
function createShape(kind) {
	const center = { x: parseFloat(svg.getAttribute("width"))/2 || 200, y: parseFloat(svg.getAttribute("height"))/2 || 150 };
	const id = makeId(kind);
	let el = null;
	if (kind === "rect") {
		el = document.createElementNS("http://www.w3.org/2000/svg", "rect");
		el.setAttribute("x", center.x - 50);
		el.setAttribute("y", center.y - 25);
		el.setAttribute("width", 100);
		el.setAttribute("height", 50);
		el.setAttribute("fill", "#1aaee5");
	} else if (kind === "circle") {
		el = document.createElementNS("http://www.w3.org/2000/svg", "circle");
		el.setAttribute("cx", center.x);
		el.setAttribute("cy", center.y);
		el.setAttribute("r", 30);
		el.setAttribute("fill", "#ff6600");
	} else if (kind === "line") {
		el = document.createElementNS("http://www.w3.org/2000/svg", "line");
		el.setAttribute("x1", center.x - 60);
		el.setAttribute("y1", center.y);
		el.setAttribute("x2", center.x + 60);
		el.setAttribute("y2", center.y);
		el.setAttribute("stroke", "#495057");
		el.setAttribute("stroke-width", 4);
	} else if (kind === "arrow") {
		el = document.createElementNS("http://www.w3.org/2000/svg", "line");
		el.setAttribute("x1", center.x - 60);
		el.setAttribute("y1", center.y - 10);
		el.setAttribute("x2", center.x + 60);
		el.setAttribute("y2", center.y + 10);
		el.setAttribute("stroke", "#495057");
		el.setAttribute("stroke-width", 4);
		el.setAttribute("marker-end", "url(#arrowhead)");
	} else {
		alert("Unknown shape: " + kind);
		return;
	}
	el.setAttribute("id", id);
	el.classList.add("draggable");
	svg.appendChild(el);
	attachShapeListeners(el);
	selectElement(el);
}

/**
    * @brief Подключает обработчики событий для фигуры
    * @param el элемент SVG
*/
function attachShapeListeners(el) {
	el.addEventListener("mousedown", (ev) => {
		ev.stopPropagation();
		const startClient = { x: ev.clientX, y: ev.clientY };
		const startSvg = clientToSvgPoint(ev.clientX, ev.clientY);
		const startAttrs = readElementAttrs(el);
		const action = mode === "Resize" ? "resize" : "move";
		dragState = { type: action, el, startClient, startSvg, startAttrs };
		selectElement(el);
		window.addEventListener("mousemove", onWindowMouseMove);
		window.addEventListener("mouseup", onWindowMouseUp);
	});
	el.addEventListener("click", (e) => { e.stopPropagation(); selectElement(el); });
}

/**
    * @brief Считывает атрибуты элемента SVG
    * @param el элемент SVG
*/
function readElementAttrs(el) {
	const tag = el.tagName.toLowerCase();
	if (tag === "rect") {
		return {
			x: parseFloat(el.getAttribute("x")||0),
			y: parseFloat(el.getAttribute("y")||0),
			width: parseFloat(el.getAttribute("width")||0),
			height: parseFloat(el.getAttribute("height")||0)
		};
	} else if (tag === "circle") {
		return {
			cx: parseFloat(el.getAttribute("cx")||0),
			cy: parseFloat(el.getAttribute("cy")||0),
			r: parseFloat(el.getAttribute("r")||0)
		};
	} else if (tag === "line") {
		return {
			x1: parseFloat(el.getAttribute("x1")||0),
			y1: parseFloat(el.getAttribute("y1")||0),
			x2: parseFloat(el.getAttribute("x2")||0),
			y2: parseFloat(el.getAttribute("y2")||0)
		};
	}
	return {};
}

/**
    * @brief Обрабатывает движение мыши при перетаскивании/изменении размера
    * @param ev событие мыши
*/
function onWindowMouseMove(ev) {
	if (!dragState) return;
	const { type, el, startSvg, startAttrs } = dragState;
	const curSvg = clientToSvgPoint(ev.clientX, ev.clientY);
	const dx = curSvg.x - startSvg.x;
	const dy = curSvg.y - startSvg.y;
	const tag = el.tagName.toLowerCase();

	if (type === "move") {
		if (tag === "rect") {
			el.setAttribute("x", startAttrs.x + dx);
			el.setAttribute("y", startAttrs.y + dy);
		} else if (tag === "circle") {
			el.setAttribute("cx", startAttrs.cx + dx);
			el.setAttribute("cy", startAttrs.cy + dy);
		} else if (tag === "line") {
			el.setAttribute("x1", startAttrs.x1 + dx);
			el.setAttribute("y1", startAttrs.y1 + dy);
			el.setAttribute("x2", startAttrs.x2 + dx);
			el.setAttribute("y2", startAttrs.y2 + dy);
		}
	} else {
		if (tag === "rect") {
			const newW = Math.max(6, startAttrs.width + dx);
			const newH = Math.max(6, startAttrs.height + dy);
			el.setAttribute("width", newW);
			el.setAttribute("height", newH);
		} else if (tag === "circle") {
			const center = { x: startAttrs.cx, y: startAttrs.cy };
			const newR = Math.max(4, Math.hypot(curSvg.x - center.x, curSvg.y - center.y));
			el.setAttribute("r", newR);
		} else if (tag === "line") {
			el.setAttribute("x2", startAttrs.x2 + dx);
			el.setAttribute("y2", startAttrs.y2 + dy);
		}
	}

	showOutlineFor(el);
}

/**
    * @brief Обрабатывает отпускание кнопки мыши при перетаскивании/изменении размера
*/
function onWindowMouseUp() {
	if (dragState) {
		dragState = null;
		window.removeEventListener("mousemove", onWindowMouseMove);
		window.removeEventListener("mouseup", onWindowMouseUp);
	}
}

svg.addEventListener("mousedown", (ev) => {
	if (ev.target === svg) selectElement(null);
});

/**
    * @brief Выбирает элемент или снимает выбор
    * @param el элемент SVG или null
*/
function selectElement(el) {
	if (currentSelected === el) return;
	if (currentSelected) currentSelected.classList.remove("selected");
	currentSelected = el;
	if (el) {
		el.classList.add("selected");
		showOutlineFor(el);
	} else {
		showOutlineFor(null);
	}
}

Array.from(svg.querySelectorAll(".draggable, rect, circle, line")).forEach(attachShapeListeners);

window.addEventListener("resize", () => showOutlineFor(currentSelected));
window.addEventListener("scroll", () => showOutlineFor(currentSelected));
window.addEventListener("keydown", (ev) => {
	if ((ev.key === "Delete" || ev.key === "Backspace") && currentSelected) {
		currentSelected.remove();
		selectElement(null);
	}
});



/** @brief Кнопки панели сайдбара */
const buttons = Array.from(document.querySelectorAll('.sidebar__button'));
/** @brief Кнопка сохранения */
const saveBtn = buttons.find(b => b.textContent.trim().toLowerCase() === 'save');
/** @brief Кнопка загрузки */
const loadBtn = buttons.find(b => b.textContent.trim().toLowerCase() === 'load');

/** @brief Генерирует следующее имя файла для сохранения */
function nextFilename() {
	localStorage.setItem(saveCountKey, String((parseInt(localStorage.getItem(saveCountKey) || '0', 10) || 0) + 1));
	const n = parseInt(localStorage.getItem(saveCountKey), 10) || 1;
	return n === 1 ? 'SvgEditorM.svg' : `SvgEditorM-${n}.svg`;
}

/** @brief Возвращает SVG внутри main */
function getMainSvg() {
	return main.querySelector('svg');
}

/**
    * @brief Устанавливает атрибуты xmlns для элемента SVG, если их нет
    * @param el элемент SVG
*/
function ensureXmlns(el) {
	if (!el.getAttribute('xmlns')) el.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
	if (!el.getAttribute('xmlns:xlink')) el.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
	return el;
}

/** @brief Сохраняет SVG из main в файл */
function saveSvg() {
	const svg = getMainSvg();
	if (!svg) return;
	const clone = svg.cloneNode(true);
	ensureXmlns(clone);
	const xml = new XMLSerializer().serializeToString(clone);
	const blob = new Blob([xml], { type: 'image/svg+xml;charset=utf-8' });
	const url = URL.createObjectURL(blob);
	const a = document.createElement('a');
	a.href = url;
	a.download = nextFilename();
	document.body.appendChild(a);
	a.click();
	a.remove();
	setTimeout(() => URL.revokeObjectURL(url), 10000);
}

/** @brief Элемент input для загрузки файлов */
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = '.svg,image/svg+xml';
fileInput.style.display = 'none';
document.body.appendChild(fileInput);

/**
    * @brief Делает узел и его потомков интерактивными
    * @param node элемент SVG
*/
function makeInteractiveForNode(node) {
	if (!(node instanceof Element)) return;
	const tag = node.tagName.toLowerCase();
	if (['rect','circle','line','path','polyline','polygon','g'].includes(tag)) {
		if (!node.classList.contains('draggable')) node.classList.add('draggable');
		if (typeof attachShapeListeners === 'function') {
			attachShapeListeners(node);
		}
	}
	Array.from(node.children || []).forEach(ch => makeInteractiveForNode(ch));
}

/**
    * @brief Загружает SVG из файла в main
    * @param file объект File
*/
async function loadSvgFile(file) {
	if (!file) return;
	const text = await file.text();
	const parser = new DOMParser();
	const doc = parser.parseFromString(text, 'image/svg+xml');
	const parsedSvg = doc.querySelector('svg');
	if (!parsedSvg) {
		alert('Выбранный файл не содержит SVG');
		return;
	}
	const targetSvg = getMainSvg();
	if (!targetSvg) {
		const imported = document.importNode(parsedSvg, true);
		ensureXmlns(imported);
		main.appendChild(imported);
		Array.from(imported.querySelectorAll('*')).forEach(n => makeInteractiveForNode(n));
	} else {
		const preservedOutline = document.getElementById('outline');
		while (targetSvg.firstChild) targetSvg.removeChild(targetSvg.firstChild);
		Array.from(parsedSvg.childNodes).forEach(n => {
			const imp = document.importNode(n, true);
			targetSvg.appendChild(imp);
		});
		Array.from(parsedSvg.attributes).forEach(attr => {
			if (attr.name === 'xmlns' || attr.name === 'xmlns:xlink') return;
			targetSvg.setAttribute(attr.name, attr.value);
		});
		ensureXmlns(targetSvg);
		Array.from(targetSvg.querySelectorAll('*')).forEach(n => makeInteractiveForNode(n));
		if (preservedOutline && preservedOutline.parentElement !== document.body) {
		}
	}
	main.dispatchEvent(new CustomEvent('svg-loaded', { detail: { fileName: file.name } }));
}

fileInput.addEventListener('change', () => {
	const f = fileInput.files && fileInput.files[0];
	loadSvgFile(f).finally(() => { fileInput.value = ''; });
});

if (saveBtn) saveBtn.addEventListener('click', (e) => { e.stopPropagation(); saveSvg(); });
if (loadBtn) loadBtn.addEventListener('click', (e) => { e.stopPropagation(); fileInput.click(); });
