import { Size, SpriteFrame } from 'cc';
import { CELL_PIXEL } from '../core/GridConstants';
import { getThemeEntityDisplayCellBoxes } from '../theme/ThemeDatabase';

/** 内置默认（themes-database 未加载时使用） */
export const DEFAULT_ENTITY_CELL_BOX = {
    player: { w: 0.68, h: 0.9 },
    vehicle: { w: 0.96, h: 0.88 },
    prop: { w: 0.52, h: 0.69 },
    propGround: { w: 0.52, h: 0.69 },
} as const;

/** 装饰物相对可拾取物的缩放比 */
const PROP_DECOR_RATIO = 0.45 / 0.69;

const cellW = (ratio: number) => CELL_PIXEL * ratio;
const cellH = (ratio: number) => CELL_PIXEL * ratio;

export function getEntityCellBox(theme?: string) {
    if (theme) return getThemeEntityDisplayCellBoxes(theme);
    return { ...DEFAULT_ENTITY_CELL_BOX };
}

export const DEFAULT_PLAYER_ANCHOR_Y = 0.35;
/** Unity silu ship pivot y = 0.45 */
export const DEFAULT_VEHICLE_ANCHOR_Y = 0.45;

export function getEntityDisplaySizes(theme?: string) {
    const box = getEntityCellBox(theme);
    return {
        player: {
            width: cellW(box.player.w),
            height: cellH(box.player.h),
        },
        vehicle: {
            width: cellW(box.vehicle.w),
            height: cellH(box.vehicle.h),
        },
        prop: {
            width: cellW(box.prop.w),
            height: cellH(box.prop.h),
        },
        propGround: {
            width: cellW(box.propGround.w),
            height: cellH(box.propGround.h),
        },
        prop_decor: {
            width: cellW(box.prop.w) * PROP_DECOR_RATIO,
            height: cellH(box.prop.h) * PROP_DECOR_RATIO,
        },
    };
}

/** @deprecated 使用 getEntityDisplaySizes(theme) */
export const ENTITY_CELL_BOX = DEFAULT_ENTITY_CELL_BOX;

/** @deprecated 使用 getEntityDisplaySizes(theme) */
export const SANXING_ENTITY_DISPLAY = {
    get player() { return getEntityDisplaySizes().player; },
    get vehicle() { return getEntityDisplaySizes().vehicle; },
    get prop() { return getEntityDisplaySizes().prop; },
    get prop_decor() { return getEntityDisplaySizes().prop_decor; },
};

export type EntityDisplayKind = 'player' | 'vehicle' | 'prop' | 'propGround' | 'prop_decor';

type SpawnKindLike = 'player' | 'vehicle' | 'prop' | 'prop_decor';

export function entityPlaceholderSize(kind: SpawnKindLike, theme?: string): { width: number; height: number } {
    const sizes = getEntityDisplaySizes(theme);
    if (kind === 'prop_decor') return sizes.prop_decor;
    if (kind === 'prop') return sizes.prop;
    if (kind === 'vehicle') return sizes.vehicle;
    return sizes.player;
}

export function spriteOriginalSize(sf: SpriteFrame): { width: number; height: number } {
    const rect = sf.rect;
    if (rect.width > 0 && rect.height > 0) {
        return { width: rect.width, height: rect.height };
    }
    let w = sf.originalSize?.width ?? 0;
    let h = sf.originalSize?.height ?? 0;
    if (w <= 0 || h <= 0) {
        w = sf.texture?.width ?? 1;
        h = sf.texture?.height ?? 1;
    }
    return { width: Math.max(1, w), height: Math.max(1, h) };
}

/** 等比缩放，完整落入主题包围盒（contain） */
export function fitEntityDisplaySize(
    kind: EntityDisplayKind,
    sf: SpriteFrame,
    scaleMul = 1,
    theme?: string,
): { width: number; height: number; anchorX: number; anchorY: number } {
    const s = computeEntityUniformScale(kind, sf, scaleMul, theme);
    return sizeFromUniformScale(sf, s, kind, theme);
}

/** 单帧 contain 缩放系数（序列动画各帧共用，避免画布尺寸不同导致比例跳变） */
export function computeEntityUniformScale(
    kind: EntityDisplayKind,
    sf: SpriteFrame,
    scaleMul = 1,
    theme?: string,
): number {
    const mul = Math.max(0.1, Math.min(4, scaleMul));
    const { width: ow, height: oh } = spriteOriginalSize(sf);
    const ref = getEntityDisplaySizes(theme)[kind];
    return Math.min(ref.width * mul / ow, ref.height * mul / oh);
}

export function sizeFromUniformScale(
    sf: SpriteFrame,
    uniformScale: number,
    kind: EntityDisplayKind = 'player',
    theme?: string,
): { width: number; height: number; anchorX: number; anchorY: number } {
    const { width: ow, height: oh } = spriteOriginalSize(sf);
    let anchorY = 0;
    if (kind === 'player') {
        anchorY = DEFAULT_PLAYER_ANCHOR_Y;
    } else if (kind === 'vehicle') {
        anchorY = DEFAULT_VEHICLE_ANCHOR_Y;
    } else if (kind !== 'prop' && kind !== 'propGround' && kind !== 'prop_decor') {
        anchorY = DEFAULT_PLAYER_ANCHOR_Y;
    }
    return {
        width: ow * uniformScale,
        height: oh * uniformScale,
        anchorX: 0.5,
        anchorY,
    };
}

/**
 * 序列帧脚点对齐：各帧保留原始比例，仅调 anchorY。
 * 脚离画布底边像素一致时：anchorY = baseAnchorY * refOh / oh
 */
export function playerSeqFrameAnchorY(
    sf: SpriteFrame,
    refSf: SpriteFrame,
    baseAnchorY = DEFAULT_PLAYER_ANCHOR_Y,
): number {
    const oh = Math.max(1, spriteOriginalSize(sf).height);
    const refOh = Math.max(1, spriteOriginalSize(refSf).height);
    if (oh === refOh) return baseAnchorY;
    return baseAnchorY * refOh / oh;
}

/** 动态 SpriteFrame 补全 originalSize（ImageAsset 直载时 Cocos 默认为 0） */
export function ensureSpriteFrameSize(sf: SpriteFrame, width: number, height: number) {
    if (sf.originalSize.width > 0 && sf.originalSize.height > 0) return;
    sf.originalSize = new Size(Math.max(1, width), Math.max(1, height));
}
