/**
 * Mirror Panel — Canvas 기반 실시간 UI 미러링
 * 
 * Screencast 프레임을 canvas에 렌더링하고
 * 마우스/키보드/스크롤 이벤트를 서버로 전달
 */

class MirrorPanel {
    constructor() {
        this.canvas = document.getElementById('mirrorCanvas');
        this.ctx = this.canvas ? this.canvas.getContext('2d') : null;
        this.containerEl = document.getElementById('mirrorContainer');

        this.active = false;
        this.sessionId = null;

        // 실제 대상 페이지 크기 (metadata에서 가져옴)
        this.deviceWidth = 0;
        this.deviceHeight = 0;

        // 콜백
        this.onStartScreencast = null;  // callback(sessionId)
        this.onStopScreencast = null;   // callback(sessionId)
        this.onInputEvent = null;       // callback(sessionId, event)

        // 이미지 로딩용
        this._img = new Image();
        this._img.onload = () => {
            if (!this.ctx) return;
            this.canvas.width = this._img.naturalWidth;
            this.canvas.height = this._img.naturalHeight;
            this.ctx.drawImage(this._img, 0, 0);
        };

        // 마우스 이벤트 쓸모링
        this._lastMouseMove = 0;
        this._MOUSE_THROTTLE = 50; // ms

        this._setupEvents();
    }

    /**
     * 이벤트 바인딩
     */
    _setupEvents() {
        if (!this.canvas) return;

        // --- 마우스 ---
        this.canvas.addEventListener('mousedown', (e) => {
            if (!this.active) return;
            const pos = this._toDeviceCoords(e);
            this._sendMouse('mousePressed', pos, e);
        });

        this.canvas.addEventListener('mouseup', (e) => {
            if (!this.active) return;
            const pos = this._toDeviceCoords(e);
            this._sendMouse('mouseReleased', pos, e);
        });

        this.canvas.addEventListener('mousemove', (e) => {
            if (!this.active) return;
            const now = Date.now();
            if (now - this._lastMouseMove < this._MOUSE_THROTTLE) return;
            this._lastMouseMove = now;
            const pos = this._toDeviceCoords(e);
            this._sendMouse('mouseMoved', pos, e);
        });

        // --- 스크롤 ---
        this.canvas.addEventListener('wheel', (e) => {
            if (!this.active) return;
            e.preventDefault();
            const pos = this._toDeviceCoords(e);
            this._sendInput({
                type: 'scroll',
                x: pos.x,
                y: pos.y,
                deltaX: e.deltaX,
                deltaY: e.deltaY,
            });
        }, { passive: false });

        // --- 키보드 ---
        this.canvas.setAttribute('tabindex', '0');

        this.canvas.addEventListener('keydown', (e) => {
            if (!this.active) return;
            e.preventDefault();
            this._sendKey('keyDown', e);
            // char 이벤트도 보내야 텍스트 입력이 됨
            if (e.key.length === 1) {
                this._sendKey('char', e);
            }
        });

        this.canvas.addEventListener('keyup', (e) => {
            if (!this.active) return;
            e.preventDefault();
            this._sendKey('keyUp', e);
        });

        // canvas 클릭 시 포커스
        this.canvas.addEventListener('click', () => {
            this.canvas.focus();
        });

        // 우클릭 방지
        this.canvas.addEventListener('contextmenu', (e) => e.preventDefault());
    }

    /**
     * 미러링 시작
     */
    start(sessionId) {
        this.sessionId = sessionId;
        this.active = true;
        if (this.containerEl) this.containerEl.style.display = 'flex';
        if (this.onStartScreencast) this.onStartScreencast(sessionId);
        this.canvas?.focus();
    }

    /**
     * 미러링 중지
     */
    stop() {
        if (this.active && this.onStopScreencast) {
            this.onStopScreencast(this.sessionId);
        }
        this.active = false;
        this.sessionId = null;
        if (this.containerEl) this.containerEl.style.display = 'none';
        // canvas 초기화
        if (this.ctx && this.canvas) {
            this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        }
    }

    /**
     * Screencast 프레임 수신
     */
    updateFrame(data, metadata) {
        if (!this.active) return;

        if (metadata) {
            this.deviceWidth = metadata.deviceWidth || this.deviceWidth;
            this.deviceHeight = metadata.deviceHeight || this.deviceHeight;
        }

        // base64 JPEG를 이미지로 로드 → canvas에 그리기
        this._img.src = `data:image/jpeg;base64,${data}`;
    }

    /**
     * canvas 좌표 → 디바이스(Antigravity) 좌표 변환
     */
    _toDeviceCoords(e) {
        const rect = this.canvas.getBoundingClientRect();
        const scaleX = this.canvas.width / rect.width;
        const scaleY = this.canvas.height / rect.height;
        return {
            x: Math.round((e.clientX - rect.left) * scaleX),
            y: Math.round((e.clientY - rect.top) * scaleY),
        };
    }

    /**
     * 마우스 이벤트 전송
     */
    _sendMouse(action, pos, e) {
        const buttonMap = { 0: 'left', 1: 'middle', 2: 'right' };
        this._sendInput({
            type: 'mouse',
            action,
            x: pos.x,
            y: pos.y,
            button: buttonMap[e.button] || 'left',
            clickCount: action === 'mousePressed' ? 1 : 0,
            modifiers: this._getModifiers(e),
        });
    }

    /**
     * 키보드 이벤트 전송
     */
    _sendKey(action, e) {
        this._sendInput({
            type: 'key',
            action,
            key: e.key,
            code: e.code,
            text: action === 'char' ? e.key : '',
            keyCode: e.keyCode,
            modifiers: this._getModifiers(e),
        });
    }

    /**
     * 입력 이벤트 전송 (공통)
     */
    _sendInput(event) {
        if (this.onInputEvent && this.sessionId) {
            this.onInputEvent(this.sessionId, event);
        }
    }

    /**
     * 수정키 비트마스크 계산 (CDP 규격)
     */
    _getModifiers(e) {
        let m = 0;
        if (e.altKey) m |= 1;
        if (e.ctrlKey) m |= 2;
        if (e.metaKey) m |= 4;
        if (e.shiftKey) m |= 8;
        return m;
    }
}
