// src/infrastructure/svg-to-png.js
/**
 * @param {SVGElement} svg - виртуальный SVG (готовый для рендеринга)
 * @param {{x:number,y:number,width:number,height:number}} rect - область в единицах SVG user units
 * @param {number} scale - множитель (вызов передаёт, например, 3)
 * @param {(blob:Blob|null)=>void} callBack
 */
export function svgToPng(svg, rect, scale, callBack) {
    if (!svg || !rect || rect.width <= 0 || rect.height <= 0) {
        callBack(null);
        return;
    }

    // output размеры с учётом devicePixelRatio
    const dpr = window.devicePixelRatio || 1;
    const outputWidth = Math.round(rect.width * scale * dpr);
    const outputHeight = Math.round(rect.height * scale * dpr);

    // Сериализуем svg в строку и делаем blob/url
    let svgString;
    try {
        svgString = new XMLSerializer().serializeToString(svg);
    } catch (e) {
        callBack(null);
        return;
    }

    let url;
    try {
        url = URL.createObjectURL(new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' }));
    } catch (e) {
        callBack(null);
        return;
    }

    const img = new Image();
    // crossOrigin можно добавить, если нужно: img.crossOrigin = 'anonymous';
    img.onload = function () {
        try {
            const canvas = document.createElement('canvas');
            canvas.width = outputWidth;
            canvas.height = outputHeight;
            canvas.style.width = `${outputWidth}px`;
            canvas.style.height = `${outputHeight}px`;

            const ctx = canvas.getContext('2d');
            if (!ctx) {
                URL.revokeObjectURL(url);
                callBack(null);
                return;
            }
            ctx.imageSmoothingEnabled = false;

            // Если rect.x/rect.y отрицательные => смещение исходного изображения внутри canvas
            const sx = Math.max(0, rect.x * scale * dpr);
            const sy = Math.max(0, rect.y * scale * dpr);
            const sWidth = rect.width * scale * dpr;
            const sHeight = rect.height * scale * dpr;

            // dx/dy: смещение на canvas (если rect.x < 0, то мы сдвигаем вправо)
            const dx = rect.x < 0 ? -rect.x * scale * dpr : 0;
            const dy = rect.y < 0 ? -rect.y * scale * dpr : 0;

            // drawImage с указанием исходной области и целевой области
            ctx.drawImage(
                img,
                sx, // sx
                sy, // sy
                sWidth, // sWidth
                sHeight, // sHeight
                dx, // dx (на canvas)
                dy, // dy
                outputWidth, // dWidth
                outputHeight // dHeight
            );

            URL.revokeObjectURL(url);
            canvas.toBlob(blob => {
                callBack(blob);
            }, 'image/png');
        } catch (err) {
            URL.revokeObjectURL(url);
            callBack(null);
        }
    };

    img.onerror = function () {
        try { URL.revokeObjectURL(url); } catch (e) {}
        callBack(null);
    };

    img.src = url;
}
