"""automations_migration

Revision: 0222
Revision ID: 0546e8ee2d53
Revises: 27f0fec65f2e
Create Date: 2021-10-08 15:52:56.641333

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql


# revision identifiers, used by Alembic.
revision = '0546e8ee2d53'
down_revision = '27f0fec65f2e'
branch_labels = None
depends_on = None


def upgrade():
    op.drop_column('automation_rules', 'trigger_count_period')
    op.execute("""
DROP TABLE IF EXISTS project_available_groups;

CREATE TEMP TABLE project_available_groups AS (
    SELECT DISTINCT p.id "project_id", g.id, g.title, cgt.id "group_type_id", a.id "attribute_id", COALESCE(a.name, cgt.name) "group_type_name"
    FROM
        projects p,
        card_groups g
        JOIN card_group_types cgt ON cgt.id = g.group_type_id
        LEFT JOIN attributes a ON a.id = cgt.attribute_id
        LEFT JOIN card_models cm ON cm.attribute_group_id = a.group_id
        LEFT JOIN project_enabled_models pem ON pem.model_id = cm.id
        LEFT JOIN project_enabled_group_types pegt ON pegt.group_type_id = cgt.id
    WHERE
        a.group_id = p.attribute_group_id OR
        pem.project_id = p.id OR
        pegt.project_id = p.id
);

INSERT INTO automation_rules (project_id, created_at, trigger_event_name, trigger_options, sequence, active, name, description, parallel, trigger_count_total, run_token)
SELECT
    r.project_id,
    r.created_at,
    'card_added_to_group',
    jsonb_build_object('group', jsonb_build_object('id', r.group_id, 'name', r.group_name)),
    (
        SELECT jsonb_agg(a.action)
        FROM (
            SELECT CASE
                WHEN action_name = 'set_attribute' AND (options->'attr')->>'type' IN ('members', 'files') THEN
                    json_build_object('action', action_name, 'options', jsonb_set(options, '{attr,value}', jsonb_build_array((options->'attr')->'value')))
                WHEN action_name = 'append_to_group' THEN
                    (
                        SELECT CASE
                            WHEN g.attribute_id IS NOT NULL THEN
                                json_build_object('action', 'set_attribute', 'options', json_build_object('attr',
                                    json_build_object('id', g.attribute_id, 'name', g.group_type_name, 'type', 'group_type', 'value', json_build_array(g.id))))
                            ELSE
                                json_build_object('action', 'append_to_group', 'options', json_build_object('group',
                                    json_build_object('id', g.id, 'name', g.title)))
                            END
                        FROM
                            project_available_groups g
                        WHERE
                            g.project_id = r.project_id AND (
                                (
                                    jsonb_path_exists(options::jsonb, '$.group.id') AND (
                                        g.id = ((options->'group')->>'id')::int
                                    )
                                ) OR (
                                    NOT jsonb_path_exists(options::jsonb, '$.group.id') AND jsonb_path_exists(options::jsonb, '$.group.group_type.name ? (@ != null)') AND (
                                        g.title = (options->'group')->>'name' AND
                                        g.group_type_name = ((options->'group')->'group_type')->>'name'
                                    )
                                ) OR (
                                    NOT jsonb_path_exists(options::jsonb, '$.group.id') AND jsonb_path_exists(options::jsonb, '$.group.group_type.name ? (!exists(@) || @ == null)') AND (
                                        g.title = (options->'group')->>'name'
                                    )
                                )
                            )
                        ORDER BY g.id LIMIT 1
                    )
                ELSE
                    json_build_object('action', action_name, 'options', options)
                END "action"
            FROM project_auto_actions WHERE project_id = r.project_id AND group_id = r.group_id
            ORDER BY id
        ) a
        WHERE a.action IS NOT NULL
    ),
    true,
    r.group_name,
    '',
    false,
    0,
    uuid_generate_v4()
FROM (
    SELECT paa.project_id, paa.group_id, g.title "group_name", MIN(paa.created_at) "created_at"
    FROM project_auto_actions paa JOIN card_groups g ON g.id = paa.group_id JOIN card_group_types cgt ON cgt.id = g.group_type_id
    WHERE cgt.attribute_id IS NULL
    GROUP BY paa.project_id, paa.group_id, g.title
) r;

INSERT INTO automation_rules (project_id, created_at, trigger_event_name, trigger_options, sequence, active, name, description, parallel, trigger_count_total, run_token)
SELECT
    r.project_id,
    r.created_at,
    'card_field_updated',
    jsonb_build_object('attribute', jsonb_build_object('id', r.attribute_id, 'name', r.attribute_name)),
    (
        SELECT jsonb_build_array(jsonb_build_object('branches', jsonb_build_array(
            jsonb_build_array('"' || r.group_name || '" in {' || r.attribute_name || '}', jsonb_agg(a.action)))))
        FROM (
            SELECT CASE
                WHEN action_name = 'set_attribute' AND (options->'attr')->>'type' IN ('members', 'files') THEN
                    json_build_object('action', action_name, 'options', jsonb_set(options, '{attr,value}', jsonb_build_array((options->'attr')->'value')))
                WHEN action_name = 'append_to_group' THEN
                    (
                        SELECT CASE
                            WHEN g.attribute_id IS NOT NULL THEN
                                json_build_object('action', 'set_attribute', 'options', json_build_object('attr',
                                    json_build_object('id', g.attribute_id, 'name', g.group_type_name, 'type', 'group_type', 'value', json_build_array(g.id))))
                            ELSE
                                json_build_object('action', 'append_to_group', 'options', json_build_object('group',
                                    json_build_object('id', g.id, 'name', g.title)))
                            END
                        FROM
                            project_available_groups g
                        WHERE
                            g.project_id = r.project_id AND (
                                (
                                    jsonb_path_exists(options::jsonb, '$.group.id') AND (
                                        g.id = ((options->'group')->>'id')::int
                                    )
                                ) OR (
                                    NOT jsonb_path_exists(options::jsonb, '$.group.id') AND jsonb_path_exists(options::jsonb, '$.group.group_type.name ? (@ != null)') AND (
                                        g.title = (options->'group')->>'name' AND
                                        g.group_type_name = ((options->'group')->'group_type')->>'name'
                                    )
                                ) OR (
                                    NOT jsonb_path_exists(options::jsonb, '$.group.id') AND jsonb_path_exists(options::jsonb, '$.group.group_type.name ? (!exists(@) || @ == null)') AND (
                                        g.title = (options->'group')->>'name'
                                    )
                                )
                            )
                        ORDER BY g.id LIMIT 1
                    )
                ELSE
                    json_build_object('action', action_name, 'options', options)
                END "action"
            FROM project_auto_actions WHERE project_id = r.project_id AND group_id = r.group_id
            ORDER BY id
        ) a
        WHERE a.action IS NOT NULL
    ),
    true,
    r.group_name,
    '',
    false,
    0,
    uuid_generate_v4()
FROM (
    SELECT paa.project_id, paa.group_id, g.title "group_name", MIN(paa.created_at) "created_at", cgt.attribute_id, a.name "attribute_name"
    FROM project_auto_actions paa JOIN card_groups g ON g.id = paa.group_id JOIN card_group_types cgt ON cgt.id = g.group_type_id
    JOIN attributes a ON a.id = cgt.attribute_id
    GROUP BY paa.project_id, paa.group_id, g.title, cgt.attribute_id, a.name
) r;

DELETE FROM automation_rules WHERE sequence IS NULL;
    """)


def downgrade():
    pass
