"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "AvatarCropper", {
    enumerable: true,
    get: function() {
        return AvatarCropper;
    }
});
var _interop_require_default = require("@swc/helpers/_/_interop_require_default");
var _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
var _async_to_generator = require("@swc/helpers/_/_async_to_generator");
var _object_spread = require("@swc/helpers/_/_object_spread");
var _object_spread_props = require("@swc/helpers/_/_object_spread_props");
var _object_without_properties = require("@swc/helpers/_/_object_without_properties");
var _sliced_to_array = require("@swc/helpers/_/_sliced_to_array");
var _ts_generator = require("@swc/helpers/_/_ts_generator");
var _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
var _classnames = /*#__PURE__*/ _interop_require_default._(require("classnames"));
var _button = /*#__PURE__*/ _interop_require_default._(require("../button"));
var _typings = require("../../utils/typings");
var _usetouch = require("../../hooks/use-touch");
var _utils = require("../../utils");
var _useclientrect = require("../../hooks/use-client-rect");
var _configprovider = require("../configprovider");
var defaultProps = (0, _object_spread_props._)((0, _object_spread._)({}, _typings.ComponentDefaults), {
    maxZoom: 3,
    space: 10,
    toolbar: [
        /*#__PURE__*/ _react.default.createElement(_button.default, {
            type: "danger",
            key: "cancel"
        }, "Cancel"),
        /*#__PURE__*/ _react.default.createElement(_button.default, {
            key: "reset"
        }, "Reset"),
        /*#__PURE__*/ _react.default.createElement(_button.default, {
            key: "rotate"
        }, "Rotate"),
        /*#__PURE__*/ _react.default.createElement(_button.default, {
            type: "success",
            key: "confirm"
        }, "Confirm")
    ],
    toolbarPosition: 'bottom',
    editText: 'Edit',
    shape: 'square'
});
var classPrefix = "nut-avatar-cropper";
var AvatarCropper = function AvatarCropper(props) {
    var locale = (0, _configprovider.useConfig)().locale;
    defaultProps.toolbar = [
        /*#__PURE__*/ _react.default.createElement(_button.default, {
            type: "danger",
            key: "cancel"
        }, locale.cancel),
        /*#__PURE__*/ _react.default.createElement(_button.default, {
            key: "reset"
        }, locale.reset),
        /*#__PURE__*/ _react.default.createElement(_button.default, {
            key: "rotate"
        }, locale.avatarCropper.rotate),
        /*#__PURE__*/ _react.default.createElement(_button.default, {
            type: "success",
            key: "confirm"
        }, locale.confirm)
    ];
    var _ref = (0, _object_spread._)({}, defaultProps, props), children = _ref.children, maxZoom = _ref.maxZoom, space = _ref.space, toolbar = _ref.toolbar, toolbarPosition = _ref.toolbarPosition, editText = _ref.editText, shape = _ref.shape, className = _ref.className, style = _ref.style, onConfirm = _ref.onConfirm, onCancel = _ref.onCancel, rest = (0, _object_without_properties._)(_ref, [
        "children",
        "maxZoom",
        "space",
        "toolbar",
        "toolbarPosition",
        "editText",
        "shape",
        "className",
        "style",
        "onConfirm",
        "onCancel"
    ]);
    var cls = (0, _classnames.default)(classPrefix, className, shape === 'round' && 'round');
    var toolbarPositionCls = (0, _classnames.default)("".concat(classPrefix, "-popup-toolbar"), toolbarPosition);
    var inputImageRef = (0, _react.useRef)(null);
    var cropperPopupRef = (0, _react.useRef)(null);
    var canvasRef = (0, _react.useRef)(null);
    var _useState = (0, _sliced_to_array._)((0, _react.useState)(false), 2), visible = _useState[0], setVisible = _useState[1];
    var _useState1 = (0, _sliced_to_array._)((0, _react.useState)(false), 2), moving = _useState1[0], setMoving = _useState1[1];
    var _useState2 = (0, _sliced_to_array._)((0, _react.useState)(false), 2), zooming = _useState2[0], setZooming = _useState2[1];
    var _useState3 = (0, _sliced_to_array._)((0, _react.useState)({
        defScale: 1,
        scale: 1,
        angle: 0,
        moveX: 0,
        moveY: 0,
        displayWidth: 0,
        displayHeight: 0
    }), 2), state = _useState3[0], setState = _useState3[1];
    var defDrawImage = {
        img: new Image(),
        sx: 0,
        sy: 0,
        swidth: 0,
        sheight: 0,
        x: 0,
        y: 0,
        width: 0,
        height: 0
    };
    var _useState4 = (0, _sliced_to_array._)((0, _react.useState)((0, _object_spread._)({}, defDrawImage)), 2), drawImage = _useState4[0], setDrawImg = _useState4[1];
    var devicePixelRatio = window.devicePixelRatio || 1;
    var touch = (0, _usetouch.useTouch)();
    var highlightStyle = (0, _react.useMemo)(function() {
        var width = "".concat(drawImage.swidth / devicePixelRatio, "px");
        var height = width;
        return {
            width: width,
            height: height,
            borderRadius: shape === 'round' ? '50%' : ''
        };
    }, [
        devicePixelRatio,
        drawImage.swidth
    ]);
    // 是否是横向
    var isAngle = (0, _react.useMemo)(function() {
        return state.angle === 90 || state.angle === 270;
    }, [
        state.angle
    ]);
    // 最大横向移动距离
    var maxMoveX = (0, _react.useMemo)(function() {
        var swidth = drawImage.swidth, height = drawImage.height;
        if (isAngle) {
            return Math.max(0, (height * state.scale - swidth) / 2);
        }
        return Math.max(0, (state.displayWidth * state.scale - swidth) / 2);
    }, [
        state.scale,
        state.displayWidth,
        drawImage,
        isAngle
    ]);
    // 最大纵向移动距离
    var maxMoveY = (0, _react.useMemo)(function() {
        var swidth = drawImage.swidth, height = drawImage.height;
        if (isAngle) {
            return Math.max(0, (state.displayWidth * state.scale - swidth) / 2);
        }
        return Math.max(0, (height * state.scale - swidth) / 2);
    }, [
        state.scale,
        state.displayWidth,
        drawImage,
        isAngle
    ]);
    // 文件转base64
    var fileToDataURL = function fileToDataURL(file) {
        return new Promise(function(resolve) {
            var reader = new FileReader();
            reader.onloadend = function(e) {
                return resolve(e.target.result);
            };
            reader.readAsDataURL(file);
        });
    };
    // base64转图片
    var dataURLToImage = function dataURLToImage(dataURL) {
        return new Promise(function(resolve) {
            var img = new Image();
            img.onload = function() {
                return resolve(img);
            };
            img.src = dataURL;
        });
    };
    // 绘制
    var draw = (0, _react.useCallback)(function() {
        var img = drawImage.img, width = drawImage.width, height = drawImage.height, x = drawImage.x, y = drawImage.y, swidth = drawImage.swidth;
        var moveX = state.moveX, moveY = state.moveY, scale = state.scale, angle = state.angle, displayWidth = state.displayWidth, displayHeight = state.displayHeight;
        var canvas = canvasRef.current;
        if (!canvas) return;
        var ctx = canvas.getContext('2d');
        canvas.width = displayWidth;
        canvas.height = displayHeight;
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = '#666';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = '#000';
        ctx.fillRect(space * devicePixelRatio, (canvas.height - swidth) / 2, swidth, swidth);
        ctx.translate(canvas.width / 2 + moveX, canvas.height / 2 + moveY);
        ctx.rotate(Math.PI / 180 * angle);
        ctx.scale(scale, scale);
        ctx.drawImage(img, x, y, width, height);
    }, [
        drawImage,
        state,
        devicePixelRatio,
        space
    ]);
    (0, _react.useEffect)(function() {
        if (Math.abs(state.moveX) > maxMoveX) {
            setState((0, _object_spread_props._)((0, _object_spread._)({}, state), {
                moveX: maxMoveX
            }));
        }
        if (Math.abs(state.moveY) > maxMoveY) {
            setState((0, _object_spread_props._)((0, _object_spread._)({}, state), {
                moveY: maxMoveY
            }));
        }
        draw();
    }, [
        state,
        maxMoveX,
        maxMoveY,
        draw
    ]);
    // 设置绘制图片
    var setDrawImgs = function setDrawImgs(image) {
        var rect = (0, _useclientrect.getRect)(cropperPopupRef.current);
        if (!rect) return;
        var clientWidth = rect.width, clientHeight = rect.height;
        var canvasWidth = state.displayWidth = clientWidth * devicePixelRatio;
        var canvasHeight = state.displayHeight = clientHeight * devicePixelRatio;
        var copyDrawImg = (0, _object_spread._)({}, defDrawImage);
        var imgWidth = image.width, imgHeight = image.height;
        copyDrawImg.img = image;
        var isPortrait = imgHeight > imgWidth;
        var rate = isPortrait ? imgWidth / imgHeight : imgHeight / imgWidth;
        copyDrawImg.width = canvasWidth;
        copyDrawImg.height = isPortrait ? canvasWidth / rate : canvasWidth * rate;
        copyDrawImg.x = -copyDrawImg.width / 2;
        copyDrawImg.y = -copyDrawImg.height / 2;
        copyDrawImg.swidth = canvasWidth - space * 2 * devicePixelRatio;
        copyDrawImg.sheight = isPortrait ? copyDrawImg.swidth / rate : copyDrawImg.swidth * rate;
        copyDrawImg.sx = space * devicePixelRatio;
        copyDrawImg.sy = (canvasHeight - copyDrawImg.swidth) / 2;
        setDrawImg(copyDrawImg);
        var scale = copyDrawImg.swidth / (isPortrait ? copyDrawImg.width : copyDrawImg.height);
        setState((0, _object_spread_props._)((0, _object_spread._)({}, state), {
            defScale: scale
        }));
        resetScale(scale);
    };
    var inputImageChange = /*#__PURE__*/ function() {
        var _ref = (0, _async_to_generator._)(function(event) {
            var $el, files, base64, image;
            return (0, _ts_generator._)(this, function(_state) {
                switch(_state.label){
                    case 0:
                        setVisible(true);
                        $el = event.target;
                        files = $el.files;
                        if (!(files === null || files === void 0 ? void 0 : files.length)) return [
                            2
                        ];
                        return [
                            4,
                            fileToDataURL(files[0])
                        ];
                    case 1:
                        base64 = _state.sent();
                        return [
                            4,
                            dataURLToImage(base64)
                        ];
                    case 2:
                        image = _state.sent();
                        setDrawImgs(image);
                        return [
                            2
                        ];
                }
            });
        });
        return function inputImageChange(event) {
            return _ref.apply(this, arguments);
        };
    }();
    var resetScale = function resetScale(scale) {
        setState((0, _object_spread_props._)((0, _object_spread._)({}, state), {
            moveX: 0,
            moveY: 0,
            angle: 0,
            scale: scale || state.defScale,
            defScale: scale || state.defScale
        }));
    };
    var setScale = function setScale(scale) {
        scale = (0, _utils.clamp)(scale, +0.3, +maxZoom + 1);
        if (scale !== state.scale) {
            setState((0, _object_spread_props._)((0, _object_spread._)({}, state), {
                scale: scale
            }));
        }
    };
    // 计算两个点的距离
    var getDistance = function getDistance(touches) {
        return Math.sqrt(Math.pow(touches[0].clientX - touches[1].clientX, 2) + Math.pow(touches[0].clientY - touches[1].clientY, 2));
    };
    var _useState5 = (0, _sliced_to_array._)((0, _react.useState)({
        startMoveX: 0,
        startMoveY: 0,
        startScale: 0,
        startDistance: 0
    }), 2), startMove = _useState5[0], setStartMove = _useState5[1];
    var startMoveX = startMove.startMoveX, startMoveY = startMove.startMoveY, startScale = startMove.startScale, startDistance = startMove.startDistance;
    var onTouchStart = function onTouchStart(event) {
        var touches = event.touches;
        var offsetX = touch.offsetX;
        touch.start(event);
        var fingerNum = touches === null || touches === void 0 ? void 0 : touches.length;
        setStartMove((0, _object_spread_props._)((0, _object_spread._)({}, startMove), {
            startMoveX: state.moveX,
            startMoveY: state.moveY
        }));
        setMoving(fingerNum === 1);
        setZooming(fingerNum === 2 && !offsetX.current);
        if (fingerNum === 2 && !offsetX.current) {
            setStartMove((0, _object_spread_props._)((0, _object_spread._)({}, startMove), {
                startScale: state.scale,
                startDistance: getDistance(event.touches)
            }));
        }
    };
    var onTouchMove = function onTouchMove(event) {
        var touches = event.touches;
        touch.move(event);
        if (moving || zooming) {
            (0, _utils.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((0, _object_spread_props._)((0, _object_spread._)({}, state), {
                moveX: (0, _utils.clamp)(moveX, -maxMoveX, maxMoveX),
                moveY: (0, _utils.clamp)(moveY, -maxMoveY, maxMoveY)
            }));
        }
        if (zooming && touches.length === 2) {
            var distance = getDistance(touches);
            var scale = startScale * distance / startDistance;
            setScale(scale);
        }
    };
    var onTouchEnd = function onTouchEnd(event) {
        var stopPropagation = false;
        if (moving || zooming) {
            stopPropagation = !(moving && startMoveX === state.moveX && startMoveY === state.moveY);
            if (!event.touches.length) {
                if (zooming) {
                    setState((0, _object_spread_props._)((0, _object_spread._)({}, state), {
                        moveX: (0, _utils.clamp)(state.moveX, -maxMoveX, maxMoveX),
                        moveY: (0, _utils.clamp)(state.moveY, -maxMoveY, maxMoveY)
                    }));
                    setZooming(false);
                }
                setMoving(false);
                setStartMove((0, _object_spread_props._)((0, _object_spread._)({}, startMove), {
                    startMoveX: 0,
                    startMoveY: 0,
                    startScale: state.defScale
                }));
                if (state.scale < state.defScale) {
                    resetScale();
                }
                if (state.scale > maxZoom) {
                    setState((0, _object_spread_props._)((0, _object_spread._)({}, state), {
                        scale: +maxZoom
                    }));
                }
            }
        }
        (0, _utils.preventDefault)(event, stopPropagation);
        touch.reset();
    };
    var reset = function reset() {
        setState((0, _object_spread_props._)((0, _object_spread._)({}, state), {
            angle: 0
        }));
    };
    var rotate = function rotate() {
        if (state.angle === 270) {
            setState((0, _object_spread_props._)((0, _object_spread._)({}, state), {
                angle: 0
            }));
            return;
        }
        setState((0, _object_spread_props._)((0, _object_spread._)({}, state), {
            angle: state.angle + 90
        }));
    };
    var cancel = function cancel() {
        var isEmit = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : true;
        setVisible(false);
        resetScale();
        inputImageRef.current && (inputImageRef.current.value = '');
        isEmit && onCancel && onCancel();
    };
    // 裁剪图片
    var confirm = function confirm() {
        var canvas = canvasRef.current;
        var sx = drawImage.sx, sy = drawImage.sy, swidth = drawImage.swidth;
        var width = swidth;
        var height = swidth;
        // 创建一个新的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, sx, sy, width, height, 0, 0, width, height);
        // 将裁剪后的内容转换为图片格式
        var imageDataURL = croppedCanvas.toDataURL('image/png');
        onConfirm && onConfirm(imageDataURL);
        cancel(false);
    };
    var ToolBar = function ToolBar() {
        var actions = [
            cancel,
            reset,
            rotate,
            confirm
        ];
        return /*#__PURE__*/ _react.default.createElement("div", {
            className: "".concat(classPrefix, "-popup-toolbar-flex")
        }, actions.map(function(action, index) {
            return /*#__PURE__*/ _react.default.createElement("div", {
                key: index,
                className: "".concat(classPrefix, "-popup-toolbar-item"),
                onClick: function onClick(_e) {
                    return action();
                }
            }, toolbar[index]);
        }));
    };
    var CropperPopup = function CropperPopup() {
        return /*#__PURE__*/ _react.default.createElement("div", {
            ref: cropperPopupRef,
            className: "".concat(classPrefix, "-popup"),
            style: {
                display: visible ? 'block' : 'none'
            }
        }, /*#__PURE__*/ _react.default.createElement("canvas", {
            ref: canvasRef,
            className: "".concat(classPrefix, "-popup-canvas")
        }), /*#__PURE__*/ _react.default.createElement("div", {
            className: "".concat(classPrefix, "-popup-highlight"),
            onTouchStart: onTouchStart,
            onTouchMove: onTouchMove,
            onTouchEnd: onTouchEnd
        }, /*#__PURE__*/ _react.default.createElement("div", {
            className: "highlight",
            style: highlightStyle
        })), /*#__PURE__*/ _react.default.createElement("div", {
            className: toolbarPositionCls
        }, /*#__PURE__*/ _react.default.createElement(ToolBar, null)));
    };
    return /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/ _react.default.createElement("div", (0, _object_spread_props._)((0, _object_spread._)({
        className: cls
    }, rest), {
        style: style
    }), children, /*#__PURE__*/ _react.default.createElement("input", {
        ref: inputImageRef,
        type: "file",
        accept: "image/*",
        className: "".concat(classPrefix, "-input"),
        onChange: function onChange(e) {
            return inputImageChange(e);
        },
        "aria-label": locale.avatarCropper.selectImage
    }), /*#__PURE__*/ _react.default.createElement("div", {
        className: "nut-avatar-cropper-edit-text"
    }, editText)), CropperPopup());
};
AvatarCropper.displayName = 'NutAvatarCropper';
