/**
 * Auto-layout pass for ContainerElement. Walks a slide's elements list,
 * finds the container by id, and rewrites the position (and optionally
 * size, when align=stretch) of every child id listed in childIds.
 *
 * This is the same algorithm the editor uses; running it in the presenter
 * keeps embedded JSONs visually identical to what the user authored, and
 * gives us a single source of truth for layout math.
 */
function resolvePadding(p) {
    if (typeof p === 'number')
        return { top: p, right: p, bottom: p, left: p };
    return p;
}
export function relayoutContainer(elements, containerId) {
    const container = elements.find((el) => el.id === containerId);
    if (!container || container.type !== 'container')
        return elements;
    const c = container;
    const pad = resolvePadding(c.padding);
    const innerW = Math.max(0, c.size.width - pad.left - pad.right);
    const innerH = Math.max(0, c.size.height - pad.top - pad.bottom);
    const isRow = c.direction === 'row';
    const innerMain = isRow ? innerW : innerH;
    const innerCross = isRow ? innerH : innerW;
    const mainOriginAbs = (isRow ? c.position.x + pad.left : c.position.y + pad.top);
    const crossOriginAbs = (isRow ? c.position.y + pad.top : c.position.x + pad.left);
    const childMap = new Map(elements.map((el) => [el.id, el]));
    const children = c.childIds
        .map((id) => childMap.get(id))
        .filter((el) => el !== undefined);
    if (children.length === 0)
        return elements;
    const mainSizes = children.map((ch) => (isRow ? ch.size.width : ch.size.height));
    const totalChildMain = mainSizes.reduce((a, b) => a + b, 0);
    const totalGap = c.gap * Math.max(0, children.length - 1);
    const usedMain = totalChildMain + totalGap;
    const freeMain = Math.max(0, innerMain - usedMain);
    let mainCursor = 0;
    let extraGap = 0;
    switch (c.justify) {
        case 'start':
            mainCursor = 0;
            break;
        case 'center':
            mainCursor = freeMain / 2;
            break;
        case 'end':
            mainCursor = freeMain;
            break;
        case 'space-between':
            mainCursor = 0;
            extraGap = children.length > 1 ? freeMain / (children.length - 1) : 0;
            break;
        case 'space-around':
            extraGap = children.length > 0 ? freeMain / children.length : 0;
            mainCursor = extraGap / 2;
            break;
        case 'space-evenly':
            extraGap = freeMain / (children.length + 1);
            mainCursor = extraGap;
            break;
    }
    const updates = new Map();
    for (let i = 0; i < children.length; i++) {
        const ch = children[i];
        const mainSize = isRow ? ch.size.width : ch.size.height;
        const intrinsicCross = isRow ? ch.size.height : ch.size.width;
        let crossOffset = 0;
        let crossSize = intrinsicCross;
        switch (c.align) {
            case 'start':
                crossOffset = 0;
                break;
            case 'center':
                crossOffset = (innerCross - intrinsicCross) / 2;
                break;
            case 'end':
                crossOffset = innerCross - intrinsicCross;
                break;
            case 'stretch':
                crossOffset = 0;
                crossSize = innerCross;
                break;
        }
        const x = isRow ? mainOriginAbs + mainCursor : crossOriginAbs + crossOffset;
        const y = isRow ? crossOriginAbs + crossOffset : mainOriginAbs + mainCursor;
        const w = isRow ? mainSize : crossSize;
        const h = isRow ? crossSize : mainSize;
        updates.set(ch.id, { position: { x, y }, size: { width: w, height: h } });
        mainCursor += mainSize + c.gap + extraGap;
    }
    return elements.map((el) => {
        const up = updates.get(el.id);
        if (!up)
            return el;
        return { ...el, position: up.position, size: up.size ?? el.size };
    });
}
export function relayoutAllContainers(elements) {
    let result = elements;
    for (const el of elements) {
        if (el.type === 'container') {
            result = relayoutContainer(result, el.id);
        }
    }
    return result;
}
