from typing import Type, Tuple, List
from os import path

from ..methods import Methods
from .renderable import Renderable
from .entity import Entity
from .enums import EntityDataKey
from ..extensions import Hitboxed
from ..hitboxes import RecurfaceHitbox


class Room(Renderable.with_extensions(Hitboxed)):
    """
    Concrete class tightly coupled to the World screen, which renders a single room and its occupants.
    Can be subclassed as needed to add further functionality
    """

    def __init__(self, parent: "World", room_id: str):
        super().__init__(parent.game, parent=parent, render_position=(0, 0), priority=0)

        self._room_id = room_id
        self.surface = self._generate_surface()

        self._load_room()

    @property
    def room_id(self) -> str:
        return self._room_id

    def generate_hitboxes(self):
        return [RecurfaceHitbox(self, tags=(), is_inverted=True)]  # TODO: Add relevant tags for Room

    def _generate_surface(self):
        """
        Loads the background image for the room object as a new Surface.
        Assumes a standard location for the image file as dictated below in `background_file_path`
        """

        background_file_path = path.join(
            self.game.config.RESOURCE_FOLDER_PATH,
            self.game.screen.state.registered_get("room_background_file_path", [self._room_id])
        )

        return Methods.load_image(background_file_path)

    def _load_room(self):
        """
        Instantiates all the entities present in the current room.
        Assumes that any custom Entity subclasses listed in the game's state
        have been made available to the game's CustomClassHandler
        """

        curr_room_entities_ids: List[str] = self.game.screen.state.registered_get(
            "room_entities_ids", [self._room_id]
        )

        for entity_id in curr_room_entities_ids:
            entity_data: dict = self.game.screen.state.registered_get("entity", [entity_id])

            entity_class: Type[Entity] = self.game.custom_class_handler.get(entity_data[EntityDataKey.CLASS])
            entity_details: Tuple[list, dict] = (
                entity_data.get(EntityDataKey.ARGS, []),
                entity_data.get(EntityDataKey.KWARGS, {})
            )

            entity_class(self, *entity_details[0], **entity_details[1])
