import os
import re
import json
from entities import Player
from engine import router
from world import get_room, set_job_items, STARTING_ROOM


def main():
    cls()

    job = get_job(input("HP or BOFH? ").lower().strip())

    player = create_player(job)

    if player.job != "unemployed":
        set_job_items(job)

    starting_id = STARTING_ROOM

    print(game(starting_id, player))


def get_job(job):
    valid_jobs = ["hp", "bofh"]
    if job in valid_jobs:
        return job
    else:
        return None


def create_player(job):
    if job == "hp":
        return Player("hp", 3, 3)
    elif job == "bofh":
        return Player("bofh", 2, 2)
    else:
        return Player("unemployed")


def game(starting_id, player):
    if player.job == "unemployed":
        return (end(player, "fail"))
    id = starting_id
    while True:
        if (check_end(id, player)):  # checks win condition
            return (end((player), check_end(id, player)))  # returns ending string
        print(f"{get_room(id)}\n{available(id)}")
        tokens = parse(input("What do you do? "))
        cls()
        id = router(player, id, tokens)


def parse(action):  # tokenizes input sentence
    allowed_commands = ["help", "status", "go", "take", "look", "use", "press", "attack", "lart"]
    reg_commands = "|".join(allowed_commands)

    if words := re.search(r"^({commands})(\s*)(.*)".format(commands=reg_commands), action.lower().strip()):
        return words.groups()


def check_end(id, player):
    if player.hit_points <= 0:
        return "fail"
    elif id == "6":
        return "standard_win"
    elif id == "0":
        return "full_win"
    else:
        return False


def end(player, win):
    with open("scores.json", "r") as scores:
        scores_data = json.load(scores)

    ending = "\n".join(scores_data[player.job][win][get_tier(player.score)])
    if win == "fail":
        ending = f"{ending}\nYOU FAILED!"
    elif win == "standard_win":
        ending = f"{ending}\nVICTORY ACHIEVED!"
    else:
        ending = f"{ending}\nFULL VICTORY ACHIEVED!"
        
    input("Your adventure ends!\nPress enter to continue.")

    cls()
    return ending


def get_tier(score):# used to get ending string
    if score == 0:
        return "0"
    elif score == 1:
        return "1"
    elif score < 5:
        return "2"
    elif score < 10:
        return "3"
    elif score < 15:
        return "4"
    else:
        return "5"


def available(id):  # adds avaliable directions each cycle
    room = get_room(id)
    open_directions = list()
    closed_directions = list()
    for direction in get_room(id).routes:
        if hasattr(get_room(room.routes[direction]), "lock"):
            closed_directions.append(direction)
        else:
            open_directions.append(direction)

    open_str = ", ".join(open_directions)
    closed_str = ", ".join(closed_directions)

    return_str = ""

    if open_str:
        return_str += f"\nYou can go to: {', '.join(open_directions)}."

    if closed_str:
        return_str += f"\nLocked: {', '.join(closed_directions)}."

    return return_str


def cls():
    os.system('cls' if os.name == 'nt' else 'clear')


if __name__ == "__main__":
    main()
