-- Must drop the materialized view and recreate, as you cannot edit it directly/any of its dependencies
DROP MATERIALIZED VIEW IF EXISTS subscriptions_search;

-- Alter customer_id type
ALTER TABLE subscriptions
    ALTER COLUMN customer_id TYPE VARCHAR;
ALTER TABLE subscription_customer_descriptions
    ALTER COLUMN customer_id TYPE VARCHAR;

-- Recreate the view
CREATE MATERIALIZED VIEW IF NOT EXISTS subscriptions_search AS WITH rt_info AS (
    SELECT s.subscription_id,
        concat_ws(
            ', ',
            string_agg(
                rt.resource_type || ':' || siv.value,
                ', '
                ORDER BY rt.resource_type
            ),
            string_agg(
                distinct 'subscription_instance_id' || ':' || si.subscription_instance_id,
                ', '
            )
        ) AS rt_info
    FROM subscription_instance_values siv
        JOIN resource_types rt ON siv.resource_type_id = rt.resource_type_id
        JOIN subscription_instances si ON siv.subscription_instance_id = si.subscription_instance_id
        JOIN subscriptions s ON si.subscription_id = s.subscription_id
    GROUP BY s.subscription_id
),
sub_prod_info AS (
    SELECT s.subscription_id,
        array_to_string(
            ARRAY ['subscription_id:' || s.subscription_id,
                                          'status:' || s.status,
                                          'insync:' || s.insync,
                                          'subscription_description:' || s.description,
                                          'note:' || coalesce(s.note, ''),
                                          'customer_id:' || s.customer_id,
                                          'product_id:' || s.product_id],
            ', '
        ) AS sub_info,
        array_to_string(
            ARRAY ['product_name:' || p.name,
                                          'product_description:' || p.description,
                                          'tag:' || p.tag,
                                          'product_type:', p.product_type],
            ', '
        ) AS prod_info
    FROM subscriptions s
        JOIN products p ON s.product_id = p.product_id
),
fi_info AS (
    SELECT s.subscription_id,
        string_agg(
            fi.name || ':' || fi.value,
            ', '
            ORDER BY fi.name
        ) AS fi_info
    FROM subscriptions s
        JOIN products p ON s.product_id = p.product_id
        JOIN fixed_inputs fi ON p.product_id = fi.product_id
    GROUP BY s.subscription_id
),
cust_info AS (
    SELECT s.subscription_id,
        string_agg(
            'customer_description: ' || scd.description,
            ', '
        ) AS cust_info
    FROM subscriptions s
        JOIN subscription_customer_descriptions scd ON s.subscription_id = scd.subscription_id
    GROUP BY s.subscription_id
)
SELECT s.subscription_id,
    to_tsvector(
        'simple',
        concat_ws(
            ', ',
            spi.sub_info,
            spi.prod_info,
            fi.fi_info,
            rti.rt_info,
            ci.cust_info
        )
    ) as tsv
FROM subscriptions s
    LEFT JOIN sub_prod_info spi ON s.subscription_id = spi.subscription_id
    LEFT JOIN fi_info fi ON s.subscription_id = fi.subscription_id
    LEFT JOIN rt_info rti ON s.subscription_id = rti.subscription_id
    LEFT JOIN cust_info ci ON s.subscription_id = ci.subscription_id;

-- Recreate refresh fn if doesn't exist
CREATE OR REPLACE FUNCTION refresh_subscriptions_search_view()
    RETURNS TRIGGER
    LANGUAGE plpgsql
AS
$$
DECLARE
    should_refresh     bool;
    current_epoch      int;
    last_refresh_epoch int;
    comment_sql        text;
BEGIN
    SELECT extract(epoch from now())::int INTO current_epoch;
    SELECT coalesce(pg_catalog.obj_description('subscriptions_search'::regclass)::int, 0) INTO last_refresh_epoch;

    SELECT (current_epoch - last_refresh_epoch) > 120 INTO should_refresh;

    IF should_refresh THEN
        REFRESH MATERIALIZED VIEW CONCURRENTLY subscriptions_search;

        comment_sql := 'COMMENT ON MATERIALIZED VIEW subscriptions_search IS ' || quote_literal(current_epoch);
        EXECUTE comment_sql;
    END IF;
    RETURN NULL;
END;
$$;

-- Recreate indexes
CREATE INDEX subscriptions_search_tsv_idx ON subscriptions_search USING GIN (tsv);
CREATE UNIQUE INDEX subscriptions_search_subscription_id_idx ON subscriptions_search (subscription_id);

-- Refresh the view
REFRESH MATERIALIZED VIEW subscriptions_search;
