import * as DesignDataHelpers from '../../../../Services/DesignDataService';

jest.mock('../../../../Services/DesignDataService');

import {
    calculateScaleFactor,
    getRasterURL,
    prepareCanvasData,
    prepareImageObjectData,
    prepareObjectData,
} from '../Transformers';

describe('App/Modules/Designer/Utils/Transformers', () => {
    it('calculateScaleFactor returns the correct scale factor for no image data', () => {
        expect(calculateScaleFactor()).toEqual(1);
    });
    it('calculateScaleFactor returns the correct scale factor for incomplete image data object', () => {
        expect(calculateScaleFactor({ preview: { width: 2048 } })).toEqual(1);
    });
    it('calculateScaleFactor returns the correct scale factor for complete image data object', () => {
        expect(calculateScaleFactor({ preview: { width: 2048 }, original: { width: 6000 } })).toEqual(
            6000 / 2048
        );
    });

    it('prepareObjectData returns the input value untouched if there is nothing to do with it', () => {
        const someValue = 'a';
        expect(prepareObjectData(someValue)).toEqual(someValue);
        const otherValue = {};
        expect(prepareObjectData(otherValue)).toEqual(otherValue);
    });
    it('prepareObjectData adds the scaleFactor to the input object', () => {
        const rawObject = {
            imageData: { preview: { width: 2048 }, original: { width: 6000 } },
            x: 20,
            y: 30,
            scaling: 0.6,
        };
        expect(prepareObjectData(rawObject)).toHaveProperty('scaleFactor');
        // make sure it's the correct scale factor
        expect(prepareObjectData(rawObject).scaleFactor).toEqual(6000 / 2048);
    });

    it('prepareCanvasData calls the prepareObjectData on each object in the canvasData.objects', () => {
        const canvasData = {
            objects: [{ type: 'Image' }, { type: 'Text' }],
        };
        const spy = jest.fn();
        prepareCanvasData(canvasData, spy);
        expect(spy).toHaveBeenCalledTimes(2);
        expect(spy.mock.calls[0][0]).toBe(canvasData.objects[0]);
        expect(spy.mock.calls[1][0]).toBe(canvasData.objects[1]);
    });

    it('transformImageSrc uses the raster url if the original image is not vector and the color preview is disabled', async () => {
        const currentSrc = 'path/to/image.svg';
        const imageObjectData = {
            type: 'Image',
            imageData: {
                src: currentSrc,
                displayColorPreview: false,
                original: {
                    format: 'JPEG',
                },
                preview: {
                    url: currentSrc,
                },
            },
        };
        const preparedImageData = prepareImageObjectData(imageObjectData);
        const transformedSrc = await preparedImageData.transformImageSrc(currentSrc);
        expect(transformedSrc.indexOf('path/to/image.png')).toBe(0);
    });

    it('transformImageSrc uses the svg if color preview is enabled', async () => {
        DesignDataHelpers.getSvgContent.mockResolvedValue('<svg></svg>');
        DesignDataHelpers.applySvgContentOperations.mockReturnValue('base64encodedSVG');
        const currentSrc = 'path/to/image.svg';
        const imageObjectData = {
            type: 'Image',
            imageData: {
                src: currentSrc,
                displayColorPreview: true,
                original: {
                    format: 'JPEG',
                },
                preview: {
                    url: currentSrc,
                },
            },
        };
        const preparedImageData = prepareImageObjectData(imageObjectData);
        const transformedSrc = await preparedImageData.transformImageSrc(currentSrc);
        expect(transformedSrc).toBe('base64encodedSVG');
    });

    it('transformImageSrc uses the SVG image if color preview is disabled but the original format is SVG', async () => {
        DesignDataHelpers.getSvgContent.mockResolvedValue('<svg></svg>');
        DesignDataHelpers.applySvgContentOperations.mockReturnValue('base64encodedSVG');
        const currentSrc = 'path/to/image.svg';
        const imageObjectData = {
            type: 'Image',
            imageData: {
                src: currentSrc,
                displayColorPreview: false,
                original: {
                    format: 'SVG',
                },
                preview: {
                    url: currentSrc,
                },
            },
        };
        const preparedImageData = prepareImageObjectData(imageObjectData);
        const transformedSrc = await preparedImageData.transformImageSrc(currentSrc);
        expect(transformedSrc).toBe('base64encodedSVG');
    });

    it('transformImageSrc applies the operations (vectorizeColorsMap) on gallery images', async () => {
        DesignDataHelpers.getSvgContent.mockResolvedValue('<svg></svg>');
        DesignDataHelpers.applySvgContentOperations.mockReturnValue('base64encodedSVG');
        const currentSrc = 'path/to/image.svg';
        const imageData = {
            src: currentSrc,
            displayColorPreview: true,
            original: {
                format: 'JPEG',
            },
            preview: {
                url: currentSrc,
            },
            operations: {
                vectorizeColorsMap: {
                    '#ff0000': {
                        /* the color */
                    },
                },
            },
        };
        const imageObjectData = {
            type: 'Image',
            imageData,
        };
        const preparedImageData = prepareImageObjectData(imageObjectData);
        await preparedImageData.transformImageSrc(currentSrc);
        expect(DesignDataHelpers.applySvgContentOperations).toBeCalledWith(
            imageData.original,
            imageData.preview,
            imageData.operations,
            '<svg></svg>'
        );
    });

    test('getRasterURL returns the raster url for an svg image source', () => {
        expect(getRasterURL('http://the.url/path/to/image.svg')).toBe('http://the.url/path/to/image.png');
        expect(getRasterURL('path/to/image.svg')).toBe('path/to/image.png');
        expect(getRasterURL('path/to/image.gif')).toBe('path/to/image.gif');
    });
});
