defmodule Towerops.Organizations.Membership do
  @moduledoc """
  Membership schema representing user-organization relationships.

  Defines user roles and permissions within an organization (owner, admin, member).
  """
  use Ecto.Schema

  import Ecto.Changeset

  alias Ecto.Association.NotLoaded
  alias Towerops.Accounts.User
  alias Towerops.Organizations.Organization

  @primary_key {:id, :binary_id, autogenerate: true}
  @foreign_key_type :binary_id
  schema "organization_memberships" do
    field :role, Ecto.Enum, values: [:owner, :admin, :member, :viewer]
    field :is_default, :boolean, default: false

    belongs_to :organization, Organization
    belongs_to :user, User

    timestamps(type: :utc_datetime)
  end

  @type t :: %__MODULE__{
          id: Ecto.UUID.t(),
          role: :owner | :admin | :member | :viewer,
          is_default: boolean(),
          organization_id: Ecto.UUID.t(),
          organization: NotLoaded.t() | Organization.t(),
          user_id: Ecto.UUID.t(),
          user: NotLoaded.t() | User.t(),
          inserted_at: DateTime.t(),
          updated_at: DateTime.t()
        }

  @doc false
  def changeset(membership, attrs) do
    membership
    |> cast(attrs, [:role, :organization_id, :user_id, :is_default])
    |> validate_required([:role, :organization_id, :user_id])
    |> foreign_key_constraint(:organization_id)
    |> foreign_key_constraint(:user_id)
    |> unique_constraint([:organization_id, :user_id],
      name: :organization_memberships_organization_id_user_id_index
    )
  end
end
