"""Collection of common components."""

from __future__ import annotations

from typing import Final, Self, Callable

import attrs
import math
import tcod.ecs.callbacks
from tcod.ecs import Entity


@attrs.define(frozen=True)
class Position:
    """An entities position."""

    x: int
    y: int

    def __add__(self, direction: tuple[int, int] | Position) -> Self:
        """Add a vector to this position."""
        match direction:
            case Position(x, y):
                return self.__class__(self.x + x, self.y + y)
            case (x, y):
                return self.__class__(self.x + x, self.y + y)
        raise NotImplementedError

    def __sub__(self, direction: tuple[int, int] | Position) -> Self:
        match direction:
            case Position(x, y):
                return self.__class__(self.x - x, self.y - y)
            case (x, y):
                return self.__class__(self.x - x, self.y - y)
        raise NotImplementedError

    def mod(self, other: tuple[int,int] | Position | int) -> Self:
        match other:
            case Position(x,y):
                return self.__class__(self.x//x, self.y//y)
            case int(x):
                return self.__class__(self.x//x, self.y//x)
            case (x, y):
                return self.__class__(self.x//x, self.y//y)
        raise NotImplementedError

    def length(self):
        return math.sqrt(self.x**2+self.y**2)

@tcod.ecs.callbacks.register_component_changed(component=Position)
def on_position_changed(entity: Entity, old: Position | None, new: Position | None) -> None:
    """Mirror position components as a tag."""
    if old == new:
        return
    if old is not None:
        entity.tags.discard(old)
    if new is not None:
        entity.tags.add(new)


@attrs.define(frozen=True)
class Graphic:
    """An entities icon and color."""

    ch: int = ord("!")
    fg: tuple[int, int, int] = (255, 255, 255)

Action: Final = ("Action", Callable[[Entity], None])
"""Possible action."""

Gold: Final = ("Gold", int)
"""Amount of gold."""
