'use strict';

import {
    getImageUsageInfo,
    getUserImagesByDesignArea,
    isColorMappingCompatible,
    isEditableVectorImage,
    isImageCompatible,
    isImageReadyToBeAdded,
    showVectorizeImageQuality,
    isHardModified,
    isColorPreviewCompatible,
    getPreviewUrlFromImageData,
} from '../Selectors';
import { ImageGalleryModes } from '../Actions';

describe('Reducers/ImageGallery/Selectors', () => {
    test('getUserImagesByDesignArea returns all the uniq images', () => {
        const state = {
            configuration: {
                designdata: {
                    a_1: {
                        canvasData: {
                            objects: [
                                {
                                    type: 'Image',
                                    imageData: {
                                        identifier: 'image1',
                                        fileName: '9c1330f774e4dada3c1bc8e2535143c3',
                                        preview: {
                                            url:
                                                '/img/uploads/designer/preview/9c1330f774e4dada3c1bc8e2535143c3.svg',
                                        },
                                    },
                                },
                            ],
                        },
                    },
                    a_2: {
                        canvasData: {
                            objects: [
                                {
                                    type: 'Image',
                                    imageData: {
                                        identifier: 'image1',
                                        fileName: '9c1330f774e4dada3c1bc8e2535143c3',
                                        preview: {
                                            url:
                                                '/img/uploads/designer/preview/9c1330f774e4dada3c1bc8e2535143c3.svg',
                                        },
                                    },
                                },
                                {
                                    type: 'Image',
                                    imageData: {
                                        identifier: 'image2',
                                        fileName: '8c1330f774e4dada3c1bc8e2535143c3',
                                        preview: {
                                            url:
                                                '/img/uploads/designer/preview/8c1330f774e4dada3c1bc8e2535143c3.svg',
                                        },
                                    },
                                },
                            ],
                        },
                    },
                },
            },
        };

        expect(getUserImagesByDesignArea(state)).toEqual([
            {
                identifier: 'image1',
                fileName: '9c1330f774e4dada3c1bc8e2535143c3',
                preview: {
                    url: '/img/uploads/designer/preview/9c1330f774e4dada3c1bc8e2535143c3.svg',
                },
            },
            {
                identifier: 'image2',
                fileName: '8c1330f774e4dada3c1bc8e2535143c3',
                preview: {
                    url: '/img/uploads/designer/preview/8c1330f774e4dada3c1bc8e2535143c3.svg',
                },
            },
        ]);
    });

    it('isEditableVectorImage returns the correct result', () => {
        expect(isEditableVectorImage({ url: 'fakeImage.svg' })).toEqual(true);
        expect(isEditableVectorImage({ url: 'data:image/svg+xml;base64,SVG+DATA' })).toEqual(true);
        expect(isEditableVectorImage({ url: 'fakeImage.jpg' })).toEqual(false);
        expect(isEditableVectorImage({ url: 'fakeImage.png' })).toEqual(false);
    });

    it('getPreviewUrlFromImageData returns the preview url from the given image data', () => {
        expect(getPreviewUrlFromImageData({ url: 'data:image/svg+xml;base64,SVG+DATA' })).toEqual(
            'data:image/svg+xml;base64,SVG+DATA'
        );
        expect(getPreviewUrlFromImageData({ url: 'data:image/png;base64,PNG+DATA' })).toEqual(
            'data:image/png;base64,PNG+DATA'
        );
        expect(
            getPreviewUrlFromImageData({ url: '/images/flowers.png' }, { host: 'http://myhost.com' })
        ).toEqual('http://myhost.com/images/flowers.png');
    });

    it('showVectorizeImageQuality returns the correct result for low quality images', () => {
        const svgImage = {
            original: {
                width: 50,
                height: 50,
                format: 'SVG',
            },
        };
        const pngImage = {
            original: {
                width: 50,
                height: 50,
                format: 'PNG',
            },
        };
        const jpgImage = {
            original: {
                width: 50,
                height: 50,
                format: 'JPEG',
            },
        };

        const minimumPixelAmount = 3000;

        expect(showVectorizeImageQuality(svgImage, minimumPixelAmount)).toEqual(false);
        expect(showVectorizeImageQuality(pngImage, minimumPixelAmount)).toEqual(true);
        expect(showVectorizeImageQuality(jpgImage, minimumPixelAmount)).toEqual(true);
    });
    it('showVectorizeImageQuality returns the correct result for higher quality images', () => {
        const svgImage = {
            original: {
                width: 60,
                height: 60,
                format: 'SVG',
            },
        };
        const pngImage = {
            original: {
                width: 60,
                height: 60,
                format: 'PNG',
            },
        };
        const jpgImage = {
            original: {
                width: 60,
                height: 60,
                format: 'JPEG',
            },
        };

        const minimumPixelAmount = 3000;

        expect(showVectorizeImageQuality(svgImage, minimumPixelAmount)).toEqual(false);
        expect(showVectorizeImageQuality(pngImage, minimumPixelAmount)).toEqual(false);
        expect(showVectorizeImageQuality(jpgImage, minimumPixelAmount)).toEqual(false);
    });

    test('getImageUsageInfo returns the correct info object using the image is not added to any area', () => {
        const state = {
            configurator: {
                configuration: {
                    designdata: {
                        a_1: {
                            canvasData: {
                                objects: [
                                    {
                                        type: 'Image',
                                        imageData: {
                                            identifier: 'image99',
                                        },
                                    },
                                ],
                            },
                        },
                    },
                },
            },
        };
        expect(getImageUsageInfo(state, 'image1')).toEqual({
            count: 0,
            designAreas: 0,
        });
    });

    test('getImageUsageInfo returns the correct info object using the same image 2 times on the same area', () => {
        const state = {
            configurator: {
                configuration: {
                    designdata: {
                        a_1: {
                            canvasData: {
                                objects: [
                                    {
                                        type: 'Image',
                                        imageData: {
                                            identifier: 'image1',
                                        },
                                    },
                                    {
                                        type: 'Image',
                                        imageData: {
                                            identifier: 'image1',
                                        },
                                    },
                                ],
                            },
                        },
                    },
                },
            },
        };
        expect(getImageUsageInfo(state, 'image1')).toEqual({
            count: 2,
            designAreas: 1,
        });
    });

    test('getImageUsageInfo returns the correct info object if the same image is present in multiple design areas', () => {
        const state = {
            configurator: {
                configuration: {
                    designdata: {
                        a_1: {
                            canvasData: {
                                objects: [
                                    {
                                        type: 'Image',
                                        imageData: {
                                            identifier: 'image1',
                                        },
                                    },
                                ],
                            },
                        },
                        a_2: {
                            canvasData: {
                                objects: [
                                    {
                                        type: 'Image',
                                        imageData: {
                                            identifier: 'image1',
                                        },
                                    },
                                ],
                            },
                        },
                    },
                },
            },
        };
        expect(getImageUsageInfo(state, 'image1')).toEqual({
            count: 2,
            designAreas: 2,
        });
    });

    describe('isImageReadyToBeAdded', () => {
        test('returns true if it is compatible and already placed once on any of the design areas', () => {
            const filteredDesignAreas = [
                {
                    identifier: 'area_1',
                    designProductionMethods: [
                        {
                            identifier: 'embroidery',
                            options: {
                                maxColorAmount: 4,
                                vectorsRequired: true,
                            },
                            colorPalettes: [
                                {
                                    identifier: 'default',
                                },
                            ],
                        },
                    ],
                },
            ];
            const image = {
                type: 'Image',
                identifier: 'image1',
                imageData: {
                    identifier: 'imageData1',
                    compatibilityInfoHash: {
                        maxColorAmount: 4,
                        vectorsRequired: true,
                        colorPalettes: ['default'],
                    },
                },
            };
            const state = {
                configurator: {
                    configuration: {
                        designdata: {
                            area_1: {
                                designProductionMethodIdentifier: 'embroidery',
                            },
                            area_2: {
                                canvasData: {
                                    objects: [image],
                                },
                            },
                        },
                    },
                },
                designArea: {
                    filteredDesignAreas,
                    selectedDesignArea: filteredDesignAreas[0],
                },
                imageGallery: {
                    mode: ImageGalleryModes.add,
                },
            };
            expect(isImageReadyToBeAdded(state, image.imageData)).toBe(true);
        });

        test('returns false if it is not compatible', () => {
            const filteredDesignAreas = [
                {
                    identifier: 'area_1',
                    designProductionMethods: [
                        {
                            identifier: 'embroidery',
                            options: {
                                maxColorAmount: 4,
                                vectorsRequired: true,
                            },
                            colorPalettes: [
                                {
                                    identifier: 'default',
                                },
                            ],
                        },
                    ],
                },
            ];
            const image = {
                type: 'Image',
                identifier: 'image1',
                imageData: {
                    identifier: 'imageData1',
                    compatibilityInfoHash: {
                        // <<< different compatibility hash >>>
                        maxColorAmount: 5,
                        vectorsRequired: true,
                        colorPalettes: ['hks'],
                    },
                },
            };
            const state = {
                configurator: {
                    configuration: {
                        designdata: {
                            area_1: {
                                designProductionMethodIdentifier: 'embroidery',
                            },
                            area_2: {
                                canvasData: {
                                    objects: [image],
                                },
                            },
                        },
                    },
                },
                designArea: {
                    filteredDesignAreas,
                    selectedDesignArea: filteredDesignAreas[0],
                },
                imageGallery: {
                    mode: ImageGalleryModes.add,
                },
            };
            expect(isImageReadyToBeAdded(state, image.imageData)).toBe(false);
        });

        test('returns false if it is not placed on any of the areas yet', () => {
            const filteredDesignAreas = [
                {
                    identifier: 'area_1',
                    designProductionMethods: [
                        {
                            identifier: 'embroidery',
                            options: {
                                maxColorAmount: 4,
                                vectorsRequired: true,
                            },
                            colorPalettes: [
                                {
                                    identifier: 'default',
                                },
                            ],
                        },
                    ],
                },
            ];
            const image = {
                type: 'Image',
                identifier: 'image1',
                imageData: {
                    identifier: 'imageData1',
                    compatibilityInfoHash: {
                        maxColorAmount: 4,
                        vectorsRequired: true,
                        colorPalettes: ['default'],
                    },
                },
            };
            const state = {
                configurator: {
                    configuration: {
                        designdata: {
                            // <<< the image is not added to any of the areas >>>
                            area_1: {
                                designProductionMethodIdentifier: 'embroidery',
                            },
                        },
                    },
                },
                designArea: {
                    filteredDesignAreas,
                    selectedDesignArea: filteredDesignAreas[0],
                },
                imageGallery: {
                    mode: ImageGalleryModes.add,
                },
            };
            expect(isImageReadyToBeAdded(state, image.imageData)).toBe(false);
        });

        test('returns false it is not in add mode', () => {
            const filteredDesignAreas = [
                {
                    identifier: 'area_1',
                    designProductionMethods: [
                        {
                            identifier: 'embroidery',
                            options: {
                                maxColorAmount: 4,
                                vectorsRequired: true,
                            },
                            colorPalettes: [
                                {
                                    identifier: 'default',
                                },
                            ],
                        },
                    ],
                },
            ];
            const image = {
                type: 'Image',
                identifier: 'image1',
                imageData: {
                    identifier: 'imageData1',
                    compatibilityInfoHash: {
                        maxColorAmount: 4,
                        vectorsRequired: true,
                        colorPalettes: ['default'],
                    },
                },
            };
            const state = {
                configurator: {
                    configuration: {
                        designdata: {
                            area_1: {
                                designProductionMethodIdentifier: 'embroidery',
                            },
                            area_2: {
                                canvasData: {
                                    objects: [image],
                                },
                            },
                        },
                    },
                },
                designArea: {
                    filteredDesignAreas,
                    selectedDesignArea: filteredDesignAreas[0],
                },
                imageGallery: {
                    mode: ImageGalleryModes.edit, /// <<< using edit mode >>>
                },
            };
            expect(isImageReadyToBeAdded(state, image.imageData)).toBe(false);
        });
    });

    describe('isImageCompatible', () => {
        test('returns true if it is compatible', () => {
            const filteredDesignAreas = [
                {
                    identifier: 'area_1',
                    designProductionMethods: [
                        {
                            identifier: 'embroidery',
                            options: {
                                maxColorAmount: 4,
                                vectorsRequired: true,
                            },
                            colorPalettes: [
                                {
                                    identifier: 'default',
                                },
                            ],
                        },
                    ],
                },
            ];
            const state = {
                configurator: {
                    configuration: {
                        designdata: {
                            area_1: {
                                designProductionMethodIdentifier: 'embroidery',
                            },
                        },
                    },
                },
                designArea: {
                    filteredDesignAreas,
                    selectedDesignArea: filteredDesignAreas[0],
                },
            };
            const imageData = {
                compatibilityInfoHash: {
                    maxColorAmount: 4,
                    vectorsRequired: true,
                    colorPalettes: ['default'],
                },
            };

            expect(isImageCompatible(state, imageData)).toBe(true);
        });

        test('returns false if it is not compatible', () => {
            const filteredDesignAreas = [
                {
                    identifier: 'area_1',
                    designProductionMethods: [
                        {
                            identifier: 'embroidery',
                            options: {
                                maxColorAmount: 4,
                                vectorsRequired: true,
                            },
                            colorPalettes: [
                                {
                                    identifier: 'default',
                                },
                            ],
                        },
                    ],
                },
            ];
            const state = {
                configurator: {
                    configuration: {
                        designdata: {
                            area_1: {
                                designProductionMethodIdentifier: 'embroidery',
                            },
                        },
                    },
                },
                designArea: {
                    filteredDesignAreas,
                    selectedDesignArea: filteredDesignAreas[0],
                },
            };
            const imageData = {
                compatibilityInfoHash: {
                    maxColorAmount: 5,
                    vectorsRequired: true,
                    colorPalettes: ['default', 'hks'],
                },
            };

            expect(isImageCompatible(state, imageData)).toBe(false);
        });
    });

    describe('isColorMappingCompatible', () => {
        test('returns true if the used color palette can be found in the checked palettes', () => {
            const colorPalettes = [
                {
                    identifier: 'default',
                    title: 'Standardfarben',
                },
                {
                    identifier: 'hks',
                    title: 'HKS',
                },
            ];
            const vectorizeColorsMap = {
                '#00FFAA': {
                    identifier: JSON.stringify({ palette: 'hks' }),
                },
            };
            expect(isColorMappingCompatible(colorPalettes, vectorizeColorsMap)).toBe(true);
        });
        test('returns false if the used color palette is missing from the checked palettes', () => {
            const incompatiblePalettes = [
                {
                    identifier: 'default',
                    title: 'Standardfarben',
                },
            ];
            const vectorizeColorsMap = {
                '#00FFAA': {
                    identifier: JSON.stringify({ palette: 'hks' }),
                },
            };
            expect(isColorMappingCompatible(incompatiblePalettes, vectorizeColorsMap)).toBe(false);
        });
    });

    test('isHardModified returns true if the related props are changed', () => {
        expect(
            isHardModified(
                {
                    operations: {
                        vectorize: false,
                    },
                },
                {
                    operations: {
                        vectorize: true,
                    },
                }
            )
        ).toBe(true);
        expect(
            isHardModified(
                {
                    compatibilityInfoHash: {
                        maxColorAmount: 4,
                        vectorsRequired: true,
                        colorPalettes: ['default'],
                    },
                },
                {
                    compatibilityInfoHash: {
                        maxColorAmount: null,
                        vectorsRequired: false,
                        colorPalettes: ['default'],
                    },
                }
            )
        ).toBe(true);
    });

    test('isHardModified returns false if none of the related props are changed', () => {
        expect(
            isHardModified(
                {
                    displayColorPreview: false,
                },
                {
                    displayColorPreview: true,
                }
            )
        ).toBe(false);
    });

    describe('isColorPreviewCompatible', () => {
        test('returns true if the current visualization effect is anything but embroidery', () => {
            const filteredDesignAreas = [
                {
                    identifier: 'area_1',
                    designProductionMethods: [
                        {
                            identifier: 'digital_printing',
                            options: {},
                            colorPalettes: [
                                {
                                    identifier: 'default',
                                },
                            ],
                        },
                    ],
                },
            ];
            const state = {
                configurator: {
                    configuration: {
                        designdata: {
                            area_1: {
                                designProductionMethodIdentifier: 'digital_printing',
                            },
                        },
                    },
                },
                designArea: {
                    filteredDesignAreas,
                    selectedDesignArea: filteredDesignAreas[0],
                },
                imageGallery: {
                    selectedImage: {
                        displayColorPreview: false,
                    },
                },
            };
            expect(isColorPreviewCompatible(state)).toBe(true);
        });

        test('returns true if the current visualization effect is embroidery and displayColorPreview is toggled', () => {
            const filteredDesignAreas = [
                {
                    identifier: 'area_1',
                    designProductionMethods: [
                        {
                            identifier: 'embroidery',
                            options: {
                                visualizationEffect: 'embroidery',
                            },
                            colorPalettes: [
                                {
                                    identifier: 'default',
                                },
                            ],
                        },
                    ],
                },
            ];
            const state = {
                configurator: {
                    configuration: {
                        designdata: {
                            area_1: {
                                designProductionMethodIdentifier: 'embroidery',
                            },
                        },
                    },
                },
                designArea: {
                    filteredDesignAreas,
                    selectedDesignArea: filteredDesignAreas[0],
                },
                imageGallery: {
                    selectedImage: {
                        displayColorPreview: true,
                    },
                },
            };
            expect(isColorPreviewCompatible(state)).toBe(true);
        });

        test('returns false if the current visualization effect is embroidery and displayColorPreview is NOT toggled', () => {
            const filteredDesignAreas = [
                {
                    identifier: 'area_1',
                    designProductionMethods: [
                        {
                            identifier: 'embroidery',
                            options: {
                                visualizationEffect: 'embroidery',
                            },
                            colorPalettes: [
                                {
                                    identifier: 'default',
                                },
                            ],
                        },
                    ],
                },
            ];
            const state = {
                configurator: {
                    configuration: {
                        designdata: {
                            area_1: {
                                designProductionMethodIdentifier: 'embroidery',
                            },
                        },
                    },
                },
                designArea: {
                    filteredDesignAreas,
                    selectedDesignArea: filteredDesignAreas[0],
                },
                imageGallery: {
                    selectedImage: {
                        displayColorPreview: false,
                    },
                },
            };
            expect(isColorPreviewCompatible(state)).toBe(false);
        });

        test('returns true if the current visualization effect is embroidery and the image is a gallery image', () => {
            const filteredDesignAreas = [
                {
                    identifier: 'area_1',
                    designProductionMethods: [
                        {
                            identifier: 'embroidery',
                            options: {
                                visualizationEffect: 'embroidery',
                            },
                            colorPalettes: [
                                {
                                    identifier: 'default',
                                },
                            ],
                        },
                    ],
                },
            ];
            const state = {
                configurator: {
                    configuration: {
                        designdata: {
                            area_1: {
                                designProductionMethodIdentifier: 'embroidery',
                            },
                        },
                    },
                },
                designArea: {
                    filteredDesignAreas,
                    selectedDesignArea: filteredDesignAreas[0],
                },
                imageGallery: {
                    selectedImage: {
                        gallery: true,
                    },
                },
            };
            expect(isColorPreviewCompatible(state)).toBe(true);
        });
    });
});
