from datetime import datetime
from decimal import Decimal
from typing import List

from maps_adv.stat_tasks_starter.lib.base.exceptions import UnexpectedNaiveDateTime

__select_events_sql_template = """SELECT *, {event_cost}
    FROM {database}.{table}
    WHERE CampaignID={campaign_id}
        AND ReceiveTimestamp BETWEEN {timing_from} AND {timing_to}
        AND EventName = 'geoadv.bb.pin.show'
    ORDER BY ReceiveTimestamp DESC
    LIMIT {limit} OFFSET {limit_offset}
    """


def build_select_events(
    database: str,
    table: str,
    campaign_id: int,
    event_cost: Decimal,
    timing_from: datetime,
    timing_to: datetime,
    limit: int,
    limit_offset: int,
) -> str:
    if not all([timing_from.tzinfo, timing_to.tzinfo]):
        raise UnexpectedNaiveDateTime()

    timing_from = int(timing_from.timestamp())
    timing_to = int(timing_to.timestamp())

    return __select_events_sql_template.format(
        database=database,
        table=table,
        campaign_id=campaign_id,
        event_cost=event_cost,
        timing_from=timing_from,
        timing_to=timing_to,
        limit=limit,
        limit_offset=limit_offset,
    )


__insert_sql_template = "INSERT INTO {database}.{table} {select_sql}"


def build_insert(database: str, table: str, select_sqls: List[str]):
    full_select_sql = " UNION ALL ".join(select_sqls)
    return __insert_sql_template.format(
        database=database, table=table, select_sql=full_select_sql
    )


__existing_charged_events = """
    SELECT CampaignID
    FROM {database}.{charged_table}
    WHERE ReceiveTimestamp BETWEEN {timing_from} AND {timing_to}
    LIMIT 1
"""


def build_existing_charged_events(
    database: str, charged_table: str, timing_from: datetime, timing_to: datetime
) -> str:
    if not all([timing_from.tzinfo, timing_to.tzinfo]):
        raise UnexpectedNaiveDateTime()

    timing_from = int(timing_from.timestamp())
    timing_to = int(timing_to.timestamp())

    return __existing_charged_events.format(
        database=database,
        charged_table=charged_table,
        timing_from=timing_from,
        timing_to=timing_to,
    )
