defmodule Microwaveprop.Rover.Location do
  @moduledoc """
  A globally-visible rover parking location contributed by a logged-in
  user. Everyone can view the list; only authenticated users can create
  entries (creator tracked via `user_id`).

  `status` is `:good` (recommended spot) or `:bad` (avoid —
  trespass, no-go, etc.).
  """
  use Ecto.Schema

  import Ecto.Changeset

  @statuses [:good, :bad]

  @primary_key {:id, :binary_id, autogenerate: true}
  @foreign_key_type :binary_id
  schema "rover_locations" do
    field :lat, :float
    field :lon, :float
    field :status, Ecto.Enum, values: @statuses, default: :good
    field :notes, :string

    belongs_to :user, Microwaveprop.Accounts.User

    timestamps(type: :utc_datetime)
  end

  @type t :: %__MODULE__{}

  @spec statuses() :: [atom()]
  def statuses, do: @statuses

  @spec changeset(t() | Ecto.Changeset.t(), map()) :: Ecto.Changeset.t()
  def changeset(location, attrs) do
    location
    |> cast(attrs, [:lat, :lon, :status, :notes])
    |> validate_required([:lat, :lon, :status])
    |> validate_number(:lat, greater_than_or_equal_to: -90.0, less_than_or_equal_to: 90.0)
    |> validate_number(:lon, greater_than_or_equal_to: -180.0, less_than_or_equal_to: 180.0)
    |> validate_inclusion(:status, @statuses)
    |> validate_length(:notes, max: 4000)
  end
end
