/** 与 Unity Platformer.Core.Define 对齐 */

export enum Direction {
    North = 0,
    East = 1,
    South = 2,
    West = 3,
}

export enum MoveState {
    Idle = 0,
    Moving = 1,
}

export enum GridType {
    Across = 0,
    Jump = 1,
    Block = 2,
    Ride = 3,
    None = 4,
    Boundary = 5,
}

export enum Skin {
    Silu = 0,
    Panda = 1,
    RedArmy = 2,
    numMan = 3,
    snow = 4,
    sanxing = 5,
}

const SKIN_TO_THEME: Record<Skin, string> = {
    [Skin.Silu]: 'silu',
    [Skin.Panda]: 'chinese',
    [Skin.RedArmy]: 'redArmy',
    [Skin.numMan]: 'numMan',
    [Skin.snow]: 'snow',
    [Skin.sanxing]: 'sanxing',
};

const THEME_TO_SKIN: Record<string, Skin> = {
    silu: Skin.Silu,
    chinese: Skin.Panda,
    redarmy: Skin.RedArmy,
    redArmy: Skin.RedArmy,
    numMan: Skin.numMan,
    snow: Skin.snow,
    sanxing: Skin.sanxing,
};

export function skinToTheme(skin: Skin): string {
    return SKIN_TO_THEME[skin] ?? 'silu';
}

export function themeToSkin(theme: string | undefined): Skin {
    if (!theme) return Skin.Silu;
    const key = theme.trim();
    return THEME_TO_SKIN[key] ?? THEME_TO_SKIN[key.toLowerCase()] ?? Skin.Silu;
}

export enum GameState {
    Run = 0,
    ResultWin = 1,
    ResultFail = 2,
}

export type MoverRole = 'player' | 'vehicle';

export const CELL_SIZE = 1;

export const CommonDefine = {
    TilemapGround: 'Ground',
    TilemapBorder: 'Border',
    Prop: 'Prop',
    Vehicle: 'Vehicle',
    BlockBase: 'Baseblock',
    BlockJump: 'JumpBlock',
    /** 墙砖贴图 key（Border 默认瓦片；仅此类参与墙遮挡） */
    BlockWall: 'WallBlock',
};

export function addDirection(dir: Direction, delta: number): Direction {
    const n = 4;
    return (((dir + delta) % n) + n) % n as Direction;
}

type MoveKey = string;

function mk(role: MoverRole, cur: GridType, next: GridType, jump: boolean): MoveKey {
    return `${role}|${cur}|${next}|${jump ? 1 : 0}`;
}

function buildMoveTable(entries: [MoverRole, GridType, GridType, boolean, number][]): Map<MoveKey, number> {
    const m = new Map<MoveKey, number>();
    for (const [role, cur, next, jump, v] of entries) {
        m.set(mk(role, cur, next, jump), v);
    }
    return m;
}

/**
 * 单人 moveCondition — 基于 Unity Define.cs，并扩展骑乘 → Jump 跳跃
 * 判定入口：gameplay/MoveRules.checkMoveStep
 */
export const moveCondition = buildMoveTable([
    ['player', GridType.Across, GridType.Across, false, 1],
    ['player', GridType.Jump, GridType.Across, false, 1],
    ['player', GridType.Jump, GridType.Across, true, 1],
    ['player', GridType.Ride, GridType.Across, false, 1],
    ['player', GridType.Ride, GridType.Across, true, 1],
    ['player', GridType.Across, GridType.Jump, true, 1],
    ['player', GridType.Across, GridType.Ride, false, 1],
    ['player', GridType.Across, GridType.Ride, true, 1],
    ['player', GridType.Jump, GridType.Ride, false, 1],
    ['player', GridType.Jump, GridType.Ride, true, 1],
    ['player', GridType.Jump, GridType.Jump, false, 1],
    ['player', GridType.Jump, GridType.Jump, true, 1],
    ['player', GridType.Ride, GridType.None, false, 1],
    ['player', GridType.Ride, GridType.None, true, 1],
    ['player', GridType.Ride, GridType.Jump, true, 1],
    ['player', GridType.None, GridType.Jump, true, 1],
    ['player', GridType.None, GridType.None, false, 1],
    ['player', GridType.None, GridType.None, true, 1],
    ['player', GridType.None, GridType.Across, false, 1],
    ['player', GridType.None, GridType.Across, true, 1],
    ['vehicle', GridType.None, GridType.None, false, 1],
    ['vehicle', GridType.None, GridType.None, true, 1],
    ['vehicle', GridType.Ride, GridType.None, false, 1],
]);

/** 多人 moveConditionMult — 与 Unity Define.cs moveConditionMult 逐项一致 */
const multEntries: [MoverRole, GridType, GridType, boolean, number][] = [
    ['player', GridType.Across, GridType.Across, false, 1],
    ['player', GridType.Across, GridType.Across, true, 1],
    ['player', GridType.Jump, GridType.Across, false, 1],
    ['player', GridType.Jump, GridType.Across, true, 1],
    ['player', GridType.Ride, GridType.Across, false, 1],
    ['player', GridType.Ride, GridType.Across, true, 1],
    ['player', GridType.Across, GridType.Jump, true, 1],
    ['player', GridType.Across, GridType.Jump, false, 1],
    ['player', GridType.Across, GridType.Ride, false, 1],
    ['player', GridType.Across, GridType.Ride, true, 1],
    ['player', GridType.Jump, GridType.Ride, false, 1],
    ['player', GridType.Jump, GridType.Ride, true, 1],
    ['player', GridType.Jump, GridType.Jump, false, 1],
    ['player', GridType.Jump, GridType.Jump, true, 1],
    ['player', GridType.Ride, GridType.None, false, 1],
    ['player', GridType.Ride, GridType.None, true, 1],
    ['player', GridType.Ride, GridType.Jump, true, 1],
    ['player', GridType.None, GridType.Jump, true, 1],
    ['player', GridType.None, GridType.None, false, 1],
    ['player', GridType.None, GridType.None, true, 1],
    ['player', GridType.None, GridType.Across, false, 1],
    ['player', GridType.None, GridType.Across, true, 1],
    ['player', GridType.Across, GridType.Block, false, 0],
    ['player', GridType.Across, GridType.Block, true, 0],
    ['vehicle', GridType.Ride, GridType.Block, false, 0],
    ['vehicle', GridType.Ride, GridType.Block, true, 0],
    ['vehicle', GridType.Ride, GridType.Across, false, 0],
    ['vehicle', GridType.Ride, GridType.Across, true, 0],
    ['vehicle', GridType.None, GridType.None, false, 1],
    ['vehicle', GridType.None, GridType.None, true, 1],
    ['vehicle', GridType.Ride, GridType.None, false, 1],
    ['vehicle', GridType.Ride, GridType.None, true, 1],
];
export const moveConditionMultMap = buildMoveTable(multEntries);

export const skinPath: Record<Skin, { unlockLevel: number }> = {
    [Skin.Silu]: { unlockLevel: 0 },
    [Skin.Panda]: { unlockLevel: 400 },
    [Skin.RedArmy]: { unlockLevel: 800 },
    [Skin.numMan]: { unlockLevel: 1200 },
    [Skin.snow]: { unlockLevel: 1600 },
    [Skin.sanxing]: { unlockLevel: 1600 },
};

export function getMoveCondition(mult: boolean): Map<MoveKey, number> {
    return mult ? moveConditionMultMap : moveCondition;
}

export function lookupMove(
    table: Map<MoveKey, number>,
    role: MoverRole,
    cur: GridType,
    next: GridType,
    jump: boolean,
): number | undefined {
    return table.get(mk(role, cur, next, jump));
}
