'use strict';

const TOOLS = ['paint', 'box', 'picker', 'eraser', 'fill'];

const TOOL_LABELS = {
    paint: '画笔：在网格上点击或拖拽绘制（需先在右侧选瓦片）',
    box: '框选：拖拽矩形区域，松开后用当前瓦片填满',
    picker: '吸管：点击已有格子，吸取瓦片为当前画笔',
    eraser: '橡皮擦：点击或拖拽删除当前层的格子',
    fill: '油漆桶：填充相连的同类型格子（需先选瓦片）',
};

const TOOL_CURSORS = {
    paint: 'crosshair',
    box: 'crosshair',
    picker: 'copy',
    eraser: 'not-allowed',
    fill: 'cell',
};

function layerMap(state) {
    return state.editLayer === 'ground' ? state.config.ground : state.config.border;
}

function getCell(state, key) {
    const map = layerMap(state);
    return map[key];
}

function hasCell(state, key) {
    return getCell(state, key) !== undefined;
}

function removeCell(state, key) {
    if (state.editLayer === 'ground') delete state.config.ground[key];
    else delete state.config.border[key];
}

function setCell(state, key, tileKey) {
    if (state.editLayer === 'ground') {
        state.config.ground[key] = tileKey === 'JumpBlock' ? 'JumpBlock' : 'Baseblock';
    } else {
        const s = typeof tileKey === 'string' ? tileKey.trim() : '';
        state.config.border[key] = (!s || s === 'Baseblock' || s === 'JumpBlock') ? 'WallBlock' : s;
    }
}

function canPaintBrush(state) {
    return state.brush && state.brush.layer === state.editLayer;
}

function fillRectangle(state, x0, y0, x1, y1, tileKey) {
    const minX = Math.min(x0, x1);
    const maxX = Math.max(x0, x1);
    const minY = Math.min(y0, y1);
    const maxY = Math.max(y0, y1);
    let n = 0;
    for (let x = minX; x <= maxX; x++) {
        for (let y = minY; y <= maxY; y++) {
            setCell(state, `${x},${y}`, tileKey);
            n++;
        }
    }
    return n;
}

function eraseRectangle(state, x0, y0, x1, y1) {
    const minX = Math.min(x0, x1);
    const maxX = Math.max(x0, x1);
    const minY = Math.min(y0, y1);
    const maxY = Math.max(y0, y1);
    let n = 0;
    for (let x = minX; x <= maxX; x++) {
        for (let y = minY; y <= maxY; y++) {
            const key = `${x},${y}`;
            if (hasCell(state, key)) {
                removeCell(state, key);
                n++;
            }
        }
    }
    return n;
}

/** 四连通洪水填充（仅当前编辑层） */
function floodFill(state, startKey, fillTileKey) {
    const map = layerMap(state);
    const target = map[startKey];
    if (target === fillTileKey) return 0;
    const q = [startKey];
    const seen = new Set([startKey]);
    let n = 0;
    while (q.length) {
        const key = q.shift();
        map[key] = fillTileKey;
        n++;
        const [xs, ys] = key.split(',');
        const x = parseInt(xs, 10);
        const y = parseInt(ys, 10);
        for (const [nx, ny] of [[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]]) {
            const nk = `${nx},${ny}`;
            if (seen.has(nk)) continue;
            const v = map[nk];
            const same = target === undefined ? v === undefined : v === target;
            if (!same) continue;
            seen.add(nk);
            q.push(nk);
        }
    }
    return n;
}

/** 洪水清除（橡皮擦油漆桶：删相连同值区域） */
function floodErase(state, startKey) {
    const map = layerMap(state);
    if (map[startKey] === undefined) return 0;
    const target = map[startKey];
    const q = [startKey];
    const seen = new Set([startKey]);
    let n = 0;
    while (q.length) {
        const key = q.shift();
        delete map[key];
        n++;
        const [xs, ys] = key.split(',');
        const x = parseInt(xs, 10);
        const y = parseInt(ys, 10);
        for (const [nx, ny] of [[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]]) {
            const nk = `${nx},${ny}`;
            if (seen.has(nk) || map[nk] !== target) continue;
            seen.add(nk);
            q.push(nk);
        }
    }
    return n;
}

function findPaletteTile(state, tileKey, layer) {
    return state.tiles.find((t) => t.tileKey === tileKey && t.layer === layer) || null;
}

/** Ground 瓦片中文名 */
function groundTileLabel(tileKey) {
    if (tileKey === 'JumpBlock') return '跳跃砖(JumpBlock)';
    return '可移动砖块(Baseblock)';
}

/** Border 瓦片中文名 */
function borderTileLabel(tileKey) {
    const s = tileKey === true || tileKey === 1 ? 'WallBlock' : String(tileKey || 'WallBlock').trim();
    if (!s || s === 'WallBlock') return '墙砖(WallBlock)';
    return `墙饰(${s})`;
}

/**
 * 汇总格子上全部内容（两层瓦片 + 实体），用于状态栏悬停提示。
 * @param {object} state
 * @param {number} x
 * @param {number} y
 * @param {{ kind: string, propPlacement?: string }[]} [spawnHits]
 * @param {Record<string, string>} [spawnKindLabels]
 */
function describeCellContents(state, x, y, spawnHits, spawnKindLabels) {
    const key = `${x},${y}`;
    const parts = [];
    const ground = state.config?.ground?.[key];
    if (ground !== undefined) parts.push(groundTileLabel(ground));
    const border = state.config?.border?.[key];
    if (border !== undefined) parts.push(borderTileLabel(border));
    if (Array.isArray(spawnHits)) {
        for (const h of spawnHits) {
            let label = (spawnKindLabels && spawnKindLabels[h.kind]) || h.kind;
            if (h.kind === 'player') label = '人物';
            if (h.kind === 'prop' && h.propPlacement === 'ground') label = `${label}(空地)`;
            parts.push(label);
        }
    }
    return parts.length ? parts.join(' + ') : '空';
}

module.exports = {
    TOOLS,
    TOOL_LABELS,
    TOOL_CURSORS,
    layerMap,
    getCell,
    hasCell,
    removeCell,
    setCell,
    canPaintBrush,
    fillRectangle,
    eraseRectangle,
    floodFill,
    floodErase,
    findPaletteTile,
    groundTileLabel,
    borderTileLabel,
    describeCellContents,
};
