"""ORM client for an specific inventory in SciNote."""

import logging

from .items import Item
from ..client.api.inventory_column_client import InventoryColumnClient
from ..client.api.inventory_item_client import InventoryItemClient
from ..client.models.inventory_cell import CreateInventoryCell

logger = logging.getLogger(__name__)


class Inventory:
    """ORM client for a specific inventory in SciNote."""

    def __init__(
        self,
        name: str,
        column_client: InventoryColumnClient,
        item_client: InventoryItemClient,
    ):
        self.column_client = column_client
        self.item_client = item_client
        self.name = name
        self.__columns = {}
        self.__item_list = []

    @staticmethod
    def load_columns(func):
        """Load the columns for this inventory."""

        def wrapper(cls, *args, **kwargs):
            if not cls.__columns:
                columns = cls.column_client.get_columns()
                for column in columns:
                    name = column.attributes.name.lower().replace(' ', '_')
                    cls.__columns[name] = column
            return func(cls, *args, **kwargs)

        return wrapper

    @load_columns
    def items(self) -> list[Item]:
        """Get the items for this inventory."""

        # If we've already loaded the items, return them.
        if self.__item_list:
            return self.__item_list

        # We need all of the columns to pass to each item. It would be good
        # to time this out somehow so we get the columns every so often.
        if not self.__columns:
            self.__load_columns()

        items = self.item_client.get_items()
        for item in items:
            self.__item_list.append(
                Item(
                    item.id,
                    item.attributes.name,
                    self.item_client,
                    self.__columns,
                    item.inventory_cells,
                )
            )

        return self.__item_list

    @load_columns
    def columns(self):
        """Get the columns for this inventory."""
        return [column for column in self.__columns.values()]

    @load_columns
    def create_item(self, name: str, **kwargs) -> Item:
        """Create a new item in this inventory."""
        cells = []
        for key, value in kwargs.items():
            if key not in self.__columns:
                raise ValueError(f'Column {key} does not exist in inventory.')

            column = self.__columns[key]
            cells.append(CreateInventoryCell(value=value, column_id=column.id))

        item = self.item_client.create_item(name, cells)

        new_item = Item(
            item.id,
            item.attributes.name,
            self.item_client,
            self.__columns,
            item.inventory_cells,
        )
        self.__item_list.append(new_item)
        return new_item
