BEGIN;

DROP INDEX IF EXISTS project_flocks_base_period_unique;

ALTER TABLE project_flocks
    ADD COLUMN IF NOT EXISTS flock_id BIGINT;

WITH normalized AS (
    SELECT
        pf.id,
        COALESCE(
            NULLIF(TRIM(regexp_replace(pf.flock_name, '\\s+\\d+(\\s+\\d+)*$', '', 'g')), ''),
            CONCAT('Project Flock ', pf.id)
        ) AS normalized_name,
        COALESCE(NULLIF(pf.created_by, 0), 1) AS created_by
    FROM project_flocks pf
),
seed_flocks AS (
    SELECT DISTINCT
        n.normalized_name,
        MIN(n.created_by) AS created_by
    FROM normalized n
    GROUP BY n.normalized_name
)
INSERT INTO flocks (name, created_by, created_at, updated_at)
SELECT sf.normalized_name, sf.created_by, NOW(), NOW()
FROM seed_flocks sf
ON CONFLICT DO NOTHING;

WITH normalized AS (
    SELECT
        pf.id,
        COALESCE(
            NULLIF(TRIM(regexp_replace(pf.flock_name, '\\s+\\d+(\\s+\\d+)*$', '', 'g')), ''),
            CONCAT('Project Flock ', pf.id)
        ) AS normalized_name
    FROM project_flocks pf
),
resolved AS (
    SELECT
        n.id,
        f.id AS flock_id
    FROM normalized n
    JOIN flocks f ON LOWER(f.name) = LOWER(n.normalized_name)
)
UPDATE project_flocks pf
SET flock_id = resolved.flock_id
FROM resolved
WHERE pf.id = resolved.id;

WITH missing AS (
    SELECT
        pf.id,
        COALESCE(
            NULLIF(TRIM(regexp_replace(pf.flock_name, '\\s+\\d+(\\s+\\d+)*$', '', 'g')), ''),
            CONCAT('Project Flock ', pf.id)
        ) AS normalized_name,
        COALESCE(NULLIF(pf.created_by, 0), 1) AS created_by
    FROM project_flocks pf
    WHERE pf.flock_id IS NULL
),
seed_missing AS (
    SELECT DISTINCT normalized_name, created_by FROM missing
)
INSERT INTO flocks (name, created_by, created_at, updated_at)
SELECT sm.normalized_name, sm.created_by, NOW(), NOW()
FROM seed_missing sm
ON CONFLICT DO NOTHING;

WITH missing AS (
    SELECT
        pf.id,
        COALESCE(
            NULLIF(TRIM(regexp_replace(pf.flock_name, '\\s+\\d+(\\s+\\d+)*$', '', 'g')), ''),
            CONCAT('Project Flock ', pf.id)
        ) AS normalized_name
    FROM project_flocks pf
    WHERE pf.flock_id IS NULL
)
UPDATE project_flocks pf
SET flock_id = f.id
FROM missing m
JOIN flocks f ON LOWER(f.name) = LOWER(m.normalized_name)
WHERE pf.id = m.id;

ALTER TABLE project_flocks
    ALTER COLUMN flock_id SET NOT NULL;

DROP INDEX IF EXISTS project_flocks_flock_name_unique;

ALTER TABLE project_flocks
    DROP COLUMN IF EXISTS flock_name;

CREATE UNIQUE INDEX IF NOT EXISTS project_flocks_flock_period_unique
    ON project_flocks (flock_id, period)
    WHERE deleted_at IS NULL;

COMMIT;
