defmodule Mv.Repo.Migrations.AddGroupsAndMemberGroups do
  @moduledoc """
  Updates resources based on their most recent snapshots.

  This file was autogenerated with `mix ash_postgres.generate_migrations`
  """

  use Ecto.Migration

  def up do
    create table(:member_groups, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("uuid_generate_v7()"), primary_key: true

      add :member_id,
          references(:members,
            column: :id,
            name: "member_groups_member_id_fkey",
            type: :uuid,
            prefix: "public",
            on_delete: :delete_all
          ),
          null: false

      add :group_id, :uuid, null: false

      add :inserted_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :updated_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")
    end

    create table(:groups, primary_key: false) do
      add :id, :uuid, null: false, default: fragment("uuid_generate_v7()"), primary_key: true
    end

    alter table(:member_groups) do
      modify :group_id,
             references(:groups,
               column: :id,
               name: "member_groups_group_id_fkey",
               type: :uuid,
               prefix: "public",
               on_delete: :delete_all
             )
    end

    # Unique constraint on (member_id, group_id) to prevent duplicate associations
    create unique_index(:member_groups, [:member_id, :group_id],
             name: "member_groups_unique_member_group_index"
           )

    # Indexes for efficient queries
    create index(:member_groups, [:member_id], name: "member_groups_member_id_index")
    create index(:member_groups, [:group_id], name: "member_groups_group_id_index")

    alter table(:groups) do
      add :name, :text, null: false
      add :slug, :text, null: false
      add :description, :text

      add :inserted_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")

      add :updated_at, :utc_datetime_usec,
        null: false,
        default: fragment("(now() AT TIME ZONE 'utc')")
    end

    # Unique index on slug (case-sensitive)
    create unique_index(:groups, [:slug], name: "groups_unique_slug_index")

    # Unique index on LOWER(name) for case-insensitive uniqueness
    # Using execute because Ecto doesn't support fragment in index column list
    execute(
      "CREATE UNIQUE INDEX groups_unique_name_lower_index ON groups (LOWER(name))",
      "DROP INDEX IF EXISTS groups_unique_name_lower_index"
    )
  end

  def down do
    execute("DROP INDEX IF EXISTS groups_unique_name_lower_index")

    drop_if_exists unique_index(:groups, [:slug], name: "groups_unique_slug_index")

    alter table(:groups) do
      remove :updated_at
      remove :inserted_at
      remove :description
      remove :slug
      remove :name
    end

    drop_if_exists index(:member_groups, [:group_id], name: "member_groups_group_id_index")
    drop_if_exists index(:member_groups, [:member_id], name: "member_groups_member_id_index")

    drop_if_exists unique_index(:member_groups, [:member_id, :group_id],
                     name: "member_groups_unique_member_group_index"
                   )

    drop constraint(:member_groups, "member_groups_group_id_fkey")

    alter table(:member_groups) do
      modify :group_id, :uuid
    end

    drop table(:groups)

    drop constraint(:member_groups, "member_groups_member_id_fkey")

    drop table(:member_groups)
  end
end
