/**
 * 等距绘制排序（重设计）
 *
 * 单一全序标量，无成环、无特判互打：
 *   frontKey = -(cellX + cellY) * CELL   // 更小 x+y → 屏幕更靠下 → 更靠前
 *   + typeRank                            // 同对角条带内：地板 < 金币 < 载具 < 角色 < 墙
 *
 * 移动中采样拆开：
 * - 角色：朝前落点 / 朝后起点
 * - 载具：朝前起点（防浮到前砖上）/ 朝后落点（防途中比落点更靠前而不被下方砖挡）
 * 贴墙南/西立面格上的实体：抬到该墙之上（露脚）。
 * 角色永远盖过同条带载具。
 */

import { Vec3 } from 'cc';
import { CommonDefine } from '../core/Define';
import { cellToWorldCenter } from '../core/GridCoords';

export const UNITY_TRANSPARENCY_AXIS = { x: 0, y: 1, z: -0.26 } as const;

export const UNITY_SORTING_ORDER = {
    nProp: 1,
    tilemap: 2,
    vehicle: 2,
    prop: 3,
    player: 4,
} as const;

const CELL = 100;
/** 同对角条带内层级：地板 < 金币 < 载具 < 角色 < 墙立面 */
const RANK_FLOOR = 0;
const RANK_PICKABLE = 20;
const RANK_VEHICLE = 30;
const RANK_PLAYER = 35;
const RANK_WALL = 40;

export function isWallBlockTileName(tileName: string): boolean {
    return tileName === CommonDefine.BlockWall;
}

export function isWalkableTileName(tileName: string): boolean {
    return tileName === CommonDefine.BlockBase || tileName === CommonDefine.BlockJump;
}

export function unityTileIndividualSortingOrder(cellX: number, cellY: number): number {
    return UNITY_SORTING_ORDER.tilemap - cellX - cellY;
}

export function unityTransparencyDepth(worldX: number, worldY: number, worldZ = 0): number {
    return worldX * UNITY_TRANSPARENCY_AXIS.x
        + worldY * UNITY_TRANSPARENCY_AXIS.y
        + worldZ * UNITY_TRANSPARENCY_AXIS.z;
}

export function unityCompositeSortKey(
    sortingOrder: number,
    depthWorldY: number,
    depthWorldZ = 0,
    bias = 0,
): number {
    const depth = unityTransparencyDepth(0, depthWorldY, depthWorldZ);
    return sortingOrder * 10_000 + depth * 100 + bias;
}

export function unityCellCenterY(cellX: number, cellY: number): number {
    return cellToWorldCenter(new Vec3(cellX, cellY, 0)).y;
}

export interface UnitySortableTile {
    cellX: number;
    cellY: number;
    tileName: string;
    centerY: number;
    depthY: number;
}

export interface UnitySortableEntity {
    sortingOrder: number;
    cellX: number;
    cellY: number;
    centerY: number;
    depthY: number;
    isPlayer: boolean;
    isPickable: boolean;
}

/** 返回值 > 0 表示 (ax,ay) 应排在 (bx,by) 之后（更靠前） */
export function compareIsoDrawOrder(ax: number, ay: number, bx: number, by: number): number {
    const ka = ax + ay;
    const kb = bx + by;
    if (ka !== kb) return kb - ka;
    return ax - bx;
}

export function compareTileCellDepth(ax: number, ay: number, bx: number, by: number): number {
    return compareIsoDrawOrder(ax, ay, bx, by);
}

function wallFaceSamples(wallX: number, wallY: number): { x: number; y: number }[] {
    return [{ x: wallX, y: wallY - 1 }, { x: wallX - 1, y: wallY }];
}

function typeRankForTile(tileName: string): number {
    return isWallBlockTileName(tileName) ? RANK_WALL : RANK_FLOOR;
}

function typeRankForEntity(entity: UnitySortableEntity): number {
    if (entity.isPickable) return RANK_PICKABLE;
    if (entity.isPlayer) return RANK_PLAYER;
    return RANK_VEHICLE;
}

/** 越大越靠前（后绘制） */
export function isoDrawFrontKey(cellX: number, cellY: number, typeRank: number): number {
    return -(cellX + cellY) * CELL + typeRank;
}

export function tileDrawFrontKey(tile: UnitySortableTile): number {
    return isoDrawFrontKey(tile.cellX, tile.cellY, typeRankForTile(tile.tileName));
}

export function entityDrawFrontKey(entity: UnitySortableEntity): number {
    return isoDrawFrontKey(entity.cellX, entity.cellY, typeRankForEntity(entity));
}

/**
 * 若实体踩在某墙南/西立面上，应露在该墙前面。
 * 返回需要超过的墙 frontKey，否则 null。
 */
export function entityFaceLiftOverWall(
    entity: UnitySortableEntity,
    tile: UnitySortableTile,
): number | null {
    if (!isWallBlockTileName(tile.tileName)) return null;
    const cell = { x: entity.cellX, y: entity.cellY };
    for (const face of wallFaceSamples(tile.cellX, tile.cellY)) {
        if (face.x === cell.x && face.y === cell.y) {
            return tileDrawFrontKey(tile);
        }
    }
    return null;
}

/** 实体相对整张关卡的 frontKey（含贴墙抬升） */
export function entityDrawFrontKeyWithWalls(
    entity: UnitySortableEntity,
    walls: UnitySortableTile[],
): number {
    let key = entityDrawFrontKey(entity);
    for (const w of walls) {
        const lift = entityFaceLiftOverWall(entity, w);
        if (lift != null && key <= lift) key = lift + 1;
    }
    return key;
}

export function compareUnityTileToTile(a: UnitySortableTile, b: UnitySortableTile): number {
    const d = tileDrawFrontKey(a) - tileDrawFrontKey(b);
    if (d !== 0) return d;
    return a.cellX - b.cellX;
}

export function compareUnityEntityToEntity(a: UnitySortableEntity, b: UnitySortableEntity): number {
    const d = entityDrawFrontKey(a) - entityDrawFrontKey(b);
    if (d !== 0) return d;
    if (a.isPlayer && !b.isPlayer) return 1;
    if (b.isPlayer && !a.isPlayer) return -1;
    return a.sortingOrder - b.sortingOrder;
}

/**
 * 实体 vs 砖：统一用 frontKey。
 * （保留函数供外部/测试调用；排序主路径用 build 里的 key）
 */
export function compareUnityEntityToTile(
    entity: UnitySortableEntity,
    tile: UnitySortableTile,
): number {
    if (!isWallBlockTileName(tile.tileName)) {
        // 地板永在实体下
        return 1;
    }
    const lift = entityFaceLiftOverWall(entity, tile);
    const eKey = lift != null ? lift + 1 : entityDrawFrontKey(entity);
    return eKey - tileDrawFrontKey(tile);
}
