"""empty message

Revision ID: e12953426813
Revises: ed749e8eb041
Create Date: 2021-12-27 19:20:10.346576

"""
import json
import logging
from datetime import datetime

import pytz
import sqlalchemy as sa
from alembic import op

from maps_adv.billing_proxy.lib.db.migration_helpers import data_migration


# revision identifiers, used by Alembic.
revision = 'e12953426813'
down_revision = 'ed749e8eb041'
branch_labels = None
depends_on = None


_moscow_tz = pytz.timezone("Europe/Moscow")

active_from = _moscow_tz.localize(datetime(2021, 12, 31, 23, 59, 59))
active_to = _moscow_tz.localize(datetime(2022, 12, 31, 23, 59, 59))

comment = "Геомедийные продукты 2022 Оферта; https://st.yandex-team.ru/GEODISPLAY-696"

products_data = [
    {
        "oracle_id": 511764,
        "title": "Геомедийная реклама. Пины по маршруту.",
        "billing_type": "CPM",
        "billing_data": {"base_cpm": "80"},
        "currency": "RUB",
        "platforms": ["NAVI", "MAPS"],
        "campaign_type": "PIN_ON_ROUTE",
        "cpm_filters": [
            "rubric_name_common_v2",
            "targeting_type_cascade_with_audience",
        ],
        "service_id": 37,
        "min_budget": 17500,
    },

    {
        "oracle_id": 511765,
        "title": "Билборды по маршруту",
        "billing_type": "CPM",
        "billing_data": {"base_cpm": "50"},
        "currency": "RUB",
        "platforms": ["NAVI"],
        "campaign_type": "BILLBOARD",
        "cpm_filters": [
            "rubric_name_common_v2",
            "targeting_type_cascade_with_audience",
        ],
        "service_id": 37,
        "min_budget": 100000,
    },

    {
        "oracle_id": 511767,
        "title": "Геомедийная реклама. Баннер",
        "billing_type": "CPM",
        "billing_data": {"base_cpm": "220"},
        "currency": "RUB",
        "platforms": ["NAVI"],
        "campaign_type": "ZERO_SPEED_BANNER",
        "cpm_filters": [
            "creative_presence_audio_banner",
            "targeting_type_cascade_with_audience",
        ],
        "service_id": 37,
        "min_budget": 17500,
    },

    {
        "oracle_id": 511766,
        "title": "Баннер при построении маршрута",
        "billing_type": "CPM",
        "billing_data": {"base_cpm": "230"},
        "currency": "RUB",
        "platforms": ["NAVI"],
        "campaign_type": "OVERVIEW_BANNER",
        "cpm_filters": [
            "targeting_type_cascade_with_audience",
        ],
        "service_id": 37,
        "min_budget": 17500,
    },
]


@data_migration
def upgrade():
    con = op.get_bind()

    product_oracle_ids = set(
        product_data["oracle_id"] for product_data in products_data
    )
    existing_products = []
    new_products = []
    for product_data in products_data:
        for platform in product_data["platforms"]:
            result = con.execute(
                sa.text(
                    """
                        SELECT id
                        FROM products
                        WHERE oracle_id = :oracle_id and platform = :platform
                """
                ),
                oracle_id=product_data["oracle_id"],
                platform=platform,
            ).fetchone()

            if result is not None:
                existing_products.append(
                    {"oracle_id": product_data["oracle_id"], "platfrom": platform}
                )
            else:
                new_products.append(
                    {"oracle_id": product_data["oracle_id"], "platfrom": platform}
                )

    # Update existing
    for product_data in products_data:
        for platform in product_data["platforms"]:
            if {
                "oracle_id": product_data["oracle_id"],
                "platfrom": platform,
            } in existing_products:
                con.execute(
                    sa.text(
                        """
                        WITH product_rules AS (
                            SELECT product_rules_versions.*
                            FROM product_rules_versions
                            INNER JOIN (
                                SELECT product_id, max(version) AS version
                                FROM product_rules_versions
                                WHERE product_id IN (
                                    SELECT id FROM products WHERE oracle_id = :oracle_id
                                )
                                GROUP BY product_id) AS product_rules_versions_subq
                            ON product_rules_versions_subq.product_id = product_rules_versions.product_id
                            AND product_rules_versions_subq.version = product_rules_versions.version
                            WHERE :active_from <= coalesce(product_rules_versions.active_to, now())
                            AND :active_from > active_from
                        ),
                        updating AS (
                            UPDATE product_rules_versions
                            SET active_to = :active_from
                            FROM product_rules
                            WHERE product_rules.id = product_rules_versions.id
                        )
                        INSERT INTO product_rules_versions(
                            product_id,
                            version,
                            active_from,
                            active_to,
                            billing_data,
                            min_budget,
                            cpm_filters)
                            SELECT product_id,
                            version + 1 AS version,
                            :active_from,
                            :active_to,
                            :billing_data,
                            :min_budget,
                            :cpm_filters
                        FROM product_rules
                    """  # noqa: E501
                    ),
                    oracle_id=product_data["oracle_id"],
                    active_from=active_from,
                    active_to=active_to,
                    billing_data=json.dumps(product_data["billing_data"]),
                    min_budget=product_data["min_budget"],
                    cpm_filters=product_data["cpm_filters"],
                )
            elif {
                "oracle_id": product_data["oracle_id"],
                "platfrom": platform,
            } in new_products:
                con.execute(
                    sa.text(
                        """
                        WITH
                            inserted_product AS (
                                INSERT INTO products (
                                    oracle_id,
                                    title,
                                    act_text,
                                    description,
                                    currency,
                                    billing_type,
                                    vat_value,
                                    campaign_type,
                                    platform,
                                    comment,
                                    available_for_agencies,
                                    available_for_internal,
                                    platforms,
                                    service_id
                                )
                                VALUES (
                                    :oracle_id,
                                    :title,
                                    :act_text,
                                    :description,
                                    :currency,
                                    :billing_type,
                                    :vat,
                                    :campaign_type,
                                    :platform,
                                    :comment,
                                    TRUE,
                                    TRUE,
                                    (:platforms)::platformtype[],
                                    :service_id
                                )
                                RETURNING id
                            ),
                            inserted_version AS (
                                INSERT INTO product_rules_versions (
                                    product_id,
                                    version,
                                    active_from,
                                    active_to,
                                    billing_data,
                                    min_budget,
                                    cpm_filters
                                )
                                SELECT id,
                                       1,
                                       :active_from,
                                       :active_to,
                                       :billing_data,
                                       :min_budget,
                                       :cpm_filters
                                FROM inserted_product
                            )
                        SELECT 1
                        """  # noqa: E501
                    ),
                    comment=comment,  # noqa: E501
                    currency=product_data["currency"],
                    vat=0.2,
                    oracle_id=product_data["oracle_id"],
                    title=product_data["title"],
                    act_text=product_data["title"],
                    description="{} {}".format(
                        product_data["oracle_id"], product_data["title"]
                    ),
                    billing_type=product_data["billing_type"],
                    campaign_type=product_data["campaign_type"],
                    platform=platform,
                    platforms=[platform],
                    active_from=active_from,
                    active_to=active_to,
                    billing_data=json.dumps(product_data["billing_data"]),
                    cpm_filters=product_data["cpm_filters"],
                    min_budget=product_data["min_budget"],
                    service_id=product_data["service_id"],
                )


def downgrade():
    pass
