
import { DungeonGenerator } from '../dungeon/DungeonGenerator.js';
import { TurnManager } from './TurnManager.js';
import { GAME_PHASES } from './GameConstants.js';
import { Entity } from './Entity.js';

export class GameEngine {
    constructor() {
        this.dungeon = new DungeonGenerator();
        this.turnManager = new TurnManager();
        this.missionConfig = null;

        this.player = null;

        this.selectedPath = [];
        this.selectedEntityId = null;

        // Simple event callbacks (external systems can assign these)
        this.onPathChange = null; // (path) => {}
        this.onEntityUpdate = null; // (entity) => {}
        this.onEntityMove = null; // (entity, path) => {}
        this.onEntitySelect = null; // (entityId, isSelected) => {}

        this.setupEventHooks();
    }

    setupEventHooks() {
        this.turnManager.on('phase_changed', (phase) => this.handlePhaseChange(phase));
    }

    startMission(missionConfig) {
        this.missionConfig = missionConfig;
        console.log(`[GameEngine] Starting mission: ${missionConfig.name}`);

        // 1. Initialize Dungeon (Places the first room)
        this.dungeon.startDungeon(missionConfig);

        // 2. Initialize Player
        // Find a valid starting spot (first occupied cell)
        const startingSpot = this.dungeon.grid.occupiedCells.keys().next().value;
        const [startX, startY] = startingSpot ? startingSpot.split(',').map(Number) : [0, 0];

        console.log(`[GameEngine] Spawning player at valid spot: ${startX}, ${startY}`);
        this.player = new Entity('p1', 'Barbaro', 'hero', startX, startY, '/assets/images/dungeon1/standees/barbaro.png');
        if (this.onEntityUpdate) this.onEntityUpdate(this.player);

        // 3. Start the Turn Sequence
        this.turnManager.startGame();
    }

    update(deltaTime) {
        // Continuous logic
    }

    handlePhaseChange(phase) {
        console.log(`[GameEngine] Phase Changed to: ${phase}`);
    }

    // --- Interaction ---
    onCellClick(x, y) {
        if (this.turnManager.currentPhase !== GAME_PHASES.HERO) return;

        console.log(`Cell Click: ${x},${y}`);

        // 1. Selector Check (Click on Player?)
        if (this.player.x === x && this.player.y === y) {
            if (this.selectedEntityId === this.player.id) {
                // Deselect
                this.selectedEntityId = null;
                console.log("Player Deselected");
                if (this.onEntitySelect) this.onEntitySelect(this.player.id, false);

                // Clear path too
                this.selectedPath = [];
                this._notifyPath();
            } else {
                // Select
                this.selectedEntityId = this.player.id;
                console.log("Player Selected");
                if (this.onEntitySelect) this.onEntitySelect(this.player.id, true);
            }
            return;
        }

        // If nothing selected, ignore floor clicks
        if (!this.selectedEntityId) return;

        // 2. Check if valid Floor (Occupied Cell)
        if (!this.dungeon.grid.occupiedCells.has(`${x},${y}`)) {
            console.log("Invalid cell: Void");
            return;
        }

        // 3. Logic: Path Building (Only if Selected)

        // A. If clicking on last selected -> Deselect (Remove last step)
        if (this.selectedPath.length > 0) {
            const last = this.selectedPath[this.selectedPath.length - 1];
            if (last.x === x && last.y === y) {
                this.selectedPath.pop();
                this._notifyPath();
                return;
            }
        }

        // B. Determine Previous Point (Player or Last Path Node)
        let prevX = this.player.x;
        let prevY = this.player.y;

        if (this.selectedPath.length > 0) {
            const last = this.selectedPath[this.selectedPath.length - 1];
            prevX = last.x;
            prevY = last.y;
        }

        // Note: Manhattan distance 1 = Adjacency (No diagonals)
        const dist = Math.abs(x - prevX) + Math.abs(y - prevY);

        if (dist === 1) {
            // Check Path Length Limit (Speed)
            if (this.selectedPath.length < this.player.stats.move) {
                this.selectedPath.push({ x, y });
                this._notifyPath();
            } else {
                console.log("Max movement reached");
            }
        } else {
            // Restart path if clicking adjacent to player
            const distFromPlayer = Math.abs(x - this.player.x) + Math.abs(y - this.player.y);
            if (distFromPlayer === 1) {
                this.selectedPath = [{ x, y }];
                this._notifyPath();
            }
        }
    }

    onCellRightClick(x, y) {
        if (this.turnManager.currentPhase !== GAME_PHASES.HERO) return;
        if (!this.selectedEntityId) return; // Must satisfy selection rule

        // Must be clicking the last tile of the path to confirm
        if (this.selectedPath.length === 0) return;

        const last = this.selectedPath[this.selectedPath.length - 1];
        if (last.x === x && last.y === y) {
            console.log("Confirming Move...");
            this.confirmMove();
        }
    }

    confirmMove() {
        if (this.selectedPath.length === 0) return;

        const target = this.selectedPath[this.selectedPath.length - 1];
        const pathCopy = [...this.selectedPath];

        // 1. Trigger Animation Sequence
        if (this.onEntityMove) this.onEntityMove(this.player, pathCopy);

        // 2. Update Logical Position
        this.player.setPosition(target.x, target.y);

        // 3. Cleanup
        this.selectedPath = [];
        this._notifyPath();

        // Note: Exploration is now manual via door interaction
    }

    _notifyPath() {
        if (this.onPathChange) this.onPathChange(this.selectedPath);
    }

    exploreExit(exitCell) {
        console.log('[GameEngine] Exploring exit:', exitCell);

        // Find this exit in pendingExits
        const exit = this.dungeon.pendingExits.find(ex => ex.x === exitCell.x && ex.y === exitCell.y);

        if (exit) {
            // Prioritize this exit
            const idx = this.dungeon.pendingExits.indexOf(exit);
            if (idx > -1) {
                this.dungeon.pendingExits.splice(idx, 1);
                this.dungeon.pendingExits.unshift(exit);
            }

            // Trigger exploration
            this.turnManager.triggerExploration();
            this.dungeon.step();
            this.turnManager.setPhase(GAME_PHASES.HERO);
        } else {
            console.warn('[GameEngine] Exit not found in pendingExits');
        }
    }
}
