# have no budget for fix campaigns,
# so will not JOIN billing_fix table
list_campaigns_by_orders = """
    SELECT
        DISTINCT campaign.id,
        campaign.name,
        campaign.timezone,
        campaign.start_datetime,
        campaign.end_datetime,
        FIRST_VALUE (status_history.status)
            OVER (
                PARTITION BY status_history.campaign_id
                ORDER BY status_history.changed_datetime DESC
            ) as status,
        FIRST_VALUE (status_history.metadata)
            OVER (
                PARTITION BY status_history.campaign_id
                ORDER BY status_history.changed_datetime DESC
            ) as metadata,
        COALESCE(billing_cpa.budget, billing_cpm.budget) as budget,
        campaign.publication_envs as publication_envs,
        campaign.datatesting_expires_at as datatesting_expires_at
    FROM campaign
    JOIN status_history ON campaign.id = status_history.campaign_id
    JOIN campaign_billing ON campaign.billing_id = campaign_billing.id
    LEFT JOIN billing_cpm ON campaign_billing.cpm_id = billing_cpm.id
    LEFT JOIN billing_cpa ON campaign_billing.cpa_id = billing_cpa.id
    WHERE campaign.order_id = ANY($1::bigint[])
        OR campaign.manul_order_id = ANY($2::bigint[])
"""

list_short_campaigns = """
    SELECT id, name, order_id, manul_order_id
    FROM campaign
    WHERE order_id = ANY($1::bigint[])
        OR manul_order_id = ANY($2::bigint[])
    ORDER BY changed_datetime DESC
"""

list_campaigns_summary = """
    SELECT
        order_id,
        manul_order_id,
        COUNT(*) FILTER(WHERE status = 'ACTIVE') AS active,
        COUNT(*) AS total
    FROM campaign
    LEFT JOIN (
        SELECT campaign_id, status, metadata
        FROM status_history
        WHERE (campaign_id, changed_datetime) IN (
            SELECT campaign_id, max(changed_datetime)
            FROM status_history
            GROUP BY campaign_id
        )
    ) AS current_status_subq
        ON campaign.id = current_status_subq.campaign_id
    WHERE
        (order_id = ANY($1) OR manul_order_id = ANY($2))
    GROUP BY order_id, manul_order_id
    ORDER BY order_id, manul_order_id
"""

list_campaigns_for_charger = """
    SELECT
        campaign.id AS campaign_id,
        campaign.order_id,
        campaign.timezone,
        (billing_cpm.cost * coalesce(discounts_subq.cost_multiplier, 1)) AS cost,
        billing_cpm.budget,
        billing_cpm.daily_budget
    FROM campaign
    LEFT JOIN campaign_billing ON campaign.billing_id = campaign_billing.id
    LEFT JOIN billing_cpm ON campaign_billing.cpm_id = billing_cpm.id
    LEFT JOIN (
        SELECT
            campaign_id,
            status,
            changed_datetime
        FROM status_history
        WHERE changed_datetime <= $1
        AND (campaign_id, changed_datetime) IN (
            SELECT campaign_id, max(changed_datetime)
            FROM status_history
            GROUP BY campaign_id
        )
    ) AS status_subq ON campaign.id = status_subq.campaign_id
    LEFT JOIN (
        SELECT DISTINCT ON (campaign_id)
            campaign_id,
            cost_multiplier
        FROM campaign_discounts
        WHERE $1 BETWEEN start_datetime AND end_datetime
        ORDER BY campaign_id, start_datetime, id
    ) AS discounts_subq
        ON campaign.id = discounts_subq.campaign_id
    WHERE billing_cpm.id IS NOT NULL
        AND publication_envs @> ARRAY['PRODUCTION']::publicationenvenum[]
        AND $1 BETWEEN campaign.start_datetime AND campaign.end_datetime
        AND status_subq.status = 'ACTIVE'
    ORDER BY campaign_id
"""  # noqa: E501

list_campaigns_for_charger_cpa = """
    SELECT
        campaign.id AS campaign_id,
        campaign.campaign_type,
        campaign.order_id,
        campaign.timezone,
        (billing_cpa.cost * coalesce(discounts_subq.cost_multiplier, 1)) AS cost,
        billing_cpa.budget,
        billing_cpa.daily_budget
    FROM campaign
    LEFT JOIN campaign_billing ON campaign.billing_id = campaign_billing.id
    LEFT JOIN billing_cpa ON campaign_billing.cpa_id = billing_cpa.id
    LEFT JOIN (
        SELECT
            campaign_id,
            status,
            changed_datetime
        FROM status_history
        WHERE changed_datetime <= $1
        AND (campaign_id, changed_datetime) IN (
            SELECT campaign_id, max(changed_datetime)
            FROM status_history
            GROUP BY campaign_id
        )
    ) AS status_subq ON campaign.id = status_subq.campaign_id
    LEFT JOIN (
        SELECT
            campaign_id,
            cost_multiplier
        FROM campaign_discounts
        WHERE $1 BETWEEN start_datetime AND end_datetime
        ORDER BY campaign_id, start_datetime, id
    ) AS discounts_subq
        ON campaign.id = discounts_subq.campaign_id
    WHERE billing_cpa.id IS NOT NULL
        AND publication_envs @> ARRAY['PRODUCTION']::publicationenvenum[]
        AND $1 BETWEEN campaign.start_datetime AND campaign.end_datetime
        AND status_subq.status = 'ACTIVE'
    ORDER BY campaign_id
"""  # noqa: E501

list_campaigns_for_charger_fix = """
    SELECT
        campaign.id AS campaign_id,
        campaign.order_id,
        campaign.timezone,
        billing_fix.time_interval,
        billing_fix.cost,
        campaign.paid_till
    FROM campaign
    LEFT JOIN campaign_billing ON campaign.billing_id = campaign_billing.id
    LEFT JOIN billing_fix ON campaign_billing.fix_id = billing_fix.id
    LEFT JOIN (
        SELECT
            campaign_id,
            status,
            changed_datetime
        FROM status_history
        WHERE changed_datetime <= $1
        AND (campaign_id, changed_datetime) IN (
            SELECT campaign_id, max(changed_datetime)
            FROM status_history
            GROUP BY campaign_id
        )
    ) AS status_subq ON campaign.id = status_subq.campaign_id
    WHERE billing_fix.id IS NOT NULL
        AND order_id IS NOT NULL
        AND publication_envs @> ARRAY['PRODUCTION']::publicationenvenum[]
        AND $1 BETWEEN campaign.start_datetime AND campaign.end_datetime
        AND status_subq.status = 'ACTIVE'
    ORDER BY campaign_id
"""  # noqa: E501

list_campaigns_for_export = """
    WITH all_campaigns as (
        SELECT campaign.id,
               campaign.campaign_type,
               campaign.platforms,
               campaign.publication_envs,
               campaign.order_id,
               campaign.user_daily_display_limit,
               campaign.user_display_limit,
               campaign.targeting,
               campaign.display_probability,
               campaign.billing_id,
               campaign.datatesting_expires_at,
               campaign.settings,
               week_schedule.interval_count as week_schedule_interval_count,
               current_status_subq.status as current_status,
               campaign.start_datetime,
               campaign.end_datetime,
               campaign.timezone,
               week_schedules.schedules as schedules,
               campaign.paid_till
        FROM campaign
            LEFT JOIN (
                SELECT campaign_id, array_agg(row(start, "end")) as schedules
                FROM campaign_week_schedule
                GROUP BY campaign_id
            ) as week_schedules on week_schedules.campaign_id = campaign.id
            -- Для вычисления в какое кол-во интервалов сейчас пападает кампания в рамках недельного расписания
            LEFT JOIN (
                SELECT campaign_week_schedule.campaign_id,
                       count(campaign_week_schedule.campaign_id) FILTER(
                           WHERE
                                 now() at time zone campaign.timezone >= date_trunc('week', (now() at time zone campaign.timezone)::timestamp) + concat(campaign_week_schedule.start::text, ' minutes')::interval
                             AND now() at time zone campaign.timezone < date_trunc('week', (now() at time zone campaign.timezone)::timestamp) + concat(campaign_week_schedule.end::text, ' minutes')::interval
                       ) as interval_count
                FROM campaign_week_schedule
                    JOIN campaign ON campaign_week_schedule.campaign_id = campaign.id
                GROUP BY campaign_week_schedule.campaign_id
            ) as week_schedule ON week_schedule.campaign_id = campaign.id

            -- Необходимо получить актуальный статус у кампании
            LEFT JOIN (
                SELECT campaign_id, status
                FROM status_history
                WHERE (campaign_id, changed_datetime) IN (
                    SELECT campaign_id, max(changed_datetime)
                    FROM status_history
                    GROUP BY campaign_id
                )
            ) AS current_status_subq ON current_status_subq.campaign_id = campaign.id
    ),
    campaigns_for_export as (
        SELECT campaign.id,
               campaign.campaign_type,
               campaign.platforms,
               array_remove(campaign.publication_envs, 'DATA_TESTING'::publicationenvenum) as publication_envs,
               campaign.order_id,
               campaign.user_daily_display_limit,
               campaign.user_display_limit,
               campaign.targeting,
               campaign.display_probability,
               campaign.billing_id,
               campaign.settings,
               campaign.timezone,
               campaign.start_datetime,
               campaign.end_datetime,
               campaign.schedules,
               campaign.paid_till
        FROM all_campaigns as campaign
        WHERE coalesce(campaign.week_schedule_interval_count, 1) > 0  -- Выбрать кампании которые попали в расписание или же без расписании вообще
                AND campaign.start_datetime <= now()
                AND campaign.end_datetime >= now()
                AND campaign.current_status = 'ACTIVE'
                AND array_remove(campaign.publication_envs, 'DATA_TESTING'::publicationenvenum) <> ARRAY[]::publicationenvenum[]

        UNION ALL

        SELECT campaign.id,
               campaign.campaign_type,
               campaign.platforms,
               ARRAY['DATA_TESTING'::publicationenvenum] AS publication_envs,
               NULL as order_id,
               NULL as user_daily_display_limit,
               NULL as user_display_limit,
               '{}'::jsonb AS targeting,
               NULL as display_probability,
               campaign.billing_id,
               campaign.settings,
               campaign.timezone,
               campaign.start_datetime,
               campaign.end_datetime,
               campaign.schedules,
               campaign.paid_till
        FROM all_campaigns as campaign
        WHERE campaign.datatesting_expires_at IS NOT NULL  -- выбрать кампании которые должны выгрузиться в тест (черновики)
                AND campaign.datatesting_expires_at >= now()
    )

    SELECT campaign.id,
           campaign.campaign_type,
           campaign.platforms,
           campaign.publication_envs,
           campaign.order_id,
           campaign.user_daily_display_limit,
           campaign.user_display_limit,
           campaign.targeting,
           campaign.display_probability,
           campaign.settings,
           coalesce(campaign_placing.data, '{}'::jsonb) as "placing",
           coalesce(campaign_actions.data, '[]'::jsonb) as actions,
           coalesce(campaign_creative.data, '[]'::jsonb) as creatives,
           billing_cpm.cost AS billing_cpm_cost,
           (billing_cpm.cost * COALESCE(campaign_discount.cost_multiplier, 1.0)) as adjusted_cpm_cost,
           (billing_cpa.cost * COALESCE(campaign_discount.cost_multiplier, 1.0)) as adjusted_cpa_cost,
           CEIL(billing_cpm.daily_budget / (billing_cpm.cost * COALESCE(campaign_discount.cost_multiplier, 1.0)) * 1000)::integer AS total_daily_display_limit,
           CEIL(billing_cpa.daily_budget / (billing_cpa.cost * COALESCE(campaign_discount.cost_multiplier, 1.0)))::integer AS total_daily_action_limit,
           campaign.timezone,
           campaign.start_datetime,
           campaign.end_datetime,
           campaign.schedules,
           campaign.paid_till
    FROM campaigns_for_export as campaign
        -- Для эксперемента GEOADVDEV-2493
        LEFT JOIN campaign_billing ON campaign_billing.id = campaign.billing_id
        LEFT JOIN billing_cpm ON billing_cpm.id = campaign_billing.cpm_id
        LEFT JOIN billing_cpa ON billing_cpa.id = campaign_billing.cpa_id

        -- текущая скидка для вычисления количества показов
        LEFT JOIN (
            SELECT campaign_id, cost_multiplier
            FROM campaign_discounts
            WHERE campaign_discounts.start_datetime <= now()
                AND campaign_discounts.end_datetime >= now()
        ) as campaign_discount ON campaign_discount.campaign_id = campaign.id

        -- Строим список действий для кампании
        LEFT JOIN (
            SELECT actions_subq.campaign_id, jsonb_agg(actions_subq.data) as data
            FROM (
                     SELECT action_open_site.campaign_id,
                            jsonb_build_object(
                                    'type_', 'open_site',
                                    'title', action_open_site.title,
                                    'url', action_open_site.url,
                                    'main', action_open_site.main
                            ) as data
                     FROM action_open_site

                     UNION ALL
                     SELECT action_search.campaign_id,
                            jsonb_build_object(
                                    'type_', 'search',
                                    'title', action_search.title,
                                    'organizations', action_search.organizations,
                                    'history_text', action_search.history_text,
                                    'main', action_search.main
                            ) as data
                     FROM action_search

                     UNION ALL
                     SELECT action_phone_call.campaign_id,
                            jsonb_build_object(
                                    'type_', 'phone_call',
                                    'title', action_phone_call.title,
                                    'phone', action_phone_call.phone,
                                    'main', action_phone_call.main
                            ) as data
                     FROM action_phone_call

                     UNION ALL
                     SELECT action_download_app.campaign_id,
                            jsonb_build_object(
                                    'type_', 'download_app',
                                    'title', action_download_app.title,
                                    'url', action_download_app.url,
                                    'app_store_id', action_download_app.app_store_id,
                                    'google_play_id', action_download_app.google_play_id,
                                    'main', action_download_app.main
                            ) as data
                     FROM action_download_app

                     UNION ALL
                     SELECT action_resolve_uri.campaign_id,
                            jsonb_build_object(
                                    'type_', 'resolve_uri',
                                    'uri', action_resolve_uri.uri,
                                    'action_type', action_resolve_uri.action_type,
                                    'target', action_resolve_uri.target,
                                    'dialog', action_resolve_uri.dialog,
                                    'main', action_resolve_uri.main
                            ) as data
                     FROM action_resolve_uri

                     UNION ALL
                     SELECT action_add_point_to_route.campaign_id,
                            jsonb_build_object(
                                    'type_', 'add_point_to_route',
                                    'latitude', action_add_point_to_route.latitude,
                                    'longitude', action_add_point_to_route.longitude,
                                    'main', action_add_point_to_route.main
                            ) as data
                     FROM action_add_point_to_route
                 ) as actions_subq
            GROUP BY actions_subq.campaign_id
        ) as campaign_actions ON campaign_actions.campaign_id = campaign.id

        -- Выборка места для рекламирования
        LEFT JOIN (
            SELECT
                campaign_id,
                jsonb_build_object(
                    'organizations', jsonb_build_object(
                        'permalinks', permalinks
                    )
                ) as data
            FROM campaign_placing_organizations
            UNION ALL
            SELECT
                campaign_id,
                jsonb_build_object(
                    'area', jsonb_build_object(
                        'version', version,
                        'areas', areas
                    )
                ) as data
            FROM campaign_placing_area
        ) as campaign_placing ON campaign_placing.campaign_id = campaign.id

        -- Формирование списка креативов у кампании
        LEFT JOIN (
            SELECT creative_subq.campaign_id, jsonb_agg(creative_subq.data) as data
            FROM (
                    SELECT creative_billboard.campaign_id, jsonb_build_object(
                        'type_', 'billboard',
                        'images', creative_billboard.images,
                        'images_v2', creative_billboard.images_v2,
                        'title', creative_billboard.title,
                        'description', creative_billboard.description
                    ) as data
                    FROM creative_billboard

                    UNION ALL
                    SELECT creative_pin.campaign_id, jsonb_build_object(
                        'type_', 'pin',
                        'images', creative_pin.images,
                        'title', creative_pin.title,
                        'subtitle', creative_pin.subtitle
                    ) as data
                    FROM creative_pin

                    UNION ALL
                    SELECT creative_banner.campaign_id, jsonb_build_object(
                        'type_', 'banner',
                        'images', creative_banner.images,
                        'disclaimer', creative_banner.disclaimer,
                        'show_ads_label', creative_banner.show_ads_label,
                        'title', creative_banner.title,
                        'description', creative_banner.description,
                        'terms', creative_banner.terms
                    ) as data
                    FROM creative_banner

                    UNION ALL
                    SELECT creative_text.campaign_id, jsonb_build_object(
                        'type_', 'text',
                        'text', creative_text.text,
                        'disclaimer', creative_text.disclaimer
                    ) as data
                    FROM creative_text

                    UNION ALL
                    SELECT creative_icon.campaign_id, jsonb_build_object(
                        'type_', 'icon',
                        'images', creative_icon.images,
                        'position', creative_icon.position,
                        'title', creative_icon.title
                    ) as data
                    FROM creative_icon

                    UNION ALL
                    SELECT creative_pin_search.campaign_id, jsonb_build_object(
                        'type_', 'pin_search',
                        'images', creative_pin_search.images,
                        'title', creative_pin_search.title,
                        'organizations', creative_pin_search.organizations
                    ) as data
                    FROM creative_pin_search

                    UNION ALL
                    SELECT creative_logo_and_text.campaign_id, jsonb_build_object(
                        'type_', 'logo_and_text',
                        'images', creative_logo_and_text.images,
                        'text', creative_logo_and_text.text
                    ) as data
                    FROM creative_logo_and_text

                    UNION ALL
                    SELECT creative_via_point.campaign_id, jsonb_build_object(
                        'type_', 'via_point',
                        'images', creative_via_point.images,
                        'button_text_active', creative_via_point.button_text_active,
                        'button_text_inactive', creative_via_point.button_text_inactive,
                        'description', creative_via_point.description
                    ) as data
                    FROM creative_via_point

                    UNION ALL
                    SELECT creative_audio_banner.campaign_id, jsonb_build_object(
                        'type_', 'audio_banner',
                        'images', creative_audio_banner.images,
                        'left_anchor', creative_audio_banner.left_anchor,
                        'audio_file_url', creative_audio_banner.audio_file_url
                    ) as data
                    FROM creative_audio_banner
            ) as creative_subq
            GROUP BY creative_subq.campaign_id
        ) as campaign_creative ON campaign_creative.campaign_id = campaign.id
    ORDER BY campaign.id
"""  # noqa: E501

list_campaigns_to_refresh_auto_daily_budgets = """
SELECT ARRAY_AGG(campaign.id)
FROM campaign
    LEFT JOIN campaign_billing ON campaign.billing_id = campaign_billing.id
    LEFT JOIN billing_cpm ON campaign_billing.cpm_id = billing_cpm.id
    LEFT JOIN billing_cpa ON campaign_billing.cpa_id = billing_cpa.id
WHERE
      extract(HOUR FROM timezone(campaign.timezone, $1)) = 0
  AND (billing_cpm.auto_daily_budget IS TRUE OR billing_cpa.auto_daily_budget IS TRUE)
"""  # noqa: E501

list_existing_campaign_ids = """
    SELECT id
    FROM campaign
    WHERE id = ANY($1::bigint[])
"""

list_targetings_for_not_ended_campaigns = """
    SELECT targeting
    FROM campaign
    WHERE end_datetime >= $1 AND targeting != '{}'
"""

list_campaigns_for_budget_analysis = """
    SELECT
        campaign.id AS id,
        billing_cpm.budget,
        billing_cpm.daily_budget,
        (campaign.end_datetime AT TIME ZONE campaign.timezone)::date
        - (now() AT TIME ZONE campaign.timezone)::date as days_left
    FROM campaign
    LEFT JOIN campaign_billing ON campaign.billing_id = campaign_billing.id
    LEFT JOIN billing_cpm ON campaign_billing.cpm_id = billing_cpm.id
    LEFT JOIN (
        SELECT campaign_id, status, metadata
        FROM status_history
        WHERE (campaign_id, changed_datetime) IN (
            SELECT campaign_id, max(changed_datetime)
            FROM status_history
            GROUP BY campaign_id
        )
    ) AS current_status_subq ON current_status_subq.campaign_id = campaign.id
    WHERE billing_cpm.id IS NOT NULL
        AND publication_envs @> ARRAY['PRODUCTION']::publicationenvenum[]
        AND now() AT TIME ZONE campaign.timezone >= campaign.start_datetime AT TIME ZONE campaign.timezone
        AND now() AT TIME ZONE campaign.timezone <= campaign.end_datetime AT TIME ZONE campaign.timezone
        AND current_status_subq.status = 'ACTIVE'
        AND billing_cpm.budget IS NOT NULL
        AND billing_cpm.daily_budget IS NOT NULL
    ORDER BY campaign_id
"""  # noqa: E501


clear_campaigns_change_logs = """
    DELETE FROM campaigns_change_log
    WHERE id IN (
        SELECT id
        FROM campaigns_change_log
        WHERE now() - created_at >= INTERVAL '1 day'
        ORDER BY created_at
        LIMIT 100000
    )
    RETURNING
        id,
        created_at,
        campaign_id,
        author_id,
        status,
        system_metadata,
        state_before,
        state_after
"""

list_campaigns_for_monitorings = """
    SELECT
        id,
        campaign_type
    FROM campaign
    WHERE id = ANY($1::bigint[])
    ORDER BY id
"""
