defmodule Remedy.Schema.Emoji do
  @moduledoc """
  Discord Emoji Object
  use Remedy.Schema
  alias Remedy.CDN

  @type t :: %__MODULE__{
          name: String.t(),
          #       roles: [Role.t()],
          require_colons: boolean(),
          managed: boolean(),
          animated: boolean(),
          available: boolean(),
          user: User.t(),
          guild: Guild.t()

  @primary_key {:id, :id, autogenerate: false}
  schema "emojis" do
    field :name, :string

    field :require_colons, :boolean
    field :managed, :boolean
    field :animated, :boolean
    field :available, :boolean
    belongs_to :user, User
    belongs_to :guild, Guild

  def changeset(model \\ %__MODULE__{}, params) do
    fields = __MODULE__.__schema__(:fields)
    embeds = __MODULE__.__schema__(:embeds)
    cast_model = cast(model, params, fields -- embeds)

    Enum.reduce(embeds, cast_model, fn embed, cast_model ->
      cast_embed(cast_model, embed)

  @doc """

  > Mention is more of a ping. potentially rename

  Formats an `Remedy.Struct.Emoji` into a mention.

  ## Examples

      iex> emoji = %Remedy.Struct.Emoji{name: "👍"}
      ...> Remedy.Struct.Emoji.mention(emoji)

      iex> emoji = %Remedy.Struct.Emoji{id: 436885297037312001, name: "tealixir"}
      ...> Remedy.Struct.Emoji.mention(emoji)

      iex> emoji = %Remedy.Struct.Emoji{id: 437016804309860372, name: "blobseizure", animated: true}
      ...> Remedy.Struct.Emoji.mention(emoji)


  @spec mention(t()) :: String.t()
  def mention(emoji)
  def mention(%__MODULE__{id: nil, name: name}), do: name
  def mention(%__MODULE__{animated: true, id: id, name: name}), do: "<a:#{name}:#{id}>"
  def mention(%__MODULE__{id: id, name: name}), do: "<:#{name}:#{id}>"

  @doc """
  Formats an emoji struct into its `t:Remedy.Struct.Emoji.api_name/0`.

  ## Examples

      iex> emoji = %Remedy.Struct.Emoji{name: "Γ¡É"}
      ...> Remedy.Struct.Emoji.api_name(emoji)

      iex> emoji = %Remedy.Struct.Emoji{id: 437093487582642177, name: "foxbot"}
      ...> Remedy.Struct.Emoji.api_name(emoji)


  @spec api_name(t) :: String.t()
  def api_name(emoji)
  def api_name(%__MODULE__{id: nil, name: name}), do: name
  def api_name(%__MODULE__{id: id, name: name}), do: "#{name}:#{id}"

  @doc """
  Returns the url of a custom emoji's image. If the emoji is not a custom one,
  returns `nil`.

  ## Examples

      iex> emoji = %Remedy.Struct.Emoji{id: 450225070569291776}
      ...> Remedy.Struct.Emoji.image_url(emoji)

      iex> emoji = %Remedy.Struct.Emoji{id: 406140226998894614, animated: true}
      ...> Remedy.Struct.Emoji.image_url(emoji)

      iex> emoji = %Remedy.Struct.Emoji{id: nil, name: "Γ¡É"}
      ...> Remedy.Struct.Emoji.image_url(emoji)

  @spec image_url(t) :: String.t() | nil
  def image_url(emoji)
  def image_url(%__MODULE__{id: nil}), do: nil
  def image_url(%__MODULE__{id: id}), do: CDN.custom_emoji(id)