/**
 * 會員頭像：選檔後方形裁切（拖曳平移、滑桿縮放），輸出至 #avatar_crop hidden。
 */
(function () {
    'use strict';

    var fileInput = document.getElementById('avatar');
    var panel = document.getElementById('avatar-crop-panel');
    var canvas = document.getElementById('avatar-crop-canvas');
    var hidden = document.getElementById('avatar_crop');
    var zoomInput = document.getElementById('avatar-crop-zoom');
    var btnApply = document.getElementById('avatar-crop-apply');
    var btnCancel = document.getElementById('avatar-crop-cancel');
    var preview = document.getElementById('avatar-crop-preview');

    if (!fileInput || !panel || !canvas || !hidden) {
        return;
    }

    var VIEW = 280;
    var EXPORT = 512;
    var MIN_ZOOM = 1;
    var MAX_ZOOM = 3;

    var state = {
        img: null,
        objectUrl: null,
        zoom: 1,
        panX: 0,
        panY: 0,
        dragging: false,
        lastX: 0,
        lastY: 0
    };

    canvas.width = VIEW;
    canvas.height = VIEW;

    function clearObjectUrl() {
        if (state.objectUrl) {
            URL.revokeObjectURL(state.objectUrl);
            state.objectUrl = null;
        }
    }

    function resetState() {
        clearObjectUrl();
        state.img = null;
        state.zoom = 1;
        state.panX = 0;
        state.panY = 0;
        if (zoomInput) {
            zoomInput.value = '1';
            zoomInput.min = String(MIN_ZOOM);
            zoomInput.max = String(MAX_ZOOM);
            zoomInput.step = '0.02';
        }
        hidden.value = '';
        panel.hidden = true;
        if (preview) {
            preview.hidden = true;
        }
    }

    function baseScale() {
        if (!state.img) {
            return 1;
        }
        return Math.max(VIEW / state.img.width, VIEW / state.img.height);
    }

    function draw() {
        var ctx = canvas.getContext('2d');
        if (!ctx || !state.img) {
            return;
        }
        ctx.clearRect(0, 0, VIEW, VIEW);
        var s = baseScale() * state.zoom;
        var dw = state.img.width * s;
        var dh = state.img.height * s;
        var x = (VIEW - dw) / 2 + state.panX;
        var y = (VIEW - dh) / 2 + state.panY;
        ctx.drawImage(state.img, x, y, dw, dh);

        ctx.save();
        ctx.fillStyle = 'rgba(0,0,0,0.45)';
        ctx.beginPath();
        ctx.rect(0, 0, VIEW, VIEW);
        ctx.arc(VIEW / 2, VIEW / 2, VIEW / 2, 0, Math.PI * 2);
        ctx.fill('evenodd');
        ctx.restore();

        ctx.strokeStyle = 'rgba(255,255,255,0.85)';
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.arc(VIEW / 2, VIEW / 2, VIEW / 2 - 1, 0, Math.PI * 2);
        ctx.stroke();
    }

    function exportCrop() {
        if (!state.img) {
            return '';
        }
        var out = document.createElement('canvas');
        out.width = EXPORT;
        out.height = EXPORT;
        var ctx = out.getContext('2d');
        if (!ctx) {
            return '';
        }
        var ratio = EXPORT / VIEW;
        var s = baseScale() * state.zoom * ratio;
        var dw = state.img.width * s;
        var dh = state.img.height * s;
        var x = (EXPORT - dw) / 2 + state.panX * ratio;
        var y = (EXPORT - dh) / 2 + state.panY * ratio;
        ctx.fillStyle = '#13161d';
        ctx.fillRect(0, 0, EXPORT, EXPORT);
        ctx.drawImage(state.img, x, y, dw, dh);
        try {
            return out.toDataURL('image/jpeg', 0.88);
        } catch (e) {
            return '';
        }
    }

    function clampPan() {
        if (!state.img) {
            return;
        }
        var s = baseScale() * state.zoom;
        var dw = state.img.width * s;
        var dh = state.img.height * s;
        var maxX = Math.max(0, (dw - VIEW) / 2);
        var maxY = Math.max(0, (dh - VIEW) / 2);
        if (state.panX > maxX) {
            state.panX = maxX;
        }
        if (state.panX < -maxX) {
            state.panX = -maxX;
        }
        if (state.panY > maxY) {
            state.panY = maxY;
        }
        if (state.panY < -maxY) {
            state.panY = -maxY;
        }
    }

    fileInput.addEventListener('change', function () {
        var file = fileInput.files && fileInput.files[0];
        resetState();
        fileInput.value = '';
        if (!file) {
            return;
        }
        if (!/^image\/(jpeg|png|webp|gif)$/i.test(file.type)) {
            window.alert('請選擇 JPEG、PNG、WebP 或 GIF 圖片。');
            return;
        }
        if (file.size > 3 * 1024 * 1024) {
            window.alert('檔案過大，請小於 3MB。');
            return;
        }
        var url = URL.createObjectURL(file);
        state.objectUrl = url;
        var img = new Image();
        img.onload = function () {
            state.img = img;
            state.zoom = 1;
            state.panX = 0;
            state.panY = 0;
            panel.hidden = false;
            draw();
        };
        img.onerror = function () {
            clearObjectUrl();
            window.alert('無法讀取圖片。');
        };
        img.src = url;
    });

    if (zoomInput) {
        zoomInput.addEventListener('input', function () {
            state.zoom = parseFloat(zoomInput.value, 10) || 1;
            clampPan();
            draw();
        });
    }

    function pointerDown(clientX, clientY) {
        state.dragging = true;
        state.lastX = clientX;
        state.lastY = clientY;
    }

    function pointerMove(clientX, clientY) {
        if (!state.dragging) {
            return;
        }
        state.panX += clientX - state.lastX;
        state.panY += clientY - state.lastY;
        state.lastX = clientX;
        state.lastY = clientY;
        clampPan();
        draw();
    }

    function pointerUp() {
        state.dragging = false;
    }

    canvas.addEventListener('mousedown', function (e) {
        e.preventDefault();
        pointerDown(e.clientX, e.clientY);
    });
    window.addEventListener('mousemove', function (e) {
        pointerMove(e.clientX, e.clientY);
    });
    window.addEventListener('mouseup', pointerUp);

    canvas.addEventListener(
        'touchstart',
        function (e) {
            if (e.touches.length === 1) {
                e.preventDefault();
                pointerDown(e.touches[0].clientX, e.touches[0].clientY);
            }
        },
        { passive: false }
    );
    canvas.addEventListener(
        'touchmove',
        function (e) {
            if (e.touches.length === 1) {
                e.preventDefault();
                pointerMove(e.touches[0].clientX, e.touches[0].clientY);
            }
        },
        { passive: false }
    );
    canvas.addEventListener('touchend', pointerUp);

    if (btnApply) {
        btnApply.addEventListener('click', function () {
            var data = exportCrop();
            if (!data) {
                window.alert('無法產生剪裁圖，請再試一次。');
                return;
            }
            hidden.value = data;
            if (preview) {
                preview.src = data;
                preview.hidden = false;
            }
            panel.hidden = true;
        });
    }

    if (btnCancel) {
        btnCancel.addEventListener('click', function () {
            resetState();
        });
    }
})();
