-- execute this manualy to avoid all this migration
--ALTER TYPE social.feedback_type ADD VALUE 'taxi-route' AFTER 'poi';
--ALTER TYPE social.feedback_type ADD VALUE 'truck-route' AFTER 'poi';
--ALTER TYPE social.feedback_type ADD VALUE 'mt-route' AFTER 'poi';
--ALTER TYPE social.feedback_type ADD VALUE 'no-road' AFTER 'poi';

CREATE FUNCTION social.drop_type_related_mat_views_temp()
    RETURNS void AS
$$
BEGIN
    drop materialized view social.feedback_task_distinct_source_type_mv;
    drop materialized view social.feedback_aoi_opened_task_stat_mv;
    drop materialized view social.feedback_aoi_oldest_opened_task_mv;
END;
$$ LANGUAGE plpgsql;


CREATE FUNCTION social.drop_type_related_constraints_temp()
    RETURNS void AS
$$
BEGIN
    ALTER TABLE social.feedback_task_outgoing_opened_experiment
        DROP CONSTRAINT check_type_experiment;

    ALTER TABLE social.feedback_task_outgoing_opened
        DROP CONSTRAINT not_experiment_type;
END;
$$ LANGUAGE plpgsql;


CREATE FUNCTION social.append_new_type_values_temp()
    RETURNS void AS
$$
BEGIN
    ALTER TYPE social.feedback_type RENAME TO feedback_type_old;

    CREATE TYPE social.feedback_type AS ENUM (
        'road',
        'street-name',
        'road-speed-limit',
        'road-direction',
        'road-surface',
        'route-gap',
        'route-lost',
        'car-route',
        'pedestrian-route',
        'bicycle-route',
        'building',
        'address',
        'address-experiment',
        'entrance',
        'entrance-experiment',
        'public-transport-stop',
        'parking',
        'maneuver',
        'barrier',
        'road-closure',
        'road-annotation',
        'traffic-light',
        'other',
        'mandatory-direction-traffic-sign',
        'prohibited-turn-sign',
        'one-way-traffic-sign',
        'traffic-lane-sign',
        'traffic-prohibited-sign',
        'traffic-circle-sign',
        'poi',
        'no-road',
        'mt-route',
        'truck-route',
        'taxi-route'
    );

    ALTER TABLE social.feedback_task
        ALTER COLUMN type TYPE social.feedback_type
            USING type::text::social.feedback_type;

    ALTER TABLE social.feedback_preset
        ALTER COLUMN types TYPE social.feedback_type[]
            USING types::text::social.feedback_type[];

    DROP TYPE social.feedback_type_old;
END;
$$ LANGUAGE plpgsql;


CREATE FUNCTION social.restore_type_related_constraints_temp()
    RETURNS void AS
$$
BEGIN
    ALTER TABLE social.feedback_task_outgoing_opened_experiment
        ADD CONSTRAINT check_type_experiment
            CHECK (type IN ('address-experiment', 'entrance-experiment'));

    ALTER TABLE social.feedback_task_outgoing_opened
        ADD CONSTRAINT not_experiment_type
            CHECK (type NOT IN ('address-experiment', 'entrance-experiment'));            
END;
$$ LANGUAGE plpgsql;


-- copy-paste from mirgation 434
CREATE FUNCTION social.restore_aoi_stat_mv_temp()
    RETURNS void AS
$$
BEGIN
    CREATE MATERIALIZED VIEW social.feedback_aoi_opened_task_stat_mv AS
    (
        SELECT
            aoi_id,
            source,
            type,
            workflow,
            COUNT(*) AS total,
            COUNT(*) FILTER (WHERE hidden = TRUE) as total_hidden,
            COUNT(*) FILTER (WHERE workflow = 'feedback' AND created_at <= now() - '24 hours'::interval) AS old,
            COUNT(*) FILTER (WHERE workflow = 'feedback' AND created_at <= now() - '24 hours'::interval AND hidden = TRUE) AS old_hidden
        FROM
            social.feedback_aoi_feed_outgoing_opened aoi
                JOIN
            social.feedback_task_outgoing_opened fb
                ON aoi.feedback_task_id = fb.id
        WHERE
            duplicate_head_id IS NULL
            AND bucket = 'outgoing'
        GROUP BY
            aoi_id,
            source,
            type,
            workflow
    )
    WITH DATA;

    -- In order to refresh this matview concurrently we must create unique index.
    -- Refresh call is executed periodically in schedule_feedback_worker

    CREATE UNIQUE INDEX feedback_aoi_opened_task_stat_mv_idx
    ON social.feedback_aoi_opened_task_stat_mv
    (aoi_id, source, type, workflow, total, total_hidden, old, old_hidden);
END;
$$ LANGUAGE plpgsql;


-- copy-paste from migration 433
CREATE FUNCTION social.restore_aoi_oldest_mv_temp()
    RETURNS void AS
$$
BEGIN
    CREATE MATERIALIZED VIEW social.feedback_aoi_oldest_opened_task_mv AS (
        WITH
            aoi_feedback_full AS (
                SELECT
                    aoi.aoi_id,
                    fb.id,
                    fb.created_at,
                    fb.type,
                    fb.attrs,
                    fb.source,
                    fb.workflow
                FROM
                    social.feedback_aoi_feed_outgoing_opened aoi
                        JOIN social.feedback_task_outgoing_opened fb
                             ON aoi.feedback_task_id = fb.id
                WHERE
                    fb.bucket = 'outgoing'
            )
        SELECT *
        FROM
            (
                SELECT
                    af_oldest.aoi_id,
                    af_oldest.source,
                    af_oldest.type,
                    af_oldest.workflow,
                    af_oldest.min_created_at,
                    af.id,
                    row_number()
                    OVER (PARTITION BY af_oldest.aoi_id, af_oldest.source, af_oldest.type, af_oldest.workflow) AS row_id
                FROM
                    (
                        SELECT
                            aoi_id,
                            source,
                            type,
                            workflow,
                            MIN(created_at) AS min_created_at
                        FROM
                            aoi_feedback_full
                        GROUP BY
                            aoi_id,
                            source,
                            type,
                            workflow
                    ) AS af_oldest
                        JOIN aoi_feedback_full AS af ON
                            af_oldest.aoi_id = af.aoi_id AND
                            af_oldest.source = af.source AND
                            af_oldest.type = af.type AND
                            af_oldest.workflow = af.workflow AND
                            af_oldest.min_created_at = af.created_at
            ) sub
        WHERE row_id = 1
    )
        WITH DATA;

    -- In order to refresh this matview concurrently we must create unique index.
    -- Refresh call is executed periodically in schedule_feedback_worker

    CREATE UNIQUE INDEX feedback_aoi_oldest_opened_task_mv_idx
    ON social.feedback_aoi_oldest_opened_task_mv
    (aoi_id, source, type, workflow, min_created_at, id);
END;
$$ LANGUAGE plpgsql;


-- copy-paste from migration 431
CREATE FUNCTION social.restore_distinct_source_type_mv_temp()
    RETURNS void AS
$$
BEGIN
    CREATE MATERIALIZED VIEW social.feedback_task_distinct_source_type_mv AS
    SELECT
        source,
        type,
        hidden,
        workflow,
        CASE WHEN resolved_by IS NOT NULL THEN 'resolved'
             WHEN bucket = 'need-info' THEN 'need-info'
             ELSE 'opened'
        END AS status,
        min(state_modified_at) AS min_created_at,
        max(state_modified_at) AS max_created_at
    FROM social.feedback_task
    WHERE
        bucket NOT IN ('incoming', 'deferred')
    GROUP BY
        source,
        type,
        hidden,
        workflow,
        status
    WITH DATA;

    -- In order to refresh this matview concurrently we must create unique index.
    -- Refresh call is executed periodically in schedule_feedback_worker

    CREATE UNIQUE INDEX feedback_task_distinct_source_type_mv_idx
    ON social.feedback_task_distinct_source_type_mv
    (source, type, hidden, workflow, status, min_created_at, max_created_at);
END;
$$ LANGUAGE plpgsql;


CREATE FUNCTION social.restore_type_related_mat_views_temp()
    RETURNS void AS
$$
BEGIN
    PERFORM social.restore_aoi_stat_mv_temp();
    PERFORM social.restore_aoi_oldest_mv_temp();
    PERFORM social.restore_distinct_source_type_mv_temp();
END;
$$ LANGUAGE plpgsql;



CREATE FUNCTION social.add_new_type_values_temp()
    RETURNS void AS
$$
BEGIN
    IF 'taxi-route' = any(enum_range(null::social.feedback_type)::name[]) THEN
        RETURN;
    END IF;

    PERFORM social.drop_type_related_mat_views_temp();
    PERFORM social.drop_type_related_constraints_temp();

    PERFORM social.append_new_type_values_temp();

    PERFORM social.restore_type_related_constraints_temp();
    PERFORM social.restore_type_related_mat_views_temp();
END;
$$ LANGUAGE plpgsql;



SELECT social.add_new_type_values_temp();

DROP FUNCTION social.add_new_type_values_temp();

DROP FUNCTION social.restore_type_related_mat_views_temp();
DROP FUNCTION social.restore_distinct_source_type_mv_temp();
DROP FUNCTION social.restore_aoi_oldest_mv_temp();
DROP FUNCTION social.restore_aoi_stat_mv_temp();

DROP FUNCTION social.restore_type_related_constraints_temp();

DROP FUNCTION social.append_new_type_values_temp();

DROP FUNCTION social.drop_type_related_constraints_temp();
DROP FUNCTION social.drop_type_related_mat_views_temp();
