from decimal import Decimal

from .base import BaseCpmFilter, CpmUndefined, CpmData


class ValuesMapCpmFilter(BaseCpmFilter):
    """
    Chooses cpm value from passed map by passed value
    Typically map is expected to be stored in product_version.billing_data
    and value comes from campaign, orders, etc.
    """

    def __init__(self, values_map_key: str, value_key: str, **settings):
        super().__init__(**settings)
        self._values_map_key = values_map_key
        self._data_key = value_key

    def __call__(self, **kwargs) -> CpmData:
        try:
            values = kwargs[self._values_map_key]
        except KeyError:
            raise CpmUndefined(f"No values map passed by key '{self._values_map_key}'")

        try:
            value = kwargs[self._data_key]
        except KeyError:
            raise CpmUndefined(f"No value passed by key '{self._data_key}'")

        try:
            cpm = values[value]
        except KeyError:
            raise CpmUndefined(f"No cpm defined in product for value {value}")

        return CpmData(base_cpm=Decimal(cpm))


cpm_filters = {
    "try_order_size_2020": ValuesMapCpmFilter(
        values_map_key="cpm_values", value_key="order_size"
    )
}
