import { type AbstractEngine } from '@babylonjs/core/Engines/abstractEngine';
import { type RenderTargetTexture } from '@babylonjs/core/Materials/Textures/renderTargetTexture';
import { type ISize } from '@babylonjs/core/Maths/math.size';
import { type Scene } from '@babylonjs/core/scene';
import { Scalar } from '@babylonjs/core/Maths/math.scalar';

export interface CopySizeToOptions {
    src: ISize | Pick<AbstractEngine, 'getRenderWidth' | 'getRenderHeight'> | Pick<Scene, 'getEngine'>;
    dst: Pick<RenderTargetTexture, 'getSize' | 'resize'>;
    scale?: number;
    epsilon?: number;
}

export function copySizeTo(options: CopySizeToOptions): void {
    // eslint-disable-next-line prefer-const
    let { src, dst, scale, epsilon } = { scale: 1, ...options };
    if ('getEngine' in src) {
        src = src.getEngine();
    }

    if ('getRenderWidth' in src) {
        src = {
            width: src.getRenderWidth(),
            height: src.getRenderHeight()
        };
    }

    const texCorrectWidth = Math.floor(src.width * scale);
    const texCorrectHeight = Math.floor(src.height * scale);

    const internalSize = dst.getSize();
    const texCurrentWidth = internalSize.width;
    const texCurrentHeight = internalSize.height;

    if (
        !Scalar.WithinEpsilon(texCurrentWidth, texCorrectWidth, epsilon) ||
        !Scalar.WithinEpsilon(texCurrentHeight, texCorrectHeight, epsilon)
    ) {
        dst.resize({
            width: texCorrectWidth,
            height: texCorrectHeight
        });
    }
}
