import logging
from operator import itemgetter

from maps_adv.export.lib.core.enum import CampaignType, CreativeType

logger = logging.getLogger(__name__)


class CampaignWithoutPlacesFilter:
    @classmethod
    def _check_campaign_without_organizations(cls, campaign: dict) -> bool:
        creatives = campaign["creatives"]
        return bool(
            (
                campaign["campaign_type"]
                in {CampaignType.PIN_ON_ROUTE, CampaignType.ROUTE_VIA_POINT}
                and not campaign["placing"]["organizations"]
            )
            or (
                campaign["campaign_type"] == CampaignType.PIN_SEARCH
                and (
                    CreativeType.PIN_SEARCH not in creatives
                    or not any(
                        [c["organizations"] for c in creatives[CreativeType.PIN_SEARCH]]
                    )
                )
            )
            or (
                campaign["campaign_type"] == CampaignType.CATEGORY
                and (
                    CreativeType.ICON not in creatives
                    or not creatives[CreativeType.ICON]["organizations"]
                )
            )
        )

    @classmethod
    def _check_campaign_without_places(cls, campaign: dict) -> bool:
        return bool(
            (
                campaign["campaign_type"] in (CampaignType.BILLBOARD,)
                and not campaign["places"]
            )
        )

    async def __call__(self, campaigns: list) -> list:
        result_campaigns = []
        campaigns_to_notify = []

        for campaign in campaigns:
            is_without_adv_places = bool(
                self._check_campaign_without_organizations(campaign)
                or self._check_campaign_without_places(campaign)
            )

            if not is_without_adv_places:
                result_campaigns.append(campaign)
            else:
                campaigns_to_notify.append(campaign)

        # TODO вернуть когда реализуем notifier
        # if campaigns_to_notify and self._notify:
        #     await self._notify(campaigns_to_notify)

        # GEODISPLAY-1438 TODO вернуть репорт взамен sentry
        if campaigns_to_notify:
            logger.error(
                "Found campaigns without organizations: {}".format(
                    sorted(map(itemgetter("id"), campaigns_to_notify))
                )
            )

        return result_campaigns
