import TilePropertyHelper, { COLOR_TILES } from './TilePropertyHelper.js';

export default class ButtonBarrierSystem {
    /**
     * @param {Phaser.Scene} scene
     * @param {Phaser.Tilemaps.TilemapLayer} barriersLayer
     */
    constructor(scene, barriersLayer) {
        this._scene = scene;
        this._barriersLayer = barriersLayer;

        this._buttons  = []; // [{ col, row, color }]
        this._barriers = []; // [{ col, row, color }]
        this._activeColor = null;
    }

    /**
     * Scan the barriers layer to build button/barrier registries and set initial
     * collision state. Call once after the layer is created.
     */
    init() {
        const layer = this._barriersLayer;

        layer.forEachTile((tile) => {
            if (tile.index <= 0) return;

            const props = TilePropertyHelper.getPropsByGID(tile.index);

            if (props.button) {
                this._buttons.push({ col: tile.x, row: tile.y, color: props.color });
                if (props.pressed) {
                    this._activeColor = props.color;
                }
            } else if (props.barrier) {
                this._barriers.push({ col: tile.x, row: tile.y, color: props.color });
            }
        });

        this._rebuildCollision();
    }

    /**
     * Press the button at the given tile coordinates.
     * Updates button/barrier tile indices and rebuilds collision.
     * @param {number} col  Tile column
     * @param {number} row  Tile row
     */
    pressButton(col, row) {
        const entry = this._buttons.find(b => b.col === col && b.row === row);
        if (!entry) return;
        if (entry.color === this._activeColor) return; // Already active

        this._activeColor = entry.color;

        // Update all button tiles
        for (const btn of this._buttons) {
            const gids = COLOR_TILES[btn.color];
            const newGID = btn.color === this._activeColor ? gids.btn_on : gids.btn_off;
            this._barriersLayer.putTileAt(newGID, btn.col, btn.row);
        }

        // Update all barrier tiles
        for (const bar of this._barriers) {
            const gids = COLOR_TILES[bar.color];
            const newGID = bar.color === this._activeColor
                ? gids.barrier_open
                : gids.barrier_solid;
            this._barriersLayer.putTileAt(newGID, bar.col, bar.row);
        }

        this._rebuildCollision();
    }

    /**
     * Returns true if the given GID is an unpressed button (a valid press target).
     * @param {number} gid
     */
    isButtonTile(gid) {
        const props = TilePropertyHelper.getPropsByGID(gid);
        return !!(props.button && !props.pressed);
    }

    /**
     * Rebuild which tiles in the barriers layer have active collision.
     * Solid: all unpressed buttons + all non-active-color solid barriers.
     * Passable: active-color barriers + pressed button.
     */
    _rebuildCollision() {
        const solidGIDs = [];

        for (const [color, gids] of Object.entries(COLOR_TILES)) {
            if (color !== this._activeColor) {
                solidGIDs.push(gids.btn_off);
                solidGIDs.push(gids.barrier_solid);
            }
            // Active color's btn_on and barrier_open remain passable (not added)
        }

        // setCollision(indices, collides, recalculate)
        // Passing false to a second call clears existing, then we set only solidGIDs
        this._barriersLayer.setCollision(solidGIDs, true, true);

        // Explicitly remove collision from active-color tiles (in case of leftovers)
        if (this._activeColor) {
            const gids = COLOR_TILES[this._activeColor];
            this._barriersLayer.setCollision(
                [gids.btn_on, gids.barrier_open],
                false,
                true
            );
        }
    }
}
