const joystickCtx = {
    base: null,
    stick: null,
    actionBtn: null,
    container: null,
    activePointerId: null,
    centerX: 0,
    centerY: 0,
    radius: 55,
    vector: { x: 0, y: 0 },
    actionPressed: false,
    enabled: false
};

function _shouldEnableTouch() {
    return window.matchMedia && window.matchMedia('(pointer: coarse)').matches;
}

function initJoystick() {
    joystickCtx.container = document.getElementById('touch-controls');
    joystickCtx.base = document.getElementById('joystick-base');
    joystickCtx.stick = document.getElementById('joystick-stick');
    joystickCtx.actionBtn = document.getElementById('action-btn');

    if (!_shouldEnableTouch()) return;

    joystickCtx.enabled = true;
    joystickCtx.container.hidden = false;

    const baseRect = () => joystickCtx.base.getBoundingClientRect();
    joystickCtx.radius = joystickCtx.base.offsetWidth / 2 - 10;

    const onDown = (e) => {
        e.preventDefault();
        if (joystickCtx.activePointerId !== null) return;
        joystickCtx.activePointerId = e.pointerId;
        const r = baseRect();
        joystickCtx.centerX = r.left + r.width / 2;
        joystickCtx.centerY = r.top + r.height / 2;
        try { joystickCtx.base.setPointerCapture(e.pointerId); } catch (_) {}
        _moveStick(e.clientX, e.clientY);
    };
    const onMove = (e) => {
        if (e.pointerId !== joystickCtx.activePointerId) return;
        e.preventDefault();
        _moveStick(e.clientX, e.clientY);
    };
    const onUp = (e) => {
        if (e.pointerId !== joystickCtx.activePointerId) return;
        joystickCtx.activePointerId = null;
        joystickCtx.vector.x = 0;
        joystickCtx.vector.y = 0;
        joystickCtx.stick.style.transform = 'translate(-50%, -50%)';
    };

    joystickCtx.base.addEventListener('pointerdown', onDown);
    joystickCtx.base.addEventListener('pointermove', onMove);
    joystickCtx.base.addEventListener('pointerup', onUp);
    joystickCtx.base.addEventListener('pointercancel', onUp);
    joystickCtx.base.addEventListener('pointerleave', onUp);

    joystickCtx.actionBtn.addEventListener('pointerdown', (e) => {
        e.preventDefault();
        joystickCtx.actionPressed = true;
    });
    joystickCtx.actionBtn.addEventListener('pointerup', (e) => {
        e.preventDefault();
        joystickCtx.actionPressed = false;
    });
    joystickCtx.actionBtn.addEventListener('pointercancel', () => {
        joystickCtx.actionPressed = false;
    });
}

function _moveStick(clientX, clientY) {
    const dx = clientX - joystickCtx.centerX;
    const dy = clientY - joystickCtx.centerY;
    const dist = Math.sqrt(dx * dx + dy * dy);
    const max = joystickCtx.radius;
    let usedX = dx, usedY = dy;
    if (dist > max) {
        usedX = (dx / dist) * max;
        usedY = (dy / dist) * max;
    }
    joystickCtx.stick.style.transform = `translate(calc(-50% + ${usedX}px), calc(-50% + ${usedY}px))`;
    joystickCtx.vector.x = usedX / max;
    joystickCtx.vector.y = usedY / max;
}

function readJoystick() {
    return joystickCtx.vector;
}

function readJoystickAction() {
    return joystickCtx.actionPressed;
}

function joystickEnabled() {
    return joystickCtx.enabled;
}
