-- +mixmaker Up
ALTER TABLE players
    ADD COLUMN IF NOT EXISTS battle_tag text NOT NULL DEFAULT '';

DO $$
DECLARE
    item record;
    base_name text;
    candidate text;
    suffix text;
    duplicate_number integer;
BEGIN
    FOR item IN SELECT id, display_name FROM players ORDER BY created_at, id LOOP
        base_name := regexp_replace(item.display_name, '^[[:space:]]+|[[:space:]]+$', '', 'g');
        IF char_length(base_name) < 2 THEN
            base_name := 'Player';
        END IF;
        base_name := left(base_name, 32);
        candidate := base_name;
        duplicate_number := 1;
        WHILE EXISTS (
            SELECT 1 FROM players
            WHERE id <> item.id AND lower(display_name) = lower(candidate)
        ) LOOP
            duplicate_number := duplicate_number + 1;
            suffix := '-' || duplicate_number::text;
            candidate := left(base_name, 32 - char_length(suffix)) || suffix;
        END LOOP;
        UPDATE players SET display_name = candidate WHERE id = item.id;
    END LOOP;
END $$;

ALTER TABLE players
    DROP CONSTRAINT IF EXISTS players_display_name_valid,
    ADD CONSTRAINT players_display_name_valid CHECK (
        display_name = regexp_replace(display_name, '^[[:space:]]+|[[:space:]]+$', '', 'g')
        AND char_length(display_name) BETWEEN 2 AND 32
    ),
    DROP CONSTRAINT IF EXISTS players_battle_tag_valid,
    ADD CONSTRAINT players_battle_tag_valid CHECK (
        battle_tag = ''
        OR battle_tag ~ '^[^#[:space:]]{2,20}#[0-9]{3,12}$'
    );

CREATE UNIQUE INDEX IF NOT EXISTS players_display_name_lower_uidx
    ON players (lower(display_name));

-- +mixmaker Down
DROP INDEX IF EXISTS players_display_name_lower_uidx;
ALTER TABLE players
    DROP CONSTRAINT IF EXISTS players_battle_tag_valid,
    DROP CONSTRAINT IF EXISTS players_display_name_valid,
    DROP COLUMN IF EXISTS battle_tag;
