import { Color, Direction, getOppositeDirection } from './const';
import { drawTextInBox, tick } from './display';
import Input from '@common/input';
import { createItems, getItemsCount } from './item';
import { GameMap } from './map';
import { Player } from './player';
import { getPossibleRoomsCount, getRoom, getRoomsCount } from './room';

let currentRoom = getRoom(0, 0, 0);
const map = new GameMap(currentRoom);
currentRoom.draw();
const player = new Player(currentRoom.x + currentRoom.width / 2, currentRoom.y + currentRoom.height / 2);

let lastMove = Date.now();
function handleInput() {
    const isSpacePressed = Input.isPressed(Input.KeyCode.SPACE);

    if (Date.now() - lastMove < 75 && !Input.isHeld(Input.KeyCode.SHIFT) && !isSpacePressed) return;
    lastMove = Date.now();
    let newX = player.x;
    let newY = player.y;
    let moved = isSpacePressed;

    if (Input.isHeld(Input.KeyCode.UP)) {
        newY--;
        moved = true;
    }

    if (Input.isHeld(Input.KeyCode.DOWN)) {
        newY++;
        moved = true;
    }

    if (Input.isHeld(Input.KeyCode.LEFT)) {
        newX--;
        moved = true;
    }

    if (Input.isHeld(Input.KeyCode.RIGHT)) {
        newX++;
        moved = true;
    }

    if (moved) {
        const activatedDoor = currentRoom.getActivatedDoor(newX, newY);
        if (activatedDoor) {
            const shouldTravel = ![Direction.UP, Direction.DOWN].includes(activatedDoor.direction) || isSpacePressed;

            if (shouldTravel) {
                currentRoom = getRoom(activatedDoor.worldX, activatedDoor.worldY, activatedDoor.worldZ);
                currentRoom.invalidate();
                map.currentRoom = currentRoom;
                map.invalidate();
                player.skipNextBackgroundRestore = true;
                const oppositeDoor = currentRoom.doors[getOppositeDirection(activatedDoor.direction)];

                if (oppositeDoor) {
                    switch (activatedDoor.direction) {
                        case Direction.NORTH:
                            newX = oppositeDoor.x + 1;
                            newY = oppositeDoor.y - 1;
                            break;
                        case Direction.SOUTH:
                            newX = oppositeDoor.x + 1;
                            newY = oppositeDoor.y + 1;
                            break;
                        case Direction.EAST:
                            newX = oppositeDoor.x + 1;
                            newY = oppositeDoor.y + 1;
                            break;
                        case Direction.WEST:
                            newX = oppositeDoor.x - 1;
                            newY = oppositeDoor.y + 1;
                            break;
                        case Direction.UP:
                        case Direction.DOWN:
                            newX = oppositeDoor.x;
                            newY = oppositeDoor.y;
                            break;
                    }
                } else {
                    newX = currentRoom.x + currentRoom.width / 2;
                    newY = currentRoom.y + currentRoom.height / 2;
                }
            }
        } else {
            if (newX < currentRoom.x + 1 || newX >= currentRoom.x + currentRoom.width + 1) {
                newX = player.x;
            }
            if (newY < currentRoom.y + 1 || newY >= currentRoom.y + currentRoom.height + 1) {
                newY = player.y;
            }
        }

        const pickedItem = currentRoom.pickItem(newX, newY);
        if (pickedItem) {
            player.addItem(pickedItem);
        }

        player.x = newX;
        player.y = newY;
        player.invalidate();
    }
}

function handleLogic() {

}

function drawInfo() {
    const coords = `${currentRoom.worldX},${currentRoom.worldY},${currentRoom.worldZ}`.padStart(9);
    const foundRooms = getRoomsCount();
    const totalRooms = getPossibleRoomsCount();
    const rooms = `${foundRooms}/${totalRooms}${foundRooms === totalRooms ? '' : '+'}`.padStart(coords.length - 2);
    const items = `${player.foundItems}/${getItemsCount()}`.padStart(coords.length - 2);
    drawTextInBox(0, 0, `Pos: ${coords}\nRooms: ${rooms}\nItems: ${items}`, { fg: Color.YELLOW, title: 'Info' });
}

function draw() {
    currentRoom.draw();
    map.draw();
    player.draw();

    drawInfo();
}

export async function main() {
    createItems();
    currentRoom.invalidate();
    player.invalidate();
    drawTextInBox(8, 11, 'Use arrow keys to move\nSHIFT to run\nSPACE to activate\nAWOO!', { fg: Color.CYAN });

    while (true) {
        Input.updateKeys();
        handleInput();
        handleLogic();
        draw();

        await tick(60);
    }
}
