from pathlib import Path
from typing import Sequence, Tuple

from jinja2 import Environment, FileSystemLoader

file_loader = FileSystemLoader(Path(__file__).parent)
env = Environment(loader=file_loader)
level_template = env.get_template("level.svg")


to_render = dict(
    worse_returns_f000_l153="""
##########
######   #
#######. #
####.    #
####  #  #
## ## #.##
#.  $$$$ #
#   # @ ##
# ########
##########
""".strip(),
    better_returns_f000_l053="""
##########
##########
##########
#######  #
######## #
#   ###.@#
#   $ $$ #
#. #.$   #
#     . ##
##########
""".strip(),
    solve_unsolved_f000_l018="""
##########
##########
##########
##########
######## #
#. ##### #
#    ###.#
#$$ ### $#
#@$ . .  #
##########
""".strip(),
    hard_illustration="""
##########
# $   .. #
#  $ # $ #
# . #### #
#  ##### #
#   ###  #
## #### .#
##$ ####@#
##       #
##########
""".strip(),
)


def render_level_svg(
    wall_positions: Sequence[Tuple[int, int]],
    box_positions: Sequence[Tuple[int, int]],
    target_positions: Sequence[Tuple[int, int]],
    player_position: Tuple[int, int],
) -> str:
    """Renders the level template with sprites and outputs the resulting SVG markup."""
    output = level_template.render(
        wall_positions=wall_positions,
        box_positions=box_positions,
        target_positions=target_positions,
        player_position=player_position,
    )
    return output


def level_to_svg(level: str, *, level_sz: int = 10) -> str:
    lv_list = level.split("\n")

    wall_pos = []
    box_pos = []
    target_pos = []
    player_pos = (-1, -1)
    assert len(lv_list) == level_sz
    for y in range(level_sz):
        assert len(lv_list[y]) == level_sz
        for x in range(level_sz):
            thing_at_pos = lv_list[y][x]
            if thing_at_pos == "#":
                wall_pos.append((x, y))
            elif thing_at_pos == ".":
                target_pos.append((x, y))
            elif thing_at_pos == "$":
                box_pos.append((x, y))
            elif thing_at_pos == "@":
                player_pos = (x, y)

    return render_level_svg(wall_pos, box_pos, list(sorted(target_pos)), player_pos)


if __name__ == "__main__":
    out_dir = Path(__file__).parent / "case-studies"
    out_dir.mkdir(exist_ok=True)
    for name, level in to_render.items():
        with open(out_dir / f"{name}_full.svg", "w") as f:
            f.write(level_to_svg(level))
