import ImageEditor from 'tui-image-editor';
import colorPicker from 'tui-color-picker';
import {showFailToast, showSuccessToast} from "vant";

const MAX_RESOLUTION = 3264 * 2448; // 8MP (Mega Pixel)

const LOCALE = {
    "Apply": "确定",
    "Arrow": "箭头",
    "Arrow-2": "箭头-2",
    "Arrow-3": "箭头-3",
    "Blend": "",
    "Blur": "模糊",
    "Bold": "粗体",
    "Brightness": "明亮",
    "Bubble": "气泡",
    "Cancel": "取消",
    "Center": "中心",
    "Circle": "圆",
    "Color": "颜色",
    "Color Filter": "颜色过滤",
    "Crop": "裁剪",
    "Custom": "自定义",
    "Custom icon": "自定义图标",
    "Delete": "删除",
    "Delete-all": "删除全部",
    "Distance": "距离",
    "Draw": "绘画",
    "Emboss": "",
    "Fill": "填充",
    "Filter": "",
    "Flip": "翻转",
    "Flip X": "水平翻转",
    "Flip Y": "垂直翻转",
    "Free": "",
    "Grayscale": "灰度",
    "Heart": "❤️",
    "Icon": "图标",
    "Invert": "翻转",
    "Italic": "斜体",
    "Left": "左",
    "Load": "加载",
    "Load Mask Image": "加载遮罩图",
    "Location": "定位",
    "Mask": "遮罩",
    "Multiply": "翻倍",
    "Noise": "噪点",
    "Pixelate": "像素化",
    "Polygon": "多边形",
    "Range": "范围",
    "Rectangle": "矩形",
    "Redo": "重做",
    "Remove White": "",
    "Reset": "重置",
    "Right": "右",
    "Rotate": "旋转",
    "Sepia": "颜料",
    "Sepia2": "颜料2",
    "Shape": "形状",
    "Sharpen": "锐度",
    "Square": "方形",
    "Star-1": "星-1",
    "Star-2": "星-2",
    "Straight": "直线",
    "Stroke": "画笔",
    "Text": "文字",
    "Text size": "文字尺寸",
    "Threshold": "",
    "Tint": "着色",
    "Triangle": "三角形",
    "Underline": "下划线",
    "Undo": "撤销",
    "Value": "值"
}

const Helper = {
    show: (node) => {
        if (node) {
            node.style = "display:block";
        }
    },
    hide: (node) => {
        if (node) {
            node.style = "display:none"
        }
    },
    find: (parent, selector) => {
        parent.querySelector(selector)
    },
    on: (els, event, listener) => {
        els.forEach(el => el.addEventListener(event, listener))
    },
    addClass: (el, className) => {
        el.className += " " + className;
    },
    removeClass: (els, className) => {
        if (!els.length) {
            els = [els];
        }
        els.forEach(el => el.className = el.className.replace(className, ""))
    },
    hasClass: (el, className) => {
        return (el.className || "").split(" ").includes(className)
    }
}


const init = () => {
    const $ = args => document.querySelector(args)

    const rImageType = /data:(image\/.+);base64,/;
    const shapeOpt = {fill: '#fff', stroke: '#000', strokeWidth: 10};

    let activeObjectId;

    // Selector of image editor controls
    const submenuClass = '.submenu';
    const hiddenmenuClass = '.hiddenmenu';



    const $controls = $('.tui-image-editor-controls');
    const $menuButtons = $controls.querySelectorAll('.menu-button');
    const $submenuButtons = $controls.querySelectorAll('.submenu-button');
    const $btnShowMenus = $controls.querySelectorAll('.btn-prev');
    const $msg = $controls.querySelector('.msg');

    const $subMenus = $controls.querySelectorAll(submenuClass);
    const $hiddenMenus = $controls.querySelectorAll(hiddenmenuClass);

    // Image editor controls - top menu buttons
    const $inputImage = $('#input-image-file');
    const $btnSave = $('#btn-save');
    const $btnUndo = $('#btn-undo');
    const $btnRedo = $('#btn-redo');
    const $btnRemoveActiveObject = $('#btn-remove-active-object');

    // Image editor controls - bottom menu buttons
    const $btnCrop = $('#btn-crop');
    const $btnAddText = $('#btn-add-text');

    // Image editor controls - bottom submenu buttons
    const $btnApplyCrop = $('#btn-apply-crop');
    const $btnFlipX = $('#btn-flip-x');
    const $btnFlipY = $('#btn-flip-y');
    const $btnRotateClockwise = $('#btn-rotate-clockwise');
    const $btnRotateCounterClockWise = $('#btn-rotate-counter-clockwise');
    const $btnAddArrowIcon = $('#btn-add-arrow-icon');
    const $btnAddCancelIcon = $('#btn-add-cancel-icon');
    const $btnAddCustomIcon = $('#btn-add-custom-icon');
    const $btnFreeDrawing = $('#btn-free-drawing');
    const $btnLineDrawing = $('#btn-line-drawing');
    const $btnAddRect = $('#btn-add-rect');
    const $btnAddSquare = $('#btn-add-square');
    const $btnAddEllipse = $('#btn-add-ellipse');
    const $btnAddCircle = $('#btn-add-circle');
    const $btnAddTriangle = $('#btn-add-triangle');
    const $btnChangeTextStyle = $('.btn-change-text-style');

    // Image editor controls - etc.
    const $inputTextSizeRange = $('#input-text-size-range');
    const $inputBrushWidthRange = $('#input-brush-range');
    const $inputStrokeWidthRange = $('#input-stroke-range');
    const $inputCheckTransparent = $('#input-check-transparent');

    // Colorpicker
    const iconColorpicker = colorPicker.create({
        container: $('#tui-icon-color-picker'),
        color: '#000000',
    });

    const textColorpicker = colorPicker.create({
        container: $('#tui-text-color-picker'),
        color: '#000000',
    });

    const brushColorpicker = colorPicker.create({
        container: $('#tui-brush-color-picker'),
        color: '#000000',
    });

    const shapeColorpicker = colorPicker.create({
        container: $('#tui-shape-color-picker'),
        color: '#000000',
    });

    // Create image editor
    const imageEditor = new ImageEditor('.tui-image-editor', {
        // includeUI: {
        //     locale: LOCALE
        // },
        cssMaxWidth: document.documentElement.clientWidth,
        cssMaxHeight: document.documentElement.clientHeight,
        selectionStyle: {
            cornerSize: 50,
            rotatingPointOffset: 100,
        },
    });

    let $displayingSubMenu, $displayingHiddenMenu;

    function hexToRGBa(hex, alpha) {
        const r = parseInt(hex.slice(1, 3), 16);
        const g = parseInt(hex.slice(3, 5), 16);
        const b = parseInt(hex.slice(5, 7), 16);
        const a = alpha || 1;

        return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')';
    }

    function base64ToBlob(data) {
        let mimeString = '';
        let raw, uInt8Array, i, rawLength;

        raw = data.replace(rImageType, function (header, imageType) {
            mimeString = imageType;

            return '';
        });

        raw = atob(raw);
        rawLength = raw.length;
        uInt8Array = new Uint8Array(rawLength); // eslint-disable-line

        for (i = 0; i < rawLength; i += 1) {
            uInt8Array[i] = raw.charCodeAt(i);
        }

        return new Blob([uInt8Array], { type: mimeString });
    }

    function getBrushSettings() {
        const brushWidth = $inputBrushWidthRange.value;
        const brushColor = brushColorpicker.getColor();

        return {
            width: brushWidth,
            color: hexToRGBa(brushColor, 0.5),
        };
    }

    function activateShapeMode() {
        imageEditor.stopDrawingMode();
    }

    function activateIconMode() {
        imageEditor.stopDrawingMode();
    }

    function activateTextMode() {
        if (imageEditor.getDrawingMode() !== 'TEXT') {
            imageEditor.stopDrawingMode();
            imageEditor.startDrawingMode('TEXT');
        }
    }

    function setTextToolbar(obj) {
        const fontSize = obj.fontSize;
        const fontColor = obj.fill;

        $inputTextSizeRange.value = fontSize;
        textColorpicker.setColor(fontColor);
    }

    function setIconToolbar(obj) {
        const iconColor = obj.fill;

        iconColorpicker.setColor(iconColor);
    }

    function setShapeToolbar(obj) {
        let strokeColor, fillColor, isTransparent;
        const colorType = $('[name="select-color-type"]:checked').value;

        if (colorType === 'stroke') {
            strokeColor = obj.stroke;
            isTransparent = strokeColor === 'transparent';

            if (!isTransparent) {
                shapeColorpicker.setColor(strokeColor);
            }
        } else if (colorType === 'fill') {
            fillColor = obj.fill;
            isTransparent = fillColor === 'transparent';

            if (!isTransparent) {
                shapeColorpicker.setColor(fillColor);
            }
        }

        $inputCheckTransparent.checked = isTransparent;
        $inputStrokeWidthRange.value = obj.strokeWith;
    }

    function showSubMenu(type) {
        let index;

        switch (type) {
            case 'shape':
                index = 3;
                break;
            case 'icon':
                index = 4;
                break;
            case 'text':
                index = 5;
                break;
            default:
                index = 0;
        }

        Helper.hide($displayingSubMenu)
        Helper.hide($displayingHiddenMenu);

        $displayingSubMenu = $menuButtons[index].parentNode.querySelector(submenuClass);
        Helper.show($displayingSubMenu)
    }

    // Bind custom event of image editor
    imageEditor.on({
        undoStackChanged: function (length) {
            if (length) {
                Helper.removeClass($btnUndo, "disabled")
            } else {
                Helper.addClass($btnUndo, "disabled")
            }
        },
        redoStackChanged: function (length) {
            if (length) {
                Helper.removeClass($btnRedo, "disabled")
            } else {
                Helper.addClass($btnRedo, "disabled")
            }
        },
        objectScaled: function (obj) {
            if (obj.type === 'text') {
                $inputTextSizeRange.value = obj.fontSize;
            }
        },
        objectActivated: function (obj) {
            activeObjectId = obj.id;
            if (obj.type === 'rect' || obj.type === 'circle' || obj.type === 'triangle') {
                showSubMenu('shape');
                setShapeToolbar(obj);
                activateShapeMode();
            } else if (obj.type === 'icon') {
                showSubMenu('icon');
                setIconToolbar(obj);
                activateIconMode();
            } else if (obj.type === 'text') {
                showSubMenu('text');
                setTextToolbar(obj);
                activateTextMode();
            }
        },
    });

    // Image editor controls action
    $menuButtons.forEach(el => {
        el.addEventListener("click", () => {
            $displayingSubMenu = el.parentNode.querySelector(submenuClass);
            Helper.show($displayingSubMenu)
            $displayingHiddenMenu = el.parentNode.querySelector(hiddenmenuClass);
        })
    });
    $submenuButtons.forEach(el => {
        el.addEventListener("click", () => {
            Helper.hide($displayingHiddenMenu);
            $displayingHiddenMenu = el.parentNode.querySelector(hiddenmenuClass);
            Helper.show($displayingHiddenMenu)
        })
    })


    $btnShowMenus.forEach(el => {
        el.addEventListener('click', function () {
            Helper.hide($displayingSubMenu);
            Helper.hide($displayingHiddenMenu)
            Helper.show($msg)

            imageEditor.stopDrawingMode();
        });
    })



    // Image load action
    $inputImage.addEventListener('change', function (event) {
        let file, img, resolution;

        file = event.target.files[0];

        if (file) {
            img = new Image();

            img.onload = function () {
                resolution = this.width * this.height;

                console.log("resolution...", resolution)
                if (resolution <= MAX_RESOLUTION) {
                    imageEditor.loadImageFromFile(file).then(function (re) {
                        console.log(re)
                        imageEditor.clearUndoStack();
                    });
                } else {
                    showFailToast("图片太大!\n最大支持尺寸为 3264 * 2448!");
                }

                URL.revokeObjectURL(file);
            };

            img.onerror = function (e) {
                console.error("error...", e)
            }

            img.src = URL.createObjectURL(file);
        }
    });

    // Undo action
    $btnUndo.addEventListener('click', function () {
        if (!Helper.hasClass($btnUndo, 'disabled')) {
            imageEditor.undo();
        }
    });

    // Redo action
    $btnRedo.addEventListener('click', function () {
        if (!Helper.hasClass($btnRedo, 'disabled')) {
            imageEditor.redo();
        }
    });

    // Remove active object action
    $btnRemoveActiveObject.addEventListener('click', function () {
        if (activeObjectId) {
            imageEditor.removeObject(activeObjectId);
        } else {
            showFailToast("请选择要删除的对象")
        }
    });

    // Download action
    $btnSave.addEventListener('click', function () {
        let imageName = imageEditor.getImageName();
        const dataURL = imageEditor.toDataURL();
        console.log(imageName, dataURL)
        // let blob, type;
        //
        // blob = base64ToBlob(dataURL);
        // type = blob.type.split('/')[1];
        // if (imageName.split('.').pop() !== type) {
        //     imageName += '.' + type;
        // }

        // console.log(imageName, blob)
        // Library: FileSaver - saveAs
        // saveAs(blob, imageName); // eslint-disable-line
    });

    // Crop menu action
    $btnCrop.addEventListener('click', function () {
        imageEditor.startDrawingMode('CROPPER');
    });

    $btnApplyCrop.addEventListener('click', function () {
        imageEditor.crop(imageEditor.getCropzoneRect()).then(function () {
            imageEditor.stopDrawingMode();
            Helper.removeClass($subMenus, "show")
            Helper.removeClass($hiddenMenus, "show")
        });
    });

    // Orientation menu action
    $btnRotateClockwise.addEventListener('click', function () {
        imageEditor.rotate(90);
    });

    $btnRotateCounterClockWise.addEventListener('click', function () {
        imageEditor.rotate(-90);
    });

    $btnFlipX.addEventListener('click', function () {
        imageEditor.flipX();
    });

    $btnFlipY.addEventListener('click', function () {
        imageEditor.flipY();
    });

    // Icon menu action
    $btnAddArrowIcon.addEventListener('click', function () {
        imageEditor.addIcon('arrow');
    });

    $btnAddCancelIcon.addEventListener('click', function () {
        imageEditor.addIcon('cancel');
    });

    $btnAddCustomIcon.addEventListener('click', function () {
        imageEditor.addIcon('customArrow');
    });

    iconColorpicker.on('selectColor', function (event) {
        imageEditor.changeIconColor(activeObjectId, event.color);
    });

    // Text menu action
    $btnAddText.addEventListener('click', function () {
        const initText = 'DoubleClick';

        imageEditor.startDrawingMode('TEXT');
        imageEditor.addText(initText, {
            styles: {
                fontSize: parseInt($inputTextSizeRange.val(), 10),
            },
        });
    });

    $btnChangeTextStyle.addEventListener('click', function () {
        const styleType = this.getAttribute('data-style-type');
        const styleObj = {};
        let styleObjKey;

        switch (styleType) {
            case 'bold':
                styleObjKey = 'fontWeight';
                break;
            case 'italic':
                styleObjKey = 'fontStyle';
                break;
            case 'underline':
                styleObjKey = 'underline';
                break;
            case 'left':
                styleObjKey = 'textAlign';
                break;
            case 'center':
                styleObjKey = 'textAlign';
                break;
            case 'right':
                styleObjKey = 'textAlign';
                break;
            default:
                styleObjKey = '';
        }

        styleObj[styleObjKey] = styleType;

        imageEditor.changeTextStyle(activeObjectId, styleObj);
    });

    $inputTextSizeRange.addEventListener('change', function () {
        imageEditor.changeTextStyle(activeObjectId, {
            fontSize: parseInt(this.value, 10),
        });
    });

    textColorpicker.on('selectColor', function (event) {
        imageEditor.changeTextStyle(activeObjectId, {
            fill: event.color,
        });
    });

    // Draw line menu action
    $btnFreeDrawing.addEventListener('click', function () {
        const settings = getBrushSettings();

        imageEditor.stopDrawingMode();
        imageEditor.startDrawingMode('FREE_DRAWING', settings);
    });

    $btnLineDrawing.addEventListener('click', function () {
        const settings = getBrushSettings();

        imageEditor.stopDrawingMode();
        imageEditor.startDrawingMode('LINE_DRAWING', settings);
    });

    $inputBrushWidthRange.addEventListener('change', function () {
        imageEditor.setBrush({
            width: parseInt(this.value, 10),
        });
    });

    brushColorpicker.on('selectColor', function (event) {
        imageEditor.setBrush({
            color: hexToRGBa(event.color, 0.5),
        });
    });

    // Add shape menu action
    $btnAddRect.addEventListener('click', function () {
        imageEditor.addShape(
            'rect',
            tui.util.extend(
                {
                    width: 500,
                    height: 300,
                },
                shapeOpt
            )
        );
    });

    $btnAddSquare.addEventListener('click', function () {
        imageEditor.addShape(
            'rect',
            tui.util.extend(
                {
                    width: 400,
                    height: 400,
                    isRegular: true,
                },
                shapeOpt
            )
        );
    });

    $btnAddEllipse.addEventListener('click', function () {
        imageEditor.addShape(
            'circle',
            tui.util.extend(
                {
                    rx: 300,
                    ry: 200,
                },
                shapeOpt
            )
        );
    });

    $btnAddCircle.addEventListener('click', function () {
        imageEditor.addShape(
            'circle',
            tui.util.extend(
                {
                    rx: 200,
                    ry: 200,
                    isRegular: true,
                },
                shapeOpt
            )
        );
    });

    $btnAddTriangle.addEventListener('click', function () {
        imageEditor.addShape(
            'triangle',
            tui.util.extend(
                {
                    width: 500,
                    height: 400,
                    isRegular: true,
                },
                shapeOpt
            )
        );
    });

    $inputStrokeWidthRange.addEventListener('change', function () {
        imageEditor.changeShape(activeObjectId, {
            strokeWidth: parseInt(this.value, 10),
        });
    });

    $inputCheckTransparent.addEventListener('change', function () {
        const colorType = $('[name="select-color-type"]:checked').value;
        const isTransparent = this.checked;
        let color;

        if (!isTransparent) {
            color = shapeColorpicker.getColor();
        } else {
            color = 'transparent';
        }

        if (colorType === 'stroke') {
            imageEditor.changeShape(activeObjectId, {
                stroke: color,
            });
        } else if (colorType === 'fill') {
            imageEditor.changeShape(activeObjectId, {
                fill: color,
            });
        }
    });

    shapeColorpicker.on('selectColor', function (event) {
        const colorType = $('[name="select-color-type"]:checked').value;
        const isTransparent = $inputCheckTransparent.checked;
        const color = event.color;

        if (isTransparent) {
            return;
        }

        if (colorType === 'stroke') {
            imageEditor.changeShape(activeObjectId, {
                stroke: color,
            });
        } else if (colorType === 'fill') {
            imageEditor.changeShape(activeObjectId, {
                fill: color,
            });
        }
    });

    return imageEditor;
}


export {
    init
}
