from typing import List, Optional

from maps_adv.adv_store.v2.lib.data_managers.campaigns import BaseCampaignsDataManager
from maps_adv.adv_store.v2.lib.data_managers.events import BaseEventsDataManager
from maps_adv.adv_store.v2.lib.domains.campaigns import CampaignsNotFound


class EventsDomain:
    __slots__ = ("_dm", "_campaign_dm")

    _dm: BaseEventsDataManager
    _campaign_dm: BaseCampaignsDataManager

    def __init__(
        self, dm: BaseEventsDataManager, campaign_dm: BaseCampaignsDataManager
    ):
        self._dm = dm
        self._campaign_dm = campaign_dm

    async def retrieve_campaigns_events_by_orders(
        self,
        order_ids: Optional[List[int]] = None,
        manul_order_ids: Optional[List[int]] = None,
        time_range: Optional[dict] = None,
        starting_event_id: Optional[int] = None,
        limit: Optional[int] = 20,
    ) -> List[dict]:
        time_range = time_range or {}

        return await self._dm.retrieve_campaigns_events_by_orders(
            order_ids,
            manul_order_ids,
            time_range.get("from_timestamp"),
            time_range.get("to_timestamp"),
            starting_event_id,
            limit,
        )

    async def create_campaign_events(self, events: List[dict]) -> None:

        campaign_ids = set(map(lambda event: event["campaign_id"], events))
        existing_campaigns = set(
            await self._campaign_dm.retrieve_existing_campaign_ids(campaign_ids)
        )

        if campaign_ids != existing_campaigns:
            diff = campaign_ids.difference(existing_campaigns)
            raise CampaignsNotFound(diff)

        for event_data in events:
            await self._dm.create_event(
                timestamp=event_data["timestamp"],
                campaign_id=event_data["campaign_id"],
                event_type=event_data["event_type"],
                event_data={},
            )
