import logging
from datetime import datetime
from typing import List

from maps_adv.stat_tasks_starter.lib.charger.events_saver.events_point import (
    EventsPoint,
)

logger = logging.getLogger(__name__)


class EventsSaver:
    def __init__(self, db_config: dict):
        self.event_point = EventsPoint(**db_config)

    async def __call__(
        self, orders: List[dict], timing_from: datetime, timing_to: datetime
    ) -> None:
        if await self.event_point.check_charging_withing_period(timing_from, timing_to):
            logger.error(
                f"Events already charged in requested period "
                f"({timing_from}, {timing_to})"
            )
            return

        select_sqls = []
        for order in orders:
            if order["billing_success"] is not False:
                for campaign in order["campaigns"]:
                    campaign_select_sqls = self._prepare_selects_for_campaign(
                        campaign, timing_from, timing_to
                    )
                    select_sqls.extend(campaign_select_sqls)

        if select_sqls:
            await self.event_point(select_sqls)

    def _prepare_selects_for_campaign(
        self, campaign: dict, timing_from: datetime, timing_to: datetime
    ) -> List[str]:
        select_sqls = []

        events_to_charge = campaign["events_to_charge"]
        if events_to_charge > 0:
            if campaign["cost_per_event"] != campaign["cost_per_last_event"]:
                events_to_charge -= 1
                sql = self.event_point.prepare_select_events_sql(
                    campaign_id=campaign["campaign_id"],
                    event_cost=campaign["cost_per_last_event"],
                    timing_from=timing_from,
                    timing_to=timing_to,
                    limit=1,
                    limit_offset=events_to_charge,
                )
                select_sqls.append(sql)

            sql = self.event_point.prepare_select_events_sql(
                campaign_id=campaign["campaign_id"],
                event_cost=campaign["cost_per_event"],
                timing_from=timing_from,
                timing_to=timing_to,
                limit=events_to_charge,
                limit_offset=0,
            )
            select_sqls.append(sql)

        return select_sqls
