<template>
    <div class="cut-avatar-page" v-if="tempFilePath">
        <div class="main-content" v-if="1==2">
            <div class="preview-section">
                <div v-if="resultPath" class="result-box">
                    <image :src="resultPath" mode="widthFix" class="result-image" @click="previewResult"></image>
                    <div class="action-row">
                        <button class="btn btn-outline" @click="reSelect">重新选择</button>
                        <button class="btn btn-primary" @click="uploadImage">确认上传</button>
                    </div>
                    <text class="tip-text">点击图片可预览大图</text>
                </div>

                <div v-else class="upload-box" @click="onSelect">
                    <div class="placeholder-icon">+</div>
                    <text class="upload-text">点击上传图片</text>
                    <text class="upload-sub-text">支持 JPG/PNG，自动裁剪 1:1</text>
                </div>
            </div>
        </div>

        <div v-if="isShowEditor" class="editor-modal" :class="{ 'dark-mode': isDarkMode }">
            <div class="cropper-wrapper">
                <movable-area class="crop-area" :style="{ height: screenHeight + 'px' }">
                    <movable-view
                        class="crop-view"
                        direction="all"
                        :out-of-bounds="true"
                        :x="imgX"
                        :y="imgY"
                        :scale="scale+''"
                        :scale-min="0.5"
                        :scale-max="4"
                        :animation="false"
                        @change="onMoveChange"
                        @scale="onScaleChange"
                        :style="{ width: imgDisplayWidth + 'px', height: imgDisplayHeight + 'px' }"
                    >
                        <image :src="tempFilePath" class="target-image" :style="{ transform: 'rotate(' + rotation + 'deg)' }"></image>
                    </movable-view>
                </movable-area>

                <div class="mask-layer" :style="{ height: screenHeight + 'px' }">
                    <div class="mask-top" :style="{ height: (screenHeight - cropSize) / 2 + 'px' }"></div>
                    <div class="mask-middle" :style="{ height: cropSize + 'px' }">
                        <div class="mask-left" :style="{ width: (screenWidth - cropSize) / 2 + 'px' }"></div>
                        <div class="crop-box" :style="{ width: cropSize + 'px', height: cropSize + 'px' }">
                            <div class="corner c-tl"></div>
                            <div class="corner c-tr"></div>
                            <div class="corner c-bl"></div>
                            <div class="corner c-br"></div>
                        </div>
                        <div class="mask-right" :style="{ width: (screenWidth - cropSize) / 2 + 'px' }"></div>
                    </div>
                    <div class="mask-bottom" :style="{ height: (screenHeight - cropSize) / 2 + 'px' }"></div>
                </div>
            </div>

            <div class="editor-toolbar">
                <div class="tool-btn" @click="onCancel">取消</div>
                <div class="tool-btn" @click="onReset"> <text class="icon-reset">↻</text> 重置 </div>
                <div class="tool-btn" @click="onRotate"> <text class="icon-rotate">↻</text> 旋转 </div>
                <div class="tool-btn btn-confirm" @click="onConfirm">确定</div>
            </div>

            <canvas canvas-id="cropCanvas" class="crop-canvas" :style="{ width: cropSize + 'px', height: cropSize + 'px' }"></canvas>
        </div>
    </div>
</template>

<script>
    /**
     * 核心逻辑说明：
     * 1. 使用 movable-view 实现用户手势交互（拖拽、缩放）。
     * 2. 使用 image 的 css transform 实现视觉上的旋转。
     * 3. 最终生成时，通过计算偏移量，使用 CanvasContext 绘制图像。
     * 4. 旋转后的 Canvas 绘图坐标系需要特殊处理 (translate + rotate)。
     */
    export default {
        data() {
            return {
                // --- 系统/环境参数 ---
                screenWidth: 375,
                screenHeight: 600,
                isDarkMode: false,

                // --- 业务数据 ---
                resultPath: '', // 最终生成的图片路径

                // --- 编辑器状态 ---
                isShowEditor: false,
                tempFilePath: '', // 选中的原始图片路径

                // --- 图片原始信息 ---
                realImgWidth: 0,
                realImgHeight: 0,

                // --- 交互状态数据 ---
                cropSize: 280, // 裁剪框大小 (正方形)
                imgDisplayWidth: 0, // 图片在屏幕上的初始显示宽度
                imgDisplayHeight: 0, // 图片在屏幕上的初始显示高度

                // movable-view 的属性
                imgX: 0,
                imgY: 0,
                scale: 1,
                rotation: 0, // 0, 90, 180, 270

                // 记录移动过程中的临时数据 (用于计算)
                currentX: 0,
                currentY: 0,
                currentScale: 1,
            };
        },
        created() {
            this.initSystemInfo();
        },
        methods: {
            // -----------------------------------------------------------
            // 初始化与系统适配
            // -----------------------------------------------------------
            initSystemInfo() {
                const sys = uni.getSystemInfoSync();
                this.screenWidth = sys.windowWidth;
                this.screenHeight = sys.windowHeight;

                // 适配暗黑模式
                if (sys.theme === 'dark') {
                    this.isDarkMode = true;
                }

                // 动态计算裁剪框大小 (屏幕宽度的 80%，最大 400px 用于适配 Pad)
                let size = this.screenWidth * 0.8;
                if (size > 400) size = 400;
                this.cropSize = Math.floor(size);
            },

            // -----------------------------------------------------------
            // 交互逻辑
            // -----------------------------------------------------------
            onSelect() {
                console.log('[Debug] 点击选择图片');
                uni.chooseImage({
                    count: 1,
                    sizeType: ['original', 'compressed'],
                    sourceType: ['album', 'camera'],
                    success: (res) => {
                        const src = res.tempFilePaths[0];
                        this.enterEditor(src);
                    },
                    fail: (err) => {
                        console.error('[Error] 选择图片失败', err);
                    },
                });
            },

            reSelect() {
                this.onSelect();
            },

            previewResult() {
                if (this.resultPath) {
                    uni.previewImage({
                        urls: [this.resultPath],
                    });
                }
            },

            uploadImage() {
                console.log('[Debug] 触发上传逻辑, 路径:', this.resultPath);
                // 这里预留上传 API 调用
                uni.showLoading({ title: '正在上传...' });
                setTimeout(() => {
                    uni.hideLoading();
                    uni.showToast({ title: '模拟上传成功', icon: 'success' });
                }, 1000);
            },

            // -----------------------------------------------------------
            // 编辑器逻辑
            // -----------------------------------------------------------

            // 进入编辑模式，初始化图片位置
            enterEditor(src) {
                uni.showLoading({ title: '加载中...' });

                uni.getImageInfo({
                    src: src,
                    success: (res) => {
                        this.tempFilePath = src;
                        this.realImgWidth = res.width;
                        this.realImgHeight = res.height;

                        // 重置状态
                        this.rotation = 0;
                        this.scale = 1;
                        this.currentScale = 1;

                        // 计算图片初始显示尺寸（使其适应屏幕宽度，类似 width: 100%）
                        // 这里我们让图片的短边至少填满裁剪框，方便用户操作
                        const ratio = this.realImgWidth / this.realImgHeight;

                        if (ratio > 1) {
                            // 横图：高度定为裁剪框大小 + 一点冗余，宽度自适应
                            this.imgDisplayHeight = this.cropSize;
                            this.imgDisplayWidth = this.imgDisplayHeight * ratio;
                        } else {
                            // 竖图
                            this.imgDisplayWidth = this.cropSize;
                            this.imgDisplayHeight = this.imgDisplayWidth / ratio;
                        }

                        // 居中计算
                        // 屏幕中心
                        const centerX = this.screenWidth / 2;
                        const centerY = this.screenHeight / 2;

                        // 计算 movable-view 的初始 x, y 使其居中
                        // movable-view 的 x,y 是相对于 movable-area (全屏) 的左上角
                        this.imgX = centerX - this.imgDisplayWidth / 2;
                        this.imgY = centerY - this.imgDisplayHeight / 2;

                        // 同步 current 值
                        this.currentX = this.imgX;
                        this.currentY = this.imgY;

                        this.isShowEditor = true;
                        uni.hideLoading();
                    },
                    fail: () => {
                        uni.hideLoading();
                        uni.showToast({ title: '图片加载失败', icon: 'none' });
                    },
                });
            },

            onMoveChange(e) {
                // 记录移动位置，用于最终裁剪计算
                // detail: {x, y, source}
                this.currentX = e.detail.x;
                this.currentY = e.detail.y;
            },
            onReset(){
                this.rotation = 0;
                this.currentScale = 1;
            },
            onScaleChange(e) {
                // detail: {scale}
                this.currentScale = e.detail.scale;
            },

            onRotate() {
                console.log('[Debug] 点击旋转');
                // 顺时针旋转 90 度
                this.rotation = (this.rotation + 90) % 360;
                // 旋转后，可能需要重置一下缩放或位置逻辑？
                // 本方案中，为了简化体验，仅做视觉旋转，
                // 最终 Canvas 裁剪时根据 rotation 参数处理坐标系。
            },

            onCancel() {
                this.isShowEditor = false;
                this.tempFilePath = '';
            },

            // -----------------------------------------------------------
            // 核心裁剪生成逻辑 (Canvas)
            // -----------------------------------------------------------
            // -----------------------------------------------------------
            onConfirm() {
                console.log('[Debug] 开始生成图片');
                uni.showLoading({ title: '处理中...' });

                const ctx = uni.createCanvasContext('cropCanvas', this);

                // 1. 基础参数
                const destSize = this.cropSize; // 画布大小 (正方形)
                const halfDest = destSize / 2;

                // 清空画布
                ctx.setFillStyle('#FFFFFF');
                ctx.fillRect(0, 0, destSize, destSize);

                // 2. 计算【屏幕坐标系】下的中心点偏移
                // 这里的逻辑是：找出"图片中心"相对于"裁剪框中心"在屏幕上的距离

                // A. 裁剪框中心在屏幕上的坐标
                const cropCenterX = (this.screenWidth - this.cropSize) / 2 + this.cropSize / 2;
                const cropCenterY = (this.screenHeight - this.cropSize) / 2 + this.cropSize / 2;

                // B. 图片中心在屏幕上的坐标
                // 注意：movable-view 的 x,y 是左上角坐标，且 movable-view 的缩放是以中心为原点的
                // 实际上 uni-app 的 movable-view 在缩放/移动后，x/y 会自动更新为当前的左上角位置
                // 所以图片中心 = 当前x + (显示宽度 * 缩放 / 2)
                const currentRealWidth = this.imgDisplayWidth * this.currentScale;
                const currentRealHeight = this.imgDisplayHeight * this.currentScale;

                const imgCenterX = this.currentX + currentRealWidth / 2;
                const imgCenterY = this.currentY + currentRealHeight / 2;

                // C. 算出屏幕偏移向量 (Screen Diff)
                // 含义：图片中心在裁剪框中心的 右侧 diffX 像素，下方 diffY 像素
                const diffX = imgCenterX - cropCenterX;
                const diffY = imgCenterY - cropCenterY;

                // 3. 将屏幕偏移向量【映射】到旋转后的 Canvas 坐标系
                // 我们需要算出：在旋转后的坐标系里，图片中心应该在哪里 (drawX, drawY)
                let drawX = 0;
                let drawY = 0;

                // 规范化旋转角度 (0, 90, 180, 270)
                const angle = this.rotation % 360;

                // 坐标系映射逻辑：
                // 屏幕 X+ (向右)，屏幕 Y+ (向下)
                // 假设 Canvas 原点已移至中心并旋转：
                switch (angle) {
                    case 0:
                        // 0度：坐标系一致
                        drawX = diffX;
                        drawY = diffY;
                        break;
                    case 90:
                        // 90度 (顺时针)：Canvas X轴指向屏幕下，Canvas Y轴指向屏幕左
                        // 屏幕的 X+ (向右) 对应 Canvas 的 Y- (向左的相反) -> drawY = -diffX
                        // 屏幕的 Y+ (向下) 对应 Canvas 的 X+ (向下)       -> drawX = diffY
                        drawX = diffY;
                        drawY = -diffX;
                        break;
                    case 180:
                        // 180度：Canvas X轴向左，Canvas Y轴向上 (完全相反)
                        drawX = -diffX;
                        drawY = -diffY;
                        break;
                    case 270: // 相当于 -90度
                        // 270度：Canvas X轴向上，Canvas Y轴向右
                        // 屏幕 X+ (向右) 对应 Canvas Y+ -> drawY = diffX
                        // 屏幕 Y+ (向下) 对应 Canvas X- -> drawX = -diffY
                        drawX = -diffY;
                        drawY = diffX;
                        break;
                }

                // 4. 执行绘制
                ctx.save();

                // a. 将原点移到画布中心
                ctx.translate(halfDest, halfDest);
                // b. 旋转坐标系
                ctx.rotate((angle * Math.PI) / 180);

                // c. 绘制图片
                // drawImage 的 x,y 是图片的左上角坐标
                // 我们算出的 drawX, drawY 是图片中心相对于画布中心的坐标
                // 所以要减去宽高的一半
                ctx.drawImage(this.tempFilePath, drawX - currentRealWidth / 2, drawY - currentRealHeight / 2, currentRealWidth, currentRealHeight);

                ctx.restore();

                // 5. 导出图片
                ctx.draw(false, () => {
                    setTimeout(() => {
                        uni.canvasToTempFilePath(
                            {
                                canvasId: 'cropCanvas',
                                width: destSize,
                                height: destSize,
                                fileType: 'jpg',
                                quality: 1,
                                success: (res) => {
                                    this.resultPath = res.tempFilePath;
                                    this.tempFilePath = "";
                                    this.isShowEditor = false;
                                    uni.hideLoading();
                                    this.$emit('save', {path:this.resultPath});
                                },
                                fail: () => {
                                    uni.hideLoading();
                                    uni.showToast({ title: '生成失败', icon: 'none' });
                                },
                            },
                            this,
                        );
                    }, 200);
                });
            },
        },
    };
</script>

<style scoped>
    /* ========================
   CSS 变量定义
   ======================== */
	.cut-avatar-page {
        --primary-color: #ef3912;
        --bg-color: #f8f9fa;
        --text-color: #333333;
        --modal-bg: #000000;

        min-height: 100vh;
        background-color: var(--bg-color);
        display: flex;
        flex-direction: column;
    }

    /* 适配暗黑模式 */
    @media (prefers-color-scheme: dark) {
        .page-container {
            --bg-color: #1a1a1a;
            --text-color: #ffffff;
        }
    }

    /* ========================
   主界面样式
   ======================== */
    .nav-bar {
        height: 44px;
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: var(--bg-color);
        /* 简单的顶部阴影 */
        box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05);
    }

    .nav-title {
        font-size: 16px;
        font-weight: bold;
        color: var(--text-color);
    }

    .main-content {
        flex: 1;
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 20px;
    }

    .preview-section {
        width: 100%;
        max-width: 600px; /* Pad 适配限制 */
        display: flex;
        flex-direction: column;
        align-items: center;
        margin-top: 40px;
    }

    /* 上传占位框 */
    .upload-box {
        width: 100%;
        height: 200px;
        border: 2px dashed #cccccc;
        border-radius: 12px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        background-color: rgba(0, 0, 0, 0.02);
        transition: all 0.3s;
    }

    .upload-box:active {
        background-color: rgba(239, 57, 18, 0.05);
        border-color: var(--primary-color);
    }

    .placeholder-icon {
        font-size: 40px;
        color: #999;
        margin-bottom: 10px;
    }

    .upload-text {
        font-size: 16px;
        color: var(--text-color);
        font-weight: bold;
    }

    .upload-sub-text {
        font-size: 12px;
        color: #999;
        margin-top: 5px;
    }

    /* 结果展示区 */
    .result-box {
        width: 100%;
        display: flex;
        flex-direction: column;
        align-items: center;
    }

    .result-image {
        width: 200px;
        height: 200px;
        border-radius: 8px;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
        background-color: #eee;
        margin-bottom: 20px;
    }

    .action-row {
        display: flex;
        flex-direction: row;
        justify-content: center;
        gap: 15px;
        width: 100%;
    }

    .btn {
        font-size: 14px;
        padding: 8px 24px;
        border-radius: 20px;
        border: none;
    }

    .btn-primary {
        background-color: var(--primary-color);
        color: #fff;
    }

    .btn-outline {
        background-color: transparent;
        border: 1px solid #ccc;
        color: var(--text-color);
    }

    .tip-text {
        font-size: 12px;
        color: #999;
        margin-top: 15px;
    }

    /* ========================
   编辑器弹窗样式 (全屏)
   ======================== */
    .editor-modal {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 999;
        background-color: #000;
        display: flex;
        flex-direction: column;
    }

    .cropper-wrapper {
        flex: 1;
        position: relative;
        overflow: hidden;
    }

    .crop-area {
        width: 100%;
        /* height 由 JS 动态控制 */
    }

    .crop-view {
        /* 初始不可见，加载图片后显示 */
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .target-image {
        width: 100%;
        height: 100%;
        /* 优化图片渲染 */
        will-change: transform;
    }

    /* 遮罩层布局 */
    .mask-layer {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        pointer-events: none; /* 让事件穿透到底下的 movable-area */
        display: flex;
        flex-direction: column;
        z-index: 10;
    }

    .mask-top,
    .mask-bottom,
    .mask-left,
    .mask-right {
        background-color: rgba(0, 0, 0, 0.6);
    }

    .mask-middle {
        display: flex;
        flex-direction: row;
    }

    /* 裁剪框样式 */
    .crop-box {
        position: relative;
        border: 1px solid rgba(255, 255, 255, 0.5);
        box-sizing: border-box;
    }

    /* 四个角的装饰 */
    .corner {
        position: absolute;
        width: 15px;
        height: 15px;
        border: 3px solid #fff;
    }

    .c-tl {
        top: -2px;
        left: -2px;
        border-right: none;
        border-bottom: none;
    }
    .c-tr {
        top: -2px;
        right: -2px;
        border-left: none;
        border-bottom: none;
    }
    .c-bl {
        bottom: -2px;
        left: -2px;
        border-right: none;
        border-top: none;
    }
    .c-br {
        bottom: -2px;
        right: -2px;
        border-left: none;
        border-top: none;
    }

    /* 底部工具栏 */
    .editor-toolbar {
        height: 80px; /* 留足安全距离 */
        background-color: #1a1a1a;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0 30px;
        padding-bottom: constant(safe-area-inset-bottom);
        padding-bottom: env(safe-area-inset-bottom);
    }

    .tool-btn {
        color: #fff;
        font-size: 16px;
        padding: 10px;
    }

    .btn-confirm {
        color: var(--primary-color);
        font-weight: bold;
    }

    .icon-rotate {
        font-size: 18px;
        margin-right: 4px;
    }

    /* Canvas 隐藏处理 */
    .crop-canvas {
        position: absolute;
        left: -9999px;
        top: -9999px;
        pointer-events: none;
        visibility: hidden; /* 这里用 hidden, 有些环境 display:none 会导致不渲染 */
        opacity: 0;
    }
</style>
