list_business_subscriptions = """
    SELECT
        id as subscription_id,
        scenario_name,
        biz_id,
        status,
        coupon_id
    FROM subscriptions
    WHERE biz_id=$1
"""

create_subscription = """
    WITH new_subscription AS (
        INSERT INTO subscriptions (
            scenario_name,
            biz_id,
            status,
            coupon_id
        )
        VALUES ($1, $2, $3, $4)
        RETURNING *
    ),
    new_version AS (
        INSERT INTO subscription_versions (subscription_id, coupon_id, status)
        SELECT id, coupon_id, status
        FROM new_subscription
    )
    SELECT id AS subscription_id,
        scenario_name,
        biz_id,
        status,
        coupon_id
    FROM new_subscription
"""

retrieve_subscription = """
    SELECT id AS subscription_id,
        biz_id,
        scenario_name,
        status,
        coupon_id
    FROM subscriptions
    WHERE id=$1 AND biz_id=$2
"""

list_subscriptions_versions_for_export = """
    SELECT
        sv.id AS version_id,
        s.id AS subscription_id,
        s.biz_id,
        s.scenario_name,
        sv.coupon_id,
        sv.status,
        sv.created_at
    FROM subscriptions AS s
    JOIN subscription_versions AS sv ON sv.subscription_id = s.id
    WHERE sv.status IS NOT NULL
    ORDER BY sv.created_at
"""

retrieve_subscription_coupons_history = """
    WITH versions AS (
        SELECT
            created_at,
            coupon_id,
            lag(coupon_id, 1) OVER (ORDER BY created_at) AS previous_coupon_id,
            lag(id, 1) OVER (ORDER BY created_at) AS previous_id
        FROM subscription_versions
        WHERE subscription_id=$1
    )
    SELECT
        versions.coupon_id,
        versions.created_at,
        jsonb_build_object(
            'sent', COALESCE(SUM(stat.sent), 0),
            'clicked', COALESCE(SUM(stat.clicked), 0),
            'opened', COALESCE(SUM(stat.opened), 0)
        ) AS statistics
    FROM versions
    -- TODO sometimes biz_id has duplicate. As tmp solution we ignore biz_id here
    LEFT JOIN certificate_mailing_stats AS stat USING (coupon_id)
    WHERE versions.coupon_id IS DISTINCT FROM versions.previous_coupon_id
        OR previous_id IS NULL -- for first version without coupon
    GROUP BY versions.coupon_id, versions.created_at
    ORDER BY versions.created_at DESC
"""

fetch_subscription_state = """
    SELECT s.status, sv.coupon_id
    FROM subscriptions AS s
    JOIN subscription_versions AS sv ON sv.subscription_id=s.id
    WHERE s.id=$1 AND s.biz_id=$2
    ORDER BY sv.created_at DESC
    LIMIT 1
"""

update_subscription_status = """
    WITH updated_subscription AS (
        UPDATE subscriptions
        SET status=$3
        WHERE id=$1 AND biz_id=$2
        RETURNING *
    )
    INSERT INTO subscription_versions (subscription_id, coupon_id, status)
    SELECT $1, coupon_id, $3
    FROM updated_subscription
"""

update_subscriptions_statuses = """
    WITH updated_subscriptions AS (
        UPDATE subscriptions
        SET status=$2
        WHERE id=ANY($1)
        RETURNING *
    )
    INSERT INTO subscription_versions (subscription_id, coupon_id, status)
    SELECT id, coupon_id, $2
    FROM updated_subscriptions
"""

replace_subscription_coupon = """
    WITH new_version AS (
        INSERT INTO subscription_versions (subscription_id, coupon_id, status)
        VALUES ($1, $3, $4)
    )
    UPDATE subscriptions
    SET status=$4, coupon_id=$3
    WHERE id=$1 AND biz_id=$2
    RETURNING status
"""

list_subscriptions_for_export = """
    SELECT
        id as subscription_id,
        scenario_name,
        biz_id,
        coupon_id
    FROM subscriptions
    WHERE status = 'ACTIVE'
    ORDER BY id
"""

create_messages_tmp_table = """
    CREATE TEMPORARY TABLE messages_tmp (
        time_to_send TEXT,
        message_anchor TEXT NOT NULL,
        message_type TEXT NOT NULL,
        message_meta TEXT NOT NULL,
        doorman_ids BIGINT[] NOT NULL,
        promoter_ids BIGINT[] NOT NULL,
        scenario_names TEXT[] NOT NULL
    )
    ON COMMIT DROP
"""

copy_messages_from_tmp = """
    INSERT INTO messages (
        time_to_send,
        message_anchor,
        message_type,
        message_meta,
        doorman_ids,
        promoter_ids,
        scenario_names
    )
    SELECT
        time_to_send::timestamptz,
        message_anchor,
        message_type::messagetype,
        message_meta::jsonb,
        doorman_ids,
        promoter_ids,
        scenario_names::scenario_name[]
    FROM messages_tmp
"""

list_unprocessed_email_messages = """
    SELECT
        time_to_send,
        subject,
        template_name,
        array_agg(
            jsonb_build_object(
                'id', id,
                'message_anchor', message_anchor,
                'recipient', recipient,
                'template_vars', template_vars
            )
            ORDER BY id
        ) AS messages
    FROM (
        SELECT
            id,
            time_to_send,
            message_anchor,
            message_meta ->> 'recipient' AS recipient,
            message_meta ->> 'subject' AS subject,
            message_meta ->> 'template_name' AS template_name,
            coalesce(message_meta -> 'template_vars', '{}'::jsonb) AS template_vars
        FROM messages
        WHERE processed_at IS NULL
            AND message_type = 'EMAIL'
    ) AS unprocessed_emails
    GROUP BY time_to_send, subject, template_name
    ORDER BY time_to_send
"""

mark_messages_processed = """
    UPDATE messages
    SET
        processed_at = $2,
        error = $3,
        processed_meta = $4
    WHERE id = ANY($1)
"""

create_certificate_mailing_stats_tmp_table = """
    CREATE TEMPORARY TABLE certificate_mailing_stats_tmp (
        id BIGSERIAL NOT NULL,
        biz_id BIGINT NOT NULL,
        coupon_id BIGINT NOT NULL,
        scenario_name TEXT NOT NULL,
        clicked INT NOT NULL,
        opened INT NOT NULL,
        sent INT NOT NULL,
        sent_date TEXT NOT NULL
    )
    ON COMMIT DROP
"""

copy_certificate_mailing_stats_from_tmp = """
    WITH merge_stats AS (
        UPDATE certificate_mailing_stats as cms
        SET
            opened = cms.opened + cms_tmp.opened,
            clicked = cms.clicked + cms_tmp.clicked,
            sent = cms.sent + cms_tmp.sent
        FROM certificate_mailing_stats_tmp as cms_tmp
        WHERE cms.coupon_id = cms_tmp.coupon_id
            AND cms.sent_date = cms_tmp.sent_date
        RETURNING cms_tmp.id
    )
    -- add not merged data
    INSERT INTO certificate_mailing_stats (
        biz_id,
        coupon_id,
        scenario_name,
        clicked,
        opened,
        sent,
        sent_date
    )
    SELECT
        cms_tmp.biz_id,
        cms_tmp.coupon_id,
        cms_tmp.scenario_name::scenario_name,
        cms_tmp.clicked,
        cms_tmp.opened,
        cms_tmp.sent,
        cms_tmp.sent_date
    FROM certificate_mailing_stats_tmp as cms_tmp
    LEFT JOIN merge_stats as sa USING (id)
    WHERE sa.id IS NULL
"""
