"""Functions for working with worlds."""

from __future__ import annotations
from random import Random
from typing import Final

from tcod.ecs import Registry, Entity
from tcod.map import Map

import g

from game.components import Action, Gold, Graphic, Position
from game.tags import IsActor, IsItem, IsPlayer

world_center: Final = Position(50, 50)

def world_pos_to_map_pos(pos):
    return pos+world_center

def map_pos_to_world_pos(pos):
    return pos-world_center

def add_wall(world, pos, remove=False):
    r_pos = world_pos_to_map_pos(pos)
    map = world[None].components[Map]
    map.walkable[r_pos.y][r_pos.x] = remove
    map.transparent[r_pos.y][r_pos.x] = remove

def add_door(world, pos):
    world.new_entity(
        components={
            Position: pos,
            Graphic: Graphic(ord('\\')),
            Action: unlock_door
        }
    )
    add_wall(world, pos)


def new_world() -> Registry:
    """Return a freshly generated world."""
    world = Registry()

    map = world[None].components[Map] = Map(100, 100)
    map.walkable[:] = True
    map.transparent[:] = True

    rng = world[None].components[Random] = Random()
    player_pos = Position(5,5)
    world.new_entity(
        components={
            Position: player_pos,
            Graphic: Graphic(ch=ord('@'), fg=(255, 0, 0)),
            Gold: 0
        },
        tags=[IsActor, IsPlayer]
    )
    # player = world[object()] # <- das hier ist das gleiche wie das world.new_entity darüber
    # player.components[Position] = Position(5, 5)
    # player.components[Graphic] = Graphic(ord("@"))
    # player.components[Gold] = 0
    # player.tags |= {IsPlayer, IsActor}

    for _ in range(10):
        world.new_entity(
            components={
                Position: Position(rng.randint(0, 20), rng.randint(0, 20)),
                Graphic: Graphic(ord("$"), fg=(255, 255, 0)),
                Gold: rng.randint(1, 10)
            },
            tags=[IsItem]
        )

    for i in range(20):
        if i == 5 or i == 9:
            add_door(world, Position(10,i))
        else:
            add_wall(world, Position(10, i))

    cam_pos = world_pos_to_map_pos(player_pos)
    map.compute_fov(cam_pos.x, cam_pos.y)
    return world


def unlock_door(door: Entity):
    door.components[Graphic] = Graphic(ord("_"))
    door.tags.clear()
    add_wall(g.world, door.components[Position], remove=True)
