from datetime import datetime

from maps_adv.adv_store.api.schemas import (
    CampaignDataSchema,
    CampaignForBudgetAnalysisListSchema,
    CampaignForChargerCpaListSchema,
    CampaignForChargerListSchema,
    CampaignForChargerFixListSchema,
    CampaignForExportListSchema,
    CampaignListSchema,
    CampaignSchema,
    CampaignStatusChangeInputSchema,
    CampaignPaidTillChangeInputSchema,
    CampaignsToStopListSchema,
    DailyBudgetPredictionInputSchema,
    DailyBudgetPredictionOutputSchema,
    OrderInputSchema,
    OrderSummaryListSchema,
    ShortCampaignListSchema,
    UsedSegmentsOutputSchema,
)
from maps_adv.adv_store.api.schemas.campaigns import (
    CampaignDataForMonitoringsListSchema,
    CampaignIdListSchema,
)
from maps_adv.adv_store.v2.lib.domains import CampaignsDomain

from .base import with_schemas


class CampaignsApiProvider:
    _domain: CampaignsDomain

    def __init__(self, domain: CampaignsDomain):
        self._domain = domain

    @with_schemas(CampaignDataSchema, CampaignSchema)
    async def create_campaign(self, **kwargs) -> dict:
        return await self._domain.create_campaign(**kwargs)

    @with_schemas(output_schema=CampaignSchema)
    async def retrieve_campaign(self, campaign_id: int) -> dict:
        return await self._domain.retrieve_campaign(campaign_id)

    @with_schemas(input_schema=CampaignDataSchema, output_schema=CampaignSchema)
    async def update_campaign(self, campaign_id: int, **kwargs) -> dict:
        # FIXME: where should it go?
        kwargs.pop("campaign_type")
        kwargs.pop("created_datetime", None)
        return await self._domain.update_campaign(campaign_id, **kwargs)

    @with_schemas(input_schema=CampaignStatusChangeInputSchema)
    async def set_status(self, campaign_id: int, **kwargs) -> None:
        return await self._domain.set_status(campaign_id=campaign_id, **kwargs)

    @with_schemas(input_schema=CampaignPaidTillChangeInputSchema)
    async def set_paid_till(self, campaign_id: int, **kwargs) -> None:
        return await self._domain.set_paid_till(campaign_id=campaign_id, **kwargs)

    @with_schemas(OrderInputSchema, ShortCampaignListSchema)
    async def list_short_campaigns(self, **kwargs) -> dict:
        got = await self._domain.list_short_campaigns(**kwargs)
        return {"campaigns": got}

    @with_schemas(OrderInputSchema, CampaignListSchema)
    async def list_campaigns_by_orders(self, **kwargs) -> dict:
        got = await self._domain.list_campaigns_by_orders(**kwargs)
        return {"campaigns": got}

    @with_schemas(OrderInputSchema, OrderSummaryListSchema)
    async def list_campaigns_summary(self, **kwargs) -> dict:
        got = await self._domain.list_campaigns_summary(**kwargs)
        return {"orders": got}

    @with_schemas(output_schema=CampaignForChargerListSchema)
    async def list_campaigns_for_charger(self, active_at: datetime) -> dict:
        got = await self._domain.list_campaigns_for_charger(active_at=active_at)
        return {"campaigns": got}

    @with_schemas(output_schema=CampaignForChargerCpaListSchema)
    async def list_campaigns_for_charger_cpa(self, active_at: datetime) -> dict:
        got = await self._domain.list_campaigns_for_charger_cpa(active_at=active_at)
        return {"campaigns": got}

    @with_schemas(output_schema=CampaignForChargerFixListSchema)
    async def list_campaigns_for_charger_fix(self, active_at: datetime) -> dict:
        got = await self._domain.list_campaigns_for_charger_fix(active_at=active_at)
        return {"campaigns": got}

    @with_schemas(input_schema=CampaignsToStopListSchema)
    async def stop_campaigns(self, **kwargs) -> None:
        await self._domain.stop_campaigns(**kwargs)

    @with_schemas(output_schema=CampaignForExportListSchema)
    async def list_campaigns_for_export(self) -> dict:
        got = await self._domain.list_campaigns_for_export()
        return {"campaigns": got}

    @with_schemas(DailyBudgetPredictionInputSchema, DailyBudgetPredictionOutputSchema)
    async def predict_daily_budget(self, **kwargs) -> dict:
        got = await self._domain.predict_daily_budget(**kwargs)
        return {"daily_budget": got}

    async def list_used_audiences(self) -> dict:
        got = await self._domain.list_used_audiences()
        return UsedSegmentsOutputSchema().dump({"usedSegmentIds": got}).data

    @with_schemas(output_schema=CampaignForBudgetAnalysisListSchema)
    async def list_campaigns_for_budget_analysis(self) -> dict:
        got = await self._domain.list_campaigns_for_budget_analysis()
        return {"campaigns": got}

    @with_schemas(
        input_schema=CampaignIdListSchema,
        output_schema=CampaignDataForMonitoringsListSchema,
    )
    async def retrieve_campaign_data_for_monitorings(self, **kwargs) -> dict:
        got = await self._domain.retrieve_campaign_data_for_monitorings(**kwargs)
        return {"campaigns": got}
