defmodule Mv.Repo.Migrations.AssignMitgliedRoleToExistingUsers do
  @moduledoc """
  Assigns the "Mitglied" role to all existing users without a role.

  This migration runs once during deployment to ensure all users have a role assigned.
  New users will automatically get the "Mitglied" role via the role_id attribute's default function.
  """
  use Ecto.Migration
  import Ecto.Query

  def up do
    # Find or create the "Mitglied" role
    # This ensures the migration works even if seeds haven't run yet
    mitglied_role_id =
      case repo().one(
             from(r in "roles",
               where: r.name == "Mitglied",
               select: r.id
             )
           ) do
        nil ->
          # Role doesn't exist - create it
          # This is idempotent and safe because the role name is unique
          # Use execute with SQL string to properly use uuid_generate_v7() function
          execute("""
            INSERT INTO roles (id, name, description, permission_set_name, is_system_role, inserted_at, updated_at)
            VALUES (uuid_generate_v7(), 'Mitglied', 'Default member role with access to own data only', 'own_data', true, (now() AT TIME ZONE 'utc'), (now() AT TIME ZONE 'utc'))
          """)

          # Get the created role ID
          role_id =
            repo().one(
              from(r in "roles",
                where: r.name == "Mitglied",
                select: r.id
              )
            )

          IO.puts("✅ Created 'Mitglied' role (was missing)")
          role_id

        role_id ->
          role_id
      end

    # Assign Mitglied role to all users without a role
    {count, _} =
      repo().update_all(
        from(u in "users", where: is_nil(u.role_id)),
        set: [role_id: mitglied_role_id]
      )

    IO.puts("✅ Assigned 'Mitglied' role to #{count} existing user(s)")
  end

  def down do
    # Not reversible - we can't know which users had no role before
    :ok
  end
end
