defmodule Towerops.EctoTypes.JsonAny do
  @moduledoc """
  Custom Ecto type for JSONB columns that can store any JSON-encodable value.

  Unlike the built-in :map type which only accepts maps, this type accepts:
  - strings
  - numbers (integer, float)
  - booleans
  - nil
  - lists
  - maps

  All values are stored as JSONB in the database.
  """
  use Ecto.Type

  def type, do: :jsonb

  # Cast accepts any JSON-encodable value
  def cast(nil), do: {:ok, nil}
  def cast(value) when is_binary(value), do: {:ok, value}
  def cast(value) when is_number(value), do: {:ok, value}
  def cast(value) when is_boolean(value), do: {:ok, value}
  def cast(value) when is_list(value), do: {:ok, value}
  def cast(value) when is_map(value), do: {:ok, value}
  def cast(_), do: :error

  # Load from database - return as-is
  def load(value), do: {:ok, value}

  # Dump to database - return as-is, Postgres will handle JSON encoding
  def dump(nil), do: {:ok, nil}
  def dump(value) when is_binary(value), do: {:ok, value}
  def dump(value) when is_number(value), do: {:ok, value}
  def dump(value) when is_boolean(value), do: {:ok, value}
  def dump(value) when is_list(value), do: {:ok, value}
  def dump(value) when is_map(value), do: {:ok, value}
  def dump(_), do: :error
end
