'use strict';

function compUuid(dump) {
    if (!dump || !dump.value) return '';
    const u = dump.value.uuid;
    return (u && u.value) ? u.value : (typeof u === 'string' ? u : '');
}

function getMessageProtocolScene(el) {
    let element = el;
    while (element) {
        const root = element.getRootNode && element.getRootNode();
        element = element.parentElement || (root && root.host) || null;
        if (element && element.messageProtocol && element.messageProtocol.scene) {
            return element.messageProtocol.scene;
        }
    }
    return 'scene';
}

async function callMethod(contextEl, uuid, name, args) {
    if (!uuid || typeof Editor === 'undefined') return;
    const protocols = [];
    const primary = getMessageProtocolScene(contextEl);
    if (primary) protocols.push(primary);
    if (protocols.indexOf('scene') < 0) protocols.push('scene');
    let lastErr;
    for (let i = 0; i < protocols.length; i++) {
        try {
            await Editor.Message.request(protocols[i], 'execute-component-method', {
                uuid,
                name,
                args: args || [],
            });
            return;
        } catch (e) {
            lastErr = e;
        }
    }
    console.warn('[game-controller-inspector]', name, lastErr);
}

function parseStep(raw) {
    const n = parseInt(String(raw || '1'), 10);
    return Number.isNaN(n) || n === 0 ? 1 : n;
}

module.exports = Editor.Panel.define({
    template: `
        <div class="gc-debug">
            <ui-label class="hint">预览 ▶ 运行后可用（对齐 Unity TestPlayer）</ui-label>
            <div class="row">
                <ui-label class="lbl">步数</ui-label>
                <ui-input class="step" value="1"></ui-input>
            </div>
            <div class="row">
                <ui-button class="fwd">前进</ui-button>
                <ui-button class="back">后退</ui-button>
                <ui-button class="jump">跳</ui-button>
            </div>
            <div class="row">
                <ui-button class="rot-l">左转</ui-button>
                <ui-button class="rot-r">右转</ui-button>
                <ui-button class="info">坐标</ui-button>
            </div>
            <div class="row">
                <ui-button class="end">结束输入</ui-button>
                <ui-button class="veh">载具+1</ui-button>
                <ui-button class="reset">重置关卡</ui-button>
            </div>
            <div class="row level-nav">
                <ui-button class="btn-prev">上一关</ui-button>
                <ui-button class="btn-next">下一关</ui-button>
            </div>
            <ui-button class="btn-switch blue">SwitchLevel</ui-button>
        </div>
    `,
    style: `
        .gc-debug { margin-top: 6px; }
        .gc-debug .hint { opacity: 0.75; font-size: 11px; margin-bottom: 8px; display: block; }
        .gc-debug .row { display: flex; gap: 4px; margin-bottom: 6px; }
        .gc-debug .lbl { font-size: 11px; align-self: center; }
        .gc-debug .step { flex: 1; }
        .gc-debug ui-button { flex: 1; }
        .gc-debug .level-nav { margin-top: 2px; }
        .gc-debug .btn-switch { width: 100%; margin-top: 4px; }
    `,
    $: {
        hint: '.hint',
        step: '.step',
        fwd: '.fwd',
        back: '.back',
        jump: '.jump',
        rotL: '.rot-l',
        rotR: '.rot-r',
        info: '.info',
        end: '.end',
        veh: '.veh',
        reset: '.reset',
        btnSwitch: '.btn-switch',
        btnPrev: '.btn-prev',
        btnNext: '.btn-next',
    },
    ready() {
        const uuid = () => compUuid(this.dump);
        const step = () => parseStep(this.$.step.value);
        const ctx = () => this.$this || this.$.btnSwitch;
        this.$.fwd.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'debugMove', [step()]));
        this.$.back.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'debugMove', [-step()]));
        this.$.jump.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'debugJump', []));
        this.$.rotL.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'debugRotateLeft', [1]));
        this.$.rotR.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'debugRotateRight', [1]));
        this.$.info.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'debugPlayerInfo', []));
        this.$.end.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'debugInputEnd', []));
        this.$.veh.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'debugVehicleMove', [1]));
        this.$.reset.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'debugResetLevel', []));
        this.$.btnPrev.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'prevLevel', []));
        this.$.btnNext.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'nextLevel', []));
        this.$.btnSwitch.addEventListener('confirm', () => void callMethod(ctx(), uuid(), 'clickSwitchLevel', []));
    },
    update(dump) {
        if (dump) this.dump = dump;
    },
});
