"""drop_profile_display_name_and_trigger_username

Revision ID: 20260224_drop_profile
Revises: 20260224_bind_profiles_auth
Create Date: 2026-02-24 22:10:00.000000

"""

from typing import Sequence, Union

from alembic import op


revision: str = "20260224_drop_profile"
down_revision: Union[str, Sequence[str], None] = "20260224_bind_profiles_auth"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    op.execute(
        """
        ALTER TABLE public.profiles
        DROP CONSTRAINT IF EXISTS uq_profiles_username
        """
    )

    op.execute(
        """
        ALTER TABLE public.profiles
        DROP COLUMN IF EXISTS display_name
        """
    )

    op.execute(
        """
        CREATE OR REPLACE FUNCTION public.create_profile_for_new_user()
        RETURNS trigger
        LANGUAGE plpgsql
        SECURITY DEFINER
        SET search_path = public
        AS $$
        BEGIN
            INSERT INTO public.profiles (id, username)
            VALUES (
                NEW.id,
                COALESCE(
                    NULLIF(NEW.raw_user_meta_data->>'username', ''),
                    'user_' || substr(replace(NEW.id::text, '-', ''), 1, 25)
                )
            )
            ON CONFLICT (id) DO NOTHING;

            RETURN NEW;
        END;
        $$
        """
    )


def downgrade() -> None:
    op.execute(
        """
        ALTER TABLE public.profiles
        ADD COLUMN IF NOT EXISTS display_name VARCHAR(50)
        """
    )

    op.execute(
        """
        WITH ranked AS (
            SELECT
                id,
                username,
                row_number() OVER (
                    PARTITION BY username
                    ORDER BY created_at ASC, id ASC
                ) AS rn
            FROM public.profiles
            WHERE username IS NOT NULL
        )
        UPDATE public.profiles p
        SET username = LEFT(p.username, 24) || '_' || (ranked.rn - 1)::text
        FROM ranked
        WHERE p.id = ranked.id
          AND ranked.rn > 1
        """
    )

    op.execute(
        """
        ALTER TABLE public.profiles
        ADD CONSTRAINT uq_profiles_username UNIQUE (username)
        """
    )

    op.execute(
        """
        CREATE OR REPLACE FUNCTION public.create_profile_for_new_user()
        RETURNS trigger
        LANGUAGE plpgsql
        SECURITY DEFINER
        SET search_path = public
        AS $$
        BEGIN
            INSERT INTO public.profiles (id, username, display_name)
            VALUES (
                NEW.id,
                'user_' || substr(replace(NEW.id::text, '-', ''), 1, 25),
                COALESCE(
                    NULLIF(NEW.raw_user_meta_data->>'display_name', ''),
                    NULLIF(NEW.raw_user_meta_data->>'full_name', '')
                )
            )
            ON CONFLICT (id) DO NOTHING;

            RETURN NEW;
        END;
        $$
        """
    )
