#!/usr/bin/env node
/**
 * 自测等距 frontKey 排序（与 UnityDrawSort.ts 对齐）
 * 运行: node tools/verify-unity-draw-sort.mjs
 */

const CELL = 100;
const RANK_FLOOR = 0;
const RANK_PICKABLE = 20;
const RANK_VEHICLE = 30;
const RANK_PLAYER = 35;
const RANK_WALL = 40;

function frontKey(x, y, rank) {
    return -(x + y) * CELL + rank;
}

function entityInFrontOfTile(entity, tile) {
    const eRank = entity.isPickable ? RANK_PICKABLE : (entity.isPlayer ? RANK_PLAYER : RANK_VEHICLE);
    let eKey = frontKey(entity.cellX, entity.cellY, eRank);
    // 贴墙立面抬升
    const faces = [
        { x: tile.cellX, y: tile.cellY - 1 },
        { x: tile.cellX - 1, y: tile.cellY },
    ];
    const onFace = faces.some((f) => f.x === entity.cellX && f.y === entity.cellY);
    const tKey = frontKey(tile.cellX, tile.cellY, tile.tileName === 'WallBlock' ? RANK_WALL : RANK_FLOOR);
    if (tile.tileName === 'WallBlock' && onFace) eKey = Math.max(eKey, tKey + 1);
    return eKey > tKey;
}

function tileInFrontOfTile(a, b) {
    return frontKey(a.x, a.y, RANK_FLOOR) > frontKey(b.x, b.y, RANK_FLOOR);
}

const cases = [
    {
        name: '砖：南 (0,-2) 挡北 (0,-1)',
        pass: tileInFrontOfTile({ x: 0, y: -2 }, { x: 0, y: -1 }),
    },
    {
        name: '北墙 (-1,1) 挡住中心角色 (0,0)',
        pass: !entityInFrontOfTile(
            { cellX: 0, cellY: 0 },
            { cellX: -1, cellY: 1, tileName: 'WallBlock' },
        ),
    },
    {
        name: '东墙 (1,-1) 挡住中心角色 (0,0)（同对角立面）',
        pass: !entityInFrontOfTile(
            { cellX: 0, cellY: 0 },
            { cellX: 1, cellY: -1, tileName: 'WallBlock' },
        ),
    },
    {
        name: '南 tip 墙 (-1,-3) 挡住金币 (0,-3)',
        pass: !entityInFrontOfTile(
            { cellX: 0, cellY: -3, isPickable: true },
            { cellX: -1, cellY: -3, tileName: 'WallBlock' },
        ),
    },
    {
        name: '金币 (0,-3) 在东后墙 (1,-3) 之前（屏上金币更靠前）',
        pass: entityInFrontOfTile(
            { cellX: 0, cellY: -3, isPickable: true },
            { cellX: -1, cellY: -2, tileName: 'Baseblock' },
        ) && entityInFrontOfTile(
            { cellX: 0, cellY: -3, isPickable: true },
            { cellX: 1, cellY: -3, tileName: 'WallBlock' },
        ),
    },
    {
        name: '贴南墙立面 (0,-1) 露在墙 (0,0) 前',
        pass: entityInFrontOfTile(
            { cellX: 0, cellY: -1 },
            { cellX: 0, cellY: 0, tileName: 'WallBlock' },
        ),
    },
    {
        name: '南墙 (0,-1) 挡住角色 (0,0)',
        pass: !entityInFrontOfTile(
            { cellX: 0, cellY: 0 },
            { cellX: 0, cellY: -1, tileName: 'WallBlock' },
        ),
    },
    {
        name: '左墙 (-6,-2) 挡住角色 (-4,-3)',
        pass: !entityInFrontOfTile(
            { cellX: -4, cellY: -3 },
            { cellX: -6, cellY: -2, tileName: 'WallBlock' },
        ),
    },
    {
        name: '载具朝前钉起点：相对南侧地砖仍被挡',
        pass: !entityInFrontOfTile(
            { cellX: 0, cellY: 0, isPlayer: false },
            { cellX: 0, cellY: -1, tileName: 'Baseblock' },
        ),
    },
    {
        name: '载具朝后用落点：从(0,0)→(1,0) 比钉起点更靠后（继续被下方砖挡）',
        pass: (() => {
            const floor = { cellX: 0, cellY: -1, tileName: 'Baseblock' };
            // 起点更靠前，相对该南侧砖「不挡得那么死」；落点更靠后应仍被挡住
            const startKeyWins = entityInFrontOfTile(
                { cellX: 0, cellY: 0, isPlayer: false },
                floor,
            );
            const landOccluded = !entityInFrontOfTile(
                { cellX: 1, cellY: 0, isPlayer: false },
                floor,
            );
            return !startKeyWins && landOccluded;
        })(),
    },
    {
        name: '角色朝前用落点：从(0,1)→(0,0) 途中露前',
        pass: (() => {
            const from = { cellX: 0, cellY: 1 };
            const to = { cellX: 0, cellY: 0 };
            const wall = { cellX: 1, cellY: 0, tileName: 'WallBlock' };
            return !entityInFrontOfTile(from, wall) && entityInFrontOfTile(to, wall);
        })(),
    },
    {
        name: '同格：角色永远盖过载具',
        pass: frontKey(0, 0, RANK_PLAYER) > frontKey(0, 0, RANK_VEHICLE),
    },
    {
        name: '南侧地砖可挡住同侧偏后的实体（下方地砖应遮挡载具）',
        pass: !entityInFrontOfTile(
            { cellX: 0, cellY: 0 },
            { cellX: 0, cellY: -1, tileName: 'Baseblock' },
        ),
    },
    {
        name: '人物与载具同格 frontKey 条带一致（主题无关）',
        pass: Math.floor(frontKey(2, -1, RANK_PLAYER) / 100) === Math.floor(frontKey(2, -1, RANK_VEHICLE) / 100),
    },
];

let failed = 0;
for (const c of cases) {
    const ok = !!c.pass;
    console.log(`${ok ? '✓' : '✗'} ${c.name}`);
    if (!ok) failed++;
}
if (failed > 0) {
    console.error(`\n${failed} case(s) failed`);
    process.exit(1);
}
console.log(`\nAll ${cases.length} cases passed.`);
