import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
import React, { useState, useEffect, useMemo, useCallback, useLayoutEffect } from "react";
import Taro, { createSelectorQuery } from "@tarojs/taro";
import classNames from "classnames";
import { Canvas, View } from "@tarojs/components";
import { getWindowInfo } from "../../utils/taro/get-system-info";
import { Button } from "../button/button";
import { useConfig } from "../configprovider/index";
import { ComponentDefaults } from "../../utils/typings";
import { useTouch } from "../../hooks/use-touch";
import { clamp, preventDefault } from "../../utils";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
    maxZoom: 3,
    space: 10,
    toolbar: [
        /*#__PURE__*/ React.createElement(Button, {
            type: "danger",
            key: "cancel"
        }, "Cancel"),
        /*#__PURE__*/ React.createElement(Button, {
            key: "reset"
        }, "Reset"),
        /*#__PURE__*/ React.createElement(Button, {
            key: "rotate"
        }, "Rotate"),
        /*#__PURE__*/ React.createElement(Button, {
            type: "success",
            key: "confirm"
        }, "Confirm")
    ],
    toolbarPosition: 'bottom',
    editText: 'Edit',
    sizeType: [
        'original',
        'compressed'
    ],
    sourceType: [
        'album',
        'camera'
    ],
    shape: 'square'
});
var classPrefix = "nut-avatar-cropper";
export var AvatarCropper = function(props) {
    var locale = useConfig().locale;
    defaultProps.toolbar = [
        /*#__PURE__*/ React.createElement(Button, {
            type: "danger",
            key: "cancel"
        }, locale.cancel),
        /*#__PURE__*/ React.createElement(Button, {
            key: "reset"
        }, locale.reset),
        /*#__PURE__*/ React.createElement(Button, {
            key: "rotate"
        }, locale.avatarCropper.rotate),
        /*#__PURE__*/ React.createElement(Button, {
            type: "success",
            key: "confirm"
        }, locale.confirm)
    ];
    defaultProps.editText = locale.edit;
    var _ref = _object_spread({}, defaultProps, props), children = _ref.children, toolbar = _ref.toolbar, maxZoom = _ref.maxZoom, space = _ref.space, toolbarPosition = _ref.toolbarPosition, editText = _ref.editText, sizeType = _ref.sizeType, sourceType = _ref.sourceType, shape = _ref.shape, className = _ref.className, style = _ref.style, onConfirm = _ref.onConfirm, onCancel = _ref.onCancel, rest = _object_without_properties(_ref, [
        "children",
        "toolbar",
        "maxZoom",
        "space",
        "toolbarPosition",
        "editText",
        "sizeType",
        "sourceType",
        "shape",
        "className",
        "style",
        "onConfirm",
        "onCancel"
    ]);
    var cls = classNames(classPrefix, 'taro', className, shape === 'round' && 'round');
    var toolbarPositionCls = classNames("".concat(classPrefix, "-popup-toolbar"), toolbarPosition);
    var _useState = _sliced_to_array(useState(false), 2), visible = _useState[0], setVisible = _useState[1];
    var _useState1 = _sliced_to_array(useState(false), 2), moving = _useState1[0], setMoving = _useState1[1];
    var _useState2 = _sliced_to_array(useState(false), 2), zooming = _useState2[0], setZooming = _useState2[1];
    var systemInfo = getWindowInfo();
    // 支付宝基础库2.7.0以上支持，需要开启支付宝小程序canvas2d
    var showAlipayCanvas2D = useMemo(function() {
        return Taro.getEnv() === 'ALIPAY' && parseInt(Taro.SDKVersion.replace(/\./g, '')) >= 270;
    }, []);
    var showPixelRatio = Taro.getEnv() === 'WEB' || showAlipayCanvas2D;
    // 设备像素比
    var pixelRatio = showPixelRatio ? systemInfo.pixelRatio : 1;
    var _useState3 = _sliced_to_array(useState({
        defScale: 1,
        scale: 1,
        angle: 0,
        moveX: 0,
        moveY: 0,
        displayWidth: systemInfo.windowWidth * pixelRatio,
        displayHeight: systemInfo.windowHeight * pixelRatio,
        cropperWidth: systemInfo.windowWidth * pixelRatio - space * pixelRatio * 2,
        cropperHeight: systemInfo.windowWidth * pixelRatio - space * pixelRatio * 2
    }), 2), state = _useState3[0], setState = _useState3[1];
    var defDrawImage = {
        src: '',
        x: 0,
        y: 0,
        width: 0,
        height: 0
    };
    var _useState4 = _sliced_to_array(useState(_object_spread({}, defDrawImage)), 2), drawImage = _useState4[0], setDrawImg = _useState4[1];
    var _useState5 = _sliced_to_array(useState({
        canvasId: "canvas-".concat(Date.now()),
        cropperCanvas: null,
        cropperCanvasContext: null
    }), 2), canvasAll = _useState5[0], setCanvasAll = _useState5[1];
    useLayoutEffect(function() {
        if (showAlipayCanvas2D) {
            var canvasId = canvasAll.canvasId;
            createSelectorQuery().select("#".concat(canvasId)).node(function(param) {
                var canvas = param.node;
                canvas.width = state.displayWidth;
                canvas.height = state.displayHeight;
                setCanvasAll(_object_spread_props(_object_spread({}, canvasAll), {
                    cropperCanvas: canvas
                }));
            }).exec();
        }
    }, [
        showAlipayCanvas2D,
        state.displayHeight,
        state.displayWidth
    ]);
    useEffect(function() {
        setCanvasAll(_object_spread_props(_object_spread({}, canvasAll), {
            cropperCanvasContext: Taro.createCanvasContext(canvasAll.canvasId)
        }));
    }, []);
    var touch = useTouch();
    var highlightStyle = useMemo(function() {
        var width = "".concat(state.cropperWidth / pixelRatio, "px");
        var height = width;
        return {
            width: width,
            height: height,
            borderRadius: shape === 'round' ? '50%' : ''
        };
    }, [
        pixelRatio,
        state.cropperWidth
    ]);
    // 是否是横向
    var isAngle = useMemo(function() {
        return state.angle === 90 || state.angle === 270;
    }, [
        state.angle
    ]);
    var canvasStyle = useMemo(function() {
        return {
            width: "".concat(state.displayWidth / pixelRatio, "px"),
            height: "".concat(state.displayHeight / pixelRatio, "px")
        };
    }, [
        pixelRatio,
        state.displayHeight,
        state.displayWidth
    ]);
    // 最大横向移动距离
    var maxMoveX = useMemo(function() {
        var displayWidth = state.displayWidth, scale = state.scale, cropperWidth = state.cropperWidth;
        if (isAngle) {
            return Math.max(0, (drawImage.height * scale - cropperWidth) / 2);
        }
        return Math.max(0, (displayWidth * scale - cropperWidth) / 2);
    }, [
        drawImage.height,
        isAngle,
        state
    ]);
    // 最大纵向移动距离
    var maxMoveY = useMemo(function() {
        var displayWidth = state.displayWidth, scale = state.scale, cropperWidth = state.cropperWidth;
        if (isAngle) {
            return Math.max(0, (displayWidth * scale - cropperWidth) / 2);
        }
        return Math.max(0, (drawImage.height * scale - cropperWidth) / 2);
    }, [
        drawImage.height,
        isAngle,
        state
    ]);
    // base64转图片
    var dataURLToImage = function(dataURL) {
        return new Promise(function(resolve) {
            var img = new Image();
            img.onload = function() {
                return resolve(img);
            };
            img.src = dataURL;
        });
    };
    // base64转图片(canvasImage)
    var dataURLToCanvasImage = function(canvas, dataURL) {
        return new Promise(function(resolve) {
            var img = canvas.createImage();
            img.onload = function() {
                return resolve(img);
            };
            img.src = dataURL;
        });
    };
    var canvas2dDraw = useCallback(function(ctx) {
        var src = drawImage.src, width = drawImage.width, height = drawImage.height, x = drawImage.x, y = drawImage.y;
        if (!ctx || !src) return;
        var moveX = state.moveX, moveY = state.moveY, scale = state.scale, angle = state.angle, displayWidth = state.displayWidth, displayHeight = state.displayHeight, cropperWidth = state.cropperWidth;
        ctx.clearRect(0, 0, displayWidth, displayHeight);
        ctx.fillStyle = '#666';
        ctx.fillRect(0, 0, displayWidth, displayHeight);
        ctx.fillStyle = '#000';
        ctx.fillRect(space * pixelRatio, (displayHeight - cropperWidth) / 2, cropperWidth, cropperWidth);
        ctx.translate(displayWidth / 2 + moveX, displayHeight / 2 + moveY);
        ctx.rotate(Math.PI / 180 * angle);
        ctx.scale(scale, scale);
        ctx.drawImage(src, x, y, width, height);
    }, [
        drawImage,
        state
    ]);
    // web绘制
    var webDraw = useCallback(function() {
        var canvasDom = document.getElementById(canvasAll.canvasId);
        var canvas = canvasDom;
        if ((canvasDom === null || canvasDom === void 0 ? void 0 : canvasDom.tagName) !== 'CANVAS') {
            canvas = canvasDom === null || canvasDom === void 0 ? void 0 : canvasDom.getElementsByTagName('canvas')[0];
        }
        if (!canvas) return;
        canvas.width = state.displayWidth;
        canvas.height = state.displayHeight;
        var ctx = canvas.getContext('2d');
        canvas2dDraw(ctx);
    }, [
        canvas2dDraw
    ]);
    var alipayDraw = useCallback(function() {
        var ctx = canvasAll.cropperCanvas.getContext('2d');
        ctx && ctx.resetTransform();
        canvas2dDraw(ctx);
    }, [
        canvas2dDraw,
        canvasAll.cropperCanvas
    ]);
    // 绘制显示的canvas内容
    var draw = useCallback(function() {
        if (Taro.getEnv() === 'WEB') {
            webDraw();
            return;
        }
        if (showAlipayCanvas2D) {
            alipayDraw();
            return;
        }
        var src = drawImage.src, width = drawImage.width, height = drawImage.height, x = drawImage.x, y = drawImage.y;
        var moveX = state.moveX, moveY = state.moveY, scale = state.scale, angle = state.angle, displayWidth = state.displayWidth, displayHeight = state.displayHeight, cropperWidth = state.cropperWidth;
        var cropperCanvasContext = canvasAll.cropperCanvasContext;
        var ctx = cropperCanvasContext;
        if (!ctx) return;
        // 绘制背景
        ctx.clearRect(0, 0, displayWidth, displayHeight);
        ctx.fillStyle = '#666';
        ctx.setFillStyle('#666');
        ctx.fillRect(0, 0, displayWidth, displayHeight);
        ctx.stroke();
        ctx.fill();
        ctx.fillStyle = '#000';
        ctx.setFillStyle('#000');
        ctx.fillRect(space, (displayHeight - cropperWidth) / 2, cropperWidth, cropperWidth);
        ctx.stroke();
        ctx.fill();
        // 绘制偏移量
        ctx.translate(displayWidth / 2 + moveX, displayHeight / 2 + moveY);
        ctx.rotate(Math.PI / 180 * angle);
        ctx.scale(scale, scale);
        ctx.drawImage(src, x, y, width, height);
        ctx.draw();
    }, [
        drawImage,
        state.scale,
        state.angle,
        state.moveX,
        state.moveY
    ]);
    useEffect(function() {
        if (Math.abs(state.moveX) > maxMoveX) {
            setState(_object_spread_props(_object_spread({}, state), {
                moveX: maxMoveX
            }));
        }
        if (Math.abs(state.moveY) > maxMoveY) {
            setState(_object_spread_props(_object_spread({}, state), {
                moveY: maxMoveY
            }));
        }
        draw();
    }, [
        state,
        maxMoveX,
        maxMoveY,
        draw
    ]);
    // 设置绘制图片
    var setDrawImgInfo = function(image) {
        return _async_to_generator(function() {
            var displayWidth, cropperWidth, copyDrawImg, imgWidth, imgHeight, isPortrait, rate, scale;
            return _ts_generator(this, function(_state) {
                switch(_state.label){
                    case 0:
                        displayWidth = state.displayWidth, cropperWidth = state.cropperWidth;
                        copyDrawImg = _object_spread({}, defDrawImage);
                        imgWidth = image.width, imgHeight = image.height;
                        copyDrawImg.src = image.path;
                        if (!(Taro.getEnv() === 'WEB')) return [
                            3,
                            2
                        ];
                        return [
                            4,
                            dataURLToImage(image.path)
                        ];
                    case 1:
                        copyDrawImg.src = _state.sent();
                        _state.label = 2;
                    case 2:
                        if (!showAlipayCanvas2D) return [
                            3,
                            4
                        ];
                        return [
                            4,
                            dataURLToCanvasImage(canvasAll.cropperCanvas, image.path)
                        ];
                    case 3:
                        copyDrawImg.src = _state.sent();
                        _state.label = 4;
                    case 4:
                        isPortrait = imgHeight > imgWidth;
                        rate = isPortrait ? imgWidth / imgHeight : imgHeight / imgWidth;
                        copyDrawImg.width = displayWidth;
                        copyDrawImg.height = isPortrait ? displayWidth / rate : displayWidth * rate;
                        copyDrawImg.x = -copyDrawImg.width / 2;
                        copyDrawImg.y = -copyDrawImg.height / 2;
                        setDrawImg(copyDrawImg);
                        scale = cropperWidth / (isPortrait ? copyDrawImg.width : copyDrawImg.height);
                        setState(_object_spread_props(_object_spread({}, state), {
                            defScale: scale
                        }));
                        resetScale(scale);
                        return [
                            2
                        ];
                }
            });
        })();
    };
    var chooseImage = function() {
        Taro.chooseImage({
            count: 1,
            // 可以指定是原图还是压缩图，默认二者都有
            sizeType: sizeType,
            sourceType: sourceType,
            success: function(res) {
                // 返回选定照片的本地文件路径列表，tempFilePath可以作为img标签的src属性显示图片
                var tempFiles = res.tempFiles;
                !!tempFiles.length && imageChange(tempFiles[0]);
            }
        });
    };
    var imageChange = function(file) {
        return _async_to_generator(function() {
            return _ts_generator(this, function(_state) {
                Taro.getImageInfo({
                    src: file.path
                }).then(function(res) {
                    setVisible(true);
                    setDrawImgInfo(res);
                });
                return [
                    2
                ];
            });
        })();
    };
    var resetScale = function(scale) {
        setState(_object_spread_props(_object_spread({}, state), {
            moveX: 0,
            moveY: 0,
            angle: 0,
            scale: scale || state.defScale,
            defScale: scale || state.defScale
        }));
    };
    var setScale = function(scale) {
        scale = clamp(scale, +0.3, +maxZoom + 1);
        if (scale !== state.scale) {
            setState(_object_spread_props(_object_spread({}, state), {
                scale: scale
            }));
        }
    };
    // 计算两个点的距离
    var getDistance = function(touches) {
        return Math.sqrt(Math.pow(touches[0].clientX - touches[1].clientX, 2) + Math.pow(touches[0].clientY - touches[1].clientY, 2));
    };
    var _useState6 = _sliced_to_array(useState({
        startMoveX: 0,
        startMoveY: 0,
        startScale: 0,
        startDistance: 0
    }), 2), startMove = _useState6[0], setStartMove = _useState6[1];
    var startMoveX = startMove.startMoveX, startMoveY = startMove.startMoveY, startScale = startMove.startScale, startDistance = startMove.startDistance;
    var onTouchStart = function(event) {
        var touches = event.touches;
        var offsetX = touch.offsetX;
        touch.start(event);
        var fingerNum = touches === null || touches === void 0 ? void 0 : touches.length;
        setStartMove(_object_spread_props(_object_spread({}, startMove), {
            startMoveX: state.moveX,
            startMoveY: state.moveY
        }));
        setMoving(fingerNum === 1);
        setZooming(fingerNum === 2 && !offsetX.current);
        if (fingerNum === 2 && !offsetX.current) {
            setStartMove(_object_spread_props(_object_spread({}, startMove), {
                startScale: state.scale,
                startDistance: getDistance(event.touches)
            }));
        }
    };
    var onTouchMove = function(event) {
        var touches = event.touches;
        touch.move(event);
        if (moving || zooming) {
            preventDefault(event, true);
        }
        if (moving) {
            var deltaX = touch.deltaX, deltaY = touch.deltaY;
            var moveX = deltaX.current * state.scale + startMoveX;
            var moveY = deltaY.current * state.scale + startMoveY;
            setState(_object_spread_props(_object_spread({}, state), {
                moveX: clamp(moveX, -maxMoveX, maxMoveX),
                moveY: clamp(moveY, -maxMoveY, maxMoveY)
            }));
        }
        if (zooming && touches.length === 2) {
            var distance = getDistance(touches);
            var scale = startScale * distance / startDistance;
            setScale(scale);
        }
    };
    var onTouchEnd = function(event) {
        var stopPropagation = false;
        if (moving || zooming) {
            stopPropagation = !(moving && startMoveX === state.moveX && startMoveY === state.moveY);
            if (!event.touches.length) {
                if (zooming) {
                    setState(_object_spread_props(_object_spread({}, state), {
                        moveX: clamp(state.moveX, -maxMoveX, maxMoveX),
                        moveY: clamp(state.moveY, -maxMoveY, maxMoveY)
                    }));
                    setZooming(false);
                }
                setMoving(false);
                setStartMove(_object_spread_props(_object_spread({}, startMove), {
                    startMoveX: 0,
                    startMoveY: 0,
                    startScale: state.defScale
                }));
                if (state.scale < state.defScale) {
                    resetScale();
                }
                if (state.scale > maxZoom) {
                    setState(_object_spread_props(_object_spread({}, state), {
                        scale: +maxZoom
                    }));
                }
            }
        }
        preventDefault(event, stopPropagation);
        touch.reset();
    };
    var reset = function() {
        setState(_object_spread_props(_object_spread({}, state), {
            angle: 0
        }));
    };
    var rotate = function() {
        if (state.angle === 270) {
            setState(_object_spread_props(_object_spread({}, state), {
                angle: 0
            }));
            return;
        }
        setState(_object_spread_props(_object_spread({}, state), {
            angle: state.angle + 90
        }));
    };
    var cancel = function() {
        var isEmit = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : true;
        setVisible(false);
        resetScale();
        isEmit && onCancel && onCancel();
    };
    // web裁剪图片
    var confirmWEB = function() {
        var cropperWidth = state.cropperWidth, displayHeight = state.displayHeight;
        var canvasDom = document.getElementById(canvasAll.canvasId);
        var canvas = canvasDom;
        if ((canvasDom === null || canvasDom === void 0 ? void 0 : canvasDom.tagName) !== 'CANVAS') {
            canvas = canvasDom === null || canvasDom === void 0 ? void 0 : canvasDom.getElementsByTagName('canvas')[0];
        }
        var width = cropperWidth;
        var height = cropperWidth;
        // 创建一个新的canvas元素，用于裁剪后的内容
        var croppedCanvas = document.createElement('canvas');
        var croppedCtx = croppedCanvas.getContext('2d');
        // 设置新canvas的大小与裁剪区域相同
        croppedCanvas.width = width;
        croppedCanvas.height = height;
        // 使用drawImage方法将原canvas中指定区域的内容绘制到新canvas上
        canvas && croppedCtx.drawImage(canvas, space * pixelRatio, (displayHeight - cropperWidth) / 2, width, height, 0, 0, width, height);
        // 将裁剪后的内容转换为图片格式
        var imageDataURL = croppedCanvas.toDataURL('image/png');
        onConfirm && onConfirm(imageDataURL);
        cancel(false);
    };
    // 支付宝基础库2.7.0以上支持，需要开启支付宝小程序canvas2d
    var confirmALIPAY = function() {
        var cropperWidth = state.cropperWidth, displayHeight = state.displayHeight;
        var cropperCanvas = canvasAll.cropperCanvas;
        Taro.canvasToTempFilePath({
            canvas: cropperCanvas,
            x: props.space,
            y: (displayHeight - cropperWidth) / 2,
            width: cropperWidth,
            height: cropperWidth,
            destWidth: cropperWidth,
            destHeight: cropperWidth,
            success: function(res) {
                return _async_to_generator(function() {
                    var filePath;
                    return _ts_generator(this, function(_state) {
                        filePath = res.tempFilePath;
                        onConfirm && onConfirm(filePath);
                        cancel(false);
                        return [
                            2
                        ];
                    });
                })();
            }
        });
    };
    // 裁剪图片
    var confirm = function() {
        if (Taro.getEnv() === 'WEB') {
            confirmWEB();
            return;
        }
        if (showAlipayCanvas2D) {
            confirmALIPAY();
            return;
        }
        var cropperWidth = state.cropperWidth, displayHeight = state.displayHeight;
        var canvasId = canvasAll.canvasId;
        // 将编辑后的canvas内容转成图片
        Taro.canvasToTempFilePath({
            canvasId: canvasId,
            x: props.space,
            y: (displayHeight - cropperWidth) / 2,
            width: cropperWidth,
            height: cropperWidth,
            destWidth: cropperWidth * systemInfo.pixelRatio,
            destHeight: cropperWidth * systemInfo.pixelRatio,
            success: function(res) {
                return _async_to_generator(function() {
                    var filePath;
                    return _ts_generator(this, function(_state) {
                        filePath = res.tempFilePath;
                        onConfirm && onConfirm(filePath);
                        cancel(false);
                        return [
                            2
                        ];
                    });
                })();
            }
        });
    };
    var ToolBar = function() {
        var actions = [
            cancel,
            reset,
            rotate,
            confirm
        ];
        return /*#__PURE__*/ React.createElement(View, {
            className: "".concat(classPrefix, "-popup-toolbar-flex")
        }, actions.map(function(action, index) {
            return /*#__PURE__*/ React.createElement(View, {
                key: index,
                className: "".concat(classPrefix, "-popup-toolbar-item"),
                onClick: function(_e) {
                    return action();
                }
            }, toolbar[index]);
        }));
    };
    var CropperPopup = function() {
        var canvasId = canvasAll.canvasId;
        return /*#__PURE__*/ React.createElement(View, {
            className: "".concat(classPrefix, "-popup"),
            style: {
                display: visible ? 'block' : 'none'
            }
        }, /*#__PURE__*/ React.createElement(Canvas, {
            id: canvasId,
            "canvas-id": canvasId,
            type: showAlipayCanvas2D ? '2d' : undefined,
            style: canvasStyle,
            className: "".concat(classPrefix, "-popup-canvas")
        }), /*#__PURE__*/ React.createElement(View, {
            className: "".concat(classPrefix, "-popup-highlight"),
            onTouchStart: onTouchStart,
            onTouchMove: onTouchMove,
            onTouchEnd: onTouchEnd
        }, /*#__PURE__*/ React.createElement(View, {
            className: "highlight",
            style: highlightStyle
        })), /*#__PURE__*/ React.createElement(View, {
            className: toolbarPositionCls
        }, /*#__PURE__*/ React.createElement(ToolBar, null)));
    };
    return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(View, _object_spread_props(_object_spread({
        className: cls
    }, rest), {
        style: style
    }), children, /*#__PURE__*/ React.createElement(View, {
        className: "nut-avatar-cropper-edit-text",
        onClick: chooseImage
    }, editText)), CropperPopup());
};
AvatarCropper.displayName = 'NutAvatarCropper';
